考勤-加班计划流程,允许非休息班次的休息时段申请加班计划

zm_dev
sy 8 months ago
parent c7b660badb
commit 521114c649

@ -38,6 +38,9 @@ public class BatchAskForLeaveWorkFlowBackAction implements Action {
List<Map<String, String>> detailTableData = CommonUtil.getDetailTableInfo(requestInfo,0);
log.info("detailTableData : [{}]",detailTableData);
String detail1TableName = requestInfo.getDetailTableInfo().getDetailTable()[0].getTableDBName();
log.info("detail1ableName : [{}]", detail1TableName);
//流程表单明细表2数据
List<Map<String, String>> detailTable2 = CommonUtil.getDetailTableInfo(requestInfo,1);
log.info("BatchAskForLeaveWorkFlowBackAction-detailTable2Data : [{}]",detailTable2);
@ -67,12 +70,13 @@ public class BatchAskForLeaveWorkFlowBackAction implements Action {
log.info("jlzt : [{}]",jlzt);
if ("1".equals(jlzt)) {
double havedyxsc = Util.null2String(map.get("yxsc")).equals("") ? 0 : Double.valueOf(map.get("yxsc").toString());
double havedwxsc = Util.null2String(map.get("wxsc")).equals("") ? 0 : Double.valueOf(map.get("wxsc").toString());
double updatedyxsc = Utils.subtract(havedyxsc,ztsc);
double updatedwxsc = Utils.add(havedwxsc,ztsc);
log.info("updatedyxsc : [{}],id:[{}]",updatedyxsc,id);
String updateSql = "update uf_jcl_kq_jqye set yxsc=? where id=?";
updateSign = DbTools.update(updateSql,updatedyxsc,id);
String updateSql = "update uf_jcl_kq_jqye set wxsc=?,yxsc=? where id=?";
updateSign = DbTools.update(updateSql,updatedwxsc, updatedyxsc,id);
} else if("0".equals(jlzt)){
double havedztsc = Util.null2String(map.get("ztsc")).equals("") ? 0 : Double.valueOf(map.get("ztsc").toString());
double havedwxsc = Util.null2String(map.get("wxsc")).equals("") ? 0 : Double.valueOf(map.get("wxsc").toString());
@ -116,6 +120,7 @@ public class BatchAskForLeaveWorkFlowBackAction implements Action {
}
}
}
//将明细表1数据

@ -99,12 +99,13 @@ public class AskForLeaveWorkflowDataReset implements WorkFlowHandleTacis{
log.info("jlzt : [{}]",jlzt);
if ("1".equals(jlzt)) {
double havedyxsc = Util.null2String(map.get("yxsc")).equals("") ? 0 : Double.valueOf(map.get("yxsc").toString());
double havedwxsc = Util.null2String(map.get("wxsc")).equals("") ? 0 : Double.valueOf(map.get("wxsc").toString());
double updatedyxsc = Utils.subtract(havedyxsc,ztsc);
double updatedwxsc = Utils.add(havedwxsc,ztsc);
log.info("updatedyxsc : [{}],id:[{}]",updatedyxsc,id);
String updateSql = "update uf_jcl_kq_jqye set yxsc=? where id=?";
updateSign = DbTools.update(updateSql,updatedyxsc,id);
String updateSql = "update uf_jcl_kq_jqye set wxsc=?,yxsc=? where id=?";
updateSign = DbTools.update(updateSql,updatedwxsc, updatedyxsc,id);
} else if("0".equals(jlzt)){
double havedztsc = Util.null2String(map.get("ztsc")).equals("") ? 0 : Double.valueOf(map.get("ztsc").toString());
double havedwxsc = Util.null2String(map.get("wxsc")).equals("") ? 0 : Double.valueOf(map.get("wxsc").toString());

@ -860,7 +860,7 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic
List<Map<String, Object>> holidayBalanceList = DbTools.getSqlToList(sql, leaveEmpId, itemId, startDate, startDate);
//获取延期失效日期最晚的一条
Map<String, Object> maxYqsxrqMap = holidayBalanceList.stream().reduce((m1, m2) -> m2).orElse(null);
//获取假期额度规则中额度可次数、单次最小休时长、额度单位
//获取假期额度规则中额度可次数、单次最小休时长、额度单位
String jqedSql = "select eddw, dczskxsc, edbxdcxw from uf_jcl_kq_jqed where jb = ?";
Map<String, Object> jqedInfo = DbTools.getSqlToMap(jqedSql, itemId);
//假期额度的额度单位0-天、1-小时

@ -54,7 +54,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
Map<String, String> detailItem;
String sql = "";
//获取作用时段包含计划加班的加班类型的考勤项目集合
sql = "select id,mc, bddrqlx, jbqsfzs, xzzjbsc, rzdjbxss, zzdjbxss, yzdjbxss, zysd, ccclfs from uf_jcl_kq_kqxm where xmlx = ?";
sql = "select id,mc, bddrqlx, jbqsfzs, xzzjbsc, rzdjbxss, zzdjbxss, yzdjbxss, zysd, ccclfs,zdkcjcxxsc from uf_jcl_kq_kqxm where xmlx = ?";
List<Map<String, Object>> jblxAttendanceList = DbTools.getSqlToList(sql, AttendanceItemTypeEnum.WORK_OVERTIME.getKey());
jblxAttendanceList = jblxAttendanceList.stream().filter(f -> Util.null2String(f.get("zysd")).contains(WorkForTimeEnum.PLAN_WORK_OVERTIME.getKey())).collect(Collectors.toList());
//获取人员id和姓名信息
@ -127,6 +127,14 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
boolean currentToNextDay = false;
boolean beforeToNextDay = false;
String belongDate = "";
//20240812需求变更休息班次允许加班计划区间和班次班段区间有重叠
boolean currentDayOverLap = false;
boolean beforeDayOverLap = false;
boolean nextDayOverLap = false;
//20240820需求变更非休息班次加班区间完全处于休息班段内时允许申请加班计划并在匹配加班类型时避开勾选了去除休息时段的加班类型
boolean onlyInRestPeriod = false;
//20240814需求变更。非休息班次出现重叠时间自动调整加班开始或结束时间并返回提示
Map<String, String> adjustInfo = new HashMap<>();
if (!"".equals(currentDayStartToEnd)) {
//1-加班时间段处于前一日下班后和当日上班前
beforeToCurrentDay = ("".equals(beforeDayEndTime) || beforeDayEndTime.compareTo(date + " " + startTime) <= 0) && currentDayStartTime.compareTo(realEndDate + " " + endTime) >=0;
@ -156,28 +164,43 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
}
} else {
//20240812需求变更休息班次允许加班计划区间和班次班段区间有重叠
boolean currentDayOverLap = !"".equals(currentDayStartToEnd) && DateUtil.isOverlapping(date + " " + startTime, realEndDate + " " + endTime, currentDayStartTime, currentDayEndTime);
boolean beforeDayOverLap = !"".equals(beforeDayStartToEnd) && DateUtil.isOverlapping(date + " " + startTime, realEndDate + " " + endTime, beforeDayStartTime, beforeDayEndTime);
boolean nextDayOverLap = !"".equals(nextDayStartToEnd) && DateUtil.isOverlapping(date + " " + startTime, realEndDate + " " + endTime, nextDayStartTime, nextDayEndTime);
currentDayOverLap = !"".equals(currentDayStartToEnd) && DateUtil.isOverlapping(date + " " + startTime, realEndDate + " " + endTime, currentDayStartTime, currentDayEndTime);
beforeDayOverLap = !"".equals(beforeDayStartToEnd) && DateUtil.isOverlapping(date + " " + startTime, realEndDate + " " + endTime, beforeDayStartTime, beforeDayEndTime);
nextDayOverLap = !"".equals(nextDayStartToEnd) && DateUtil.isOverlapping(date + " " + startTime, realEndDate + " " + endTime, nextDayStartTime, nextDayEndTime);
//20240814需求变更。非休息班次出现重叠时间自动调整加班开始或结束时间并返回提示
Map<String, String> adjustInfo = new HashMap<>();
adjustInfo.put("startWithAdjust", date + " " + startTime);
adjustInfo.put("endWithAdjust", realEndDate + " " + endTime);
adjustInfo.put("startDate", date);
adjustInfo.put("startTime", startTime);
adjustInfo.put("endDate", realEndDate);
adjustInfo.put("endTime", endTime);
if ((!currentDayRestBc && currentDayOverLap) || (!beforeDayRestBc && beforeDayOverLap) || (!nextDayRestBc && nextDayOverLap)) {
//处理前一天
if(!beforeDayRestBc && beforeDayOverLap) {
belongDate = DateUtil.beforeDay(date, 1);
adjustInfo = doAdjust(adjustInfo, beforeDayStartTime, beforeDayEndTime);
if (overtimeOnlyInRestRange(beforeDayBcId, date + " " + startTime, realEndDate + " " + endTime, DateUtil.beforeDay(date, 1))) {
onlyInRestPeriod = true;
} else {
adjustInfo = doAdjust(adjustInfo, beforeDayStartTime, beforeDayEndTime);
}
}
//处理当天
if(!currentDayRestBc && currentDayOverLap) {
belongDate = "".equals(belongDate) ? date : belongDate;
adjustInfo = doAdjust(adjustInfo, currentDayStartTime, currentDayEndTime);
if (overtimeOnlyInRestRange(currentDayBcId, date + " " + startTime, realEndDate + " " + endTime, date)) {
onlyInRestPeriod = true;
} else {
adjustInfo = doAdjust(adjustInfo, currentDayStartTime, currentDayEndTime);
}
}
//处理次日
if(!nextDayRestBc && nextDayOverLap) {
belongDate = "".equals(belongDate) ? DateUtil.AfterDay(date, 1) : belongDate;
adjustInfo = doAdjust(adjustInfo, nextDayStartTime, nextDayEndTime);
if (overtimeOnlyInRestRange(nextDayBcId, date + " " + startTime, realEndDate + " " + endTime, DateUtil.AfterDay(date, 1))) {
onlyInRestPeriod = true;
} else {
adjustInfo = doAdjust(adjustInfo, nextDayStartTime, nextDayEndTime);
}
}
//重置加班开始和结束时间、加班时长
detailItem.put("ksrq", adjustInfo.get("startDate"));
@ -186,26 +209,19 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
detailItem.put("jsrq", adjustInfo.get("endDate"));
overtimeMinutes = DateUtil.getBetWeenMinutes(adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"));
//4-非休息班次,出现重叠时间,属于不合理加班安排,返回提示”已自动调整开始和结束时间点“
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划区间和非休息班次班段出现时间重叠,已自动调整开始和结束时间点!");
if (!onlyInRestPeriod) {
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划区间和非休息班次班段出现时间重叠,已自动调整开始和结束时间点!");
}
}
//5-加班区间和休息班次出现重叠,首次重叠的日期,即为归属日期;如果已有归属日,则比较当前日期和归属日谁更早
//20240816需求变更需要去除重叠的休息班次中的休息时段时长
int restOverLapMinutes = 0;
if (beforeDayRestBc && beforeDayOverLap) {
belongDate = DateUtil.beforeDay(date, 1);
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes(beforeDayBcId, adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"), DateUtil.beforeDay(date, 1));
} else if (currentDayRestBc && currentDayOverLap) {
belongDate = "".equals(belongDate) || date.compareTo(belongDate) < 0 ? date : belongDate;
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes(currentDayBcId, adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"), date);
} else if (nextDayRestBc && nextDayOverLap) {
belongDate = "".equals(belongDate) ? DateUtil.AfterDay(date, 1) : belongDate;
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes(nextDayBcId, adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"), DateUtil.AfterDay(date, 1));
}
overtimeMinutes = overtimeMinutes - restOverLapMinutes;
detailItem.put("jbsc", String.format("%.2f", overtimeMinutes / 60.0));
}
//判断归属日的日期类型,首先从排班的信息来获取
String belongDateType = dateTypeInfoFromBc.getOrDefault(belongDate, "");
@ -224,6 +240,10 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//判断该加班类型考勤项目是否被该人员使用,且考勤项目的绑定的日期类型是否包含归属日期类型
if (kqxmSetIds.contains(Util.null2String(attendanceItemInfo.get("id")))
&& Util.null2String(attendanceItemInfo.get("bddrqlx")).contains(belongDateType)) {
//非休息班次,加班区间完全处于休息班段内时,在匹配加班类型时避开勾选了“是否扣除时间区间内的就餐时长”的加班类型
if (onlyInRestPeriod && "1".equals(Util.null2String(attendanceItemInfo.get("zdkcjcxxsc")))) {
continue;
}
detailItem.put("jblx", Util.null2String(attendanceItemInfo.get("id")));
detailItem.put("jblxName", Util.null2String(attendanceItemInfo.get("mc")));
matchItemInfo = attendanceItemInfo;
@ -237,6 +257,22 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
continue;
} else {
log.info(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划匹配到:" + Util.null2String(matchItemInfo.get("mc")));
//20240816需求变更根据zdkcjcxxsc字段设置即“是否扣除时间区间内的就餐时长”需要去除重叠的休息班次中的休息时段时长
String removeRestSc = Util.null2String(matchItemInfo.get("zdkcjcxxsc"));
int restOverLapMinutes = 0;
if (beforeDayRestBc && beforeDayOverLap && "1".equals(removeRestSc)) {
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes(beforeDayBcId, adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"), DateUtil.beforeDay(date, 1));
} else if (currentDayRestBc && currentDayOverLap && "1".equals(removeRestSc)) {
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes(currentDayBcId, adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"), date);
} else if (nextDayRestBc && nextDayOverLap && "1".equals(removeRestSc)) {
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes(nextDayBcId, adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"), DateUtil.AfterDay(date, 1));
}
overtimeMinutes = overtimeMinutes - restOverLapMinutes;
detailItem.put("jbsc", String.format("%.2f", overtimeMinutes / 60.0));
//单条明细的最小加班分钟数校验
String minMinutes = Util.null2String(matchItemInfo.get("jbqsfzs"));
if (!"".equals(minMinutes) && Integer.parseInt(minMinutes) > overtimeMinutes) {
//最小加班分钟数大于单条明细的加班时长分钟数
@ -329,18 +365,21 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
/**
*
*/
private int countRestOverLapMinutes(String nextDayBcId, String startTime, String endTime, String date) {
private int countRestOverLapMinutes(String dayBcId, String startTime, String endTime, String date) {
List<String> countBdlxList = new ArrayList<>();
countBdlxList.add(ClassSegmentTypeEnum.REST_AND_DINE.getKey());
countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey());
countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey());
String sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + nextDayBcId;
String sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + dayBcId;
List<Map<String, Object>> bcDetailData = DbTools.getSqlToList(sql);
bcDetailData = bcDetailData.stream().filter(e -> countBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
//获取需要累计的班段时长区间和目标区间存在交集的分钟数
return Utils.removeTime(startTime, endTime, bcDetailData, date);
}
/**
* /
*/
private Map<String, String> doAdjust(Map<String, String> adjustInfo, String bcStartTime, String bcEndTime) {
String startWithAdjust = adjustInfo.get("startWithAdjust");
String endWithAdjust = adjustInfo.get("endWithAdjust");
@ -348,12 +387,15 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
if (bcStartTime.compareTo(startWithAdjust) > 0 && bcEndTime.compareTo(endWithAdjust) < 0) {
startWithAdjust = bcEndTime;
} else {
//加班区间与部分班次区间重叠时
//加班区间与部分班次区间重叠时,此处可能出现加班区间完全被班次区间包含情况,从而导致加班开始时间晚于加班结束时间
startWithAdjust = bcStartTime.compareTo(startWithAdjust) <= 0 && bcEndTime.compareTo(startWithAdjust) > 0
? bcEndTime : startWithAdjust;
endWithAdjust = bcStartTime.compareTo(endWithAdjust) < 0 && bcEndTime.compareTo(endWithAdjust) >= 0
? bcStartTime : endWithAdjust;
}
//当加班开始时间晚于加班结束时间时
endWithAdjust = startWithAdjust.compareTo(endWithAdjust) > 0 ? startWithAdjust : endWithAdjust;
adjustInfo.put("startWithAdjust", startWithAdjust);
adjustInfo.put("endWithAdjust", endWithAdjust);
adjustInfo.put("startDate", startWithAdjust.split(" ")[0]);
@ -363,6 +405,22 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
return adjustInfo;
}
/**
*
*/
private boolean overtimeOnlyInRestRange(String bcId, String startTime, String endTime, String date) {
int overRangeMinutes = DateUtil.getBetWeenMinutes(startTime, endTime);
List<String> countBdlxList = new ArrayList<>();
countBdlxList.add(ClassSegmentTypeEnum.REST_AND_DINE.getKey());
countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey());
countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey());
String sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + bcId;
List<Map<String, Object>> bcDetailData = DbTools.getSqlToList(sql);
bcDetailData = bcDetailData.stream().filter(e -> countBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
//获取需要累计的班段时长区间和目标区间存在交集的分钟数,并与请假区间内的分钟数最比较
return overRangeMinutes == Utils.removeTime(startTime, endTime, bcDetailData, date);
}
private boolean checkRestBc(String bcId) {
boolean restSign = false;
if (!"".equals(bcId)) {

@ -588,6 +588,7 @@ public class CommonUtil {
}
}
}else if ("2".equals(list_type) && !"".equals(sqltj)){
empGroupUserInfo.put("listType", PersonGroupListTypeEnum.SQLCONDITION.getKey());
sqltj = Utils.converSQL(sqltj);
log.info("getPersonnelGroupingByPerson sqltj : [{}]",sqltj);
List<Map<String,Object>> dataList = DbTools.getSqlToList(sqltj);

@ -50,6 +50,21 @@
WfForm.addDetailRow("detail_1", addObj);
})
}else{
WfForm.delDetailRow("detail_1", "all");
let resultData = res.data.data;
resultData.filter(item => {
let addObj = {};
addObj[WfForm.convertFieldNameToId("jbry", "detail_1")] = {value:item.jbry,specialobj:[{id:item.jbry,name:item.jbryName}]};
addObj[WfForm.convertFieldNameToId("jblx", "detail_1")] = {value:item.jblx,specialobj:[{id:item.jblx,name:item.jblxName}]};
addObj[WfForm.convertFieldNameToId("ksrq", "detail_1")]={value:item.ksrq};
addObj[WfForm.convertFieldNameToId("kssj", "detail_1")]={value:item.kssj};
addObj[WfForm.convertFieldNameToId("jsrq", "detail_1")]={value:item.jsrq};
addObj[WfForm.convertFieldNameToId("jssj", "detail_1")]={value:item.jssj};
addObj[WfForm.convertFieldNameToId("gsrq", "detail_1")]={value:item.gsrq};
addObj[WfForm.convertFieldNameToId("jbsc", "detail_1")]={value:Number(item.jbsc)};
WfForm.addDetailRow("detail_1", addObj);
});
WfForm.showMessage(res.data.errorInfo, 2, 5);
}
}

Loading…
Cancel
Save