考勤,加班计划流程明细数据生成逻辑改造,区分休息、就餐班段

main
sy 6 months ago
parent be540dbd51
commit c33cec2a67

@ -10,6 +10,9 @@ import weaver.general.Util;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -25,7 +28,7 @@ import java.util.stream.Collectors;
public class BatchAskForLeaveWorkFlowArchivingAction implements Action {
@Override
public String execute(RequestInfo requestInfo) {
String requestid = requestInfo.getRequestid();
// 流程表单主表数据
HashMap<String,String> mainTableData = CommonUtil.getMainTableInfo(requestInfo);
log.info("mainTableData : [{}]",mainTableData);
@ -53,7 +56,7 @@ public class BatchAskForLeaveWorkFlowArchivingAction implements Action {
String jqye = Util.null2String(data.get("jqye"));
double sysc = Double.valueOf(data.get("sysc").toString());
double havedSysc= balanceMap.get(jqye) ==null?0:Double.valueOf(balanceMap.get(jqye).toString());
sysc = Utils.add(sysc,havedSysc);
sysc = new BigDecimal(String.valueOf(sysc)).add(new BigDecimal(String.valueOf(havedSysc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
balanceMap.put(jqye,sysc);
}
@ -65,11 +68,14 @@ public class BatchAskForLeaveWorkFlowArchivingAction implements Action {
double havedztsc = Util.null2String(map.get("ztsc")).equals("") ? 0 : Double.valueOf(map.get("ztsc").toString());
double havedyxsc = Util.null2String(map.get("yxsc")).equals("") ? 0 : Double.valueOf(map.get("yxsc").toString());
double updatedztsc = Utils.subtract(havedztsc,ztsc);
double updatedwxsc = Utils.add(havedyxsc,ztsc);
// double updatedztsc = Utils.subtract(havedztsc,ztsc);
// double updatedyxsc = Utils.add(havedyxsc,ztsc);
double updatedztsc = new BigDecimal(String.valueOf(havedztsc)).subtract(new BigDecimal(String.valueOf(ztsc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
double updatedyxsc = new BigDecimal(String.valueOf(havedyxsc)).add(new BigDecimal(String.valueOf(ztsc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
String updateSql = "update uf_jcl_kq_jqye set yxsc=?,ztsc=? where id=?";
if (!DbTools.update(updateSql,updatedwxsc,updatedztsc,id)){
log.info(requestid + "-updateSql : {}", updateSql);
if (!DbTools.update(updateSql,updatedyxsc,updatedztsc,id)){
//更新假期余额失败
String message = "更新假期余额失败";
log.error(message);

@ -10,6 +10,9 @@ import weaver.general.Util;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -63,7 +66,7 @@ public class BatchAskForLeaveWorkFlowBackAction implements Action {
String jqye = Util.null2String(data.get("jqye"));
double sysc = Double.valueOf(data.get("sysc").toString());
double havedSysc= balanceMap.get(jqye) ==null?0:Double.valueOf(balanceMap.get(jqye).toString());
sysc = Utils.add(sysc,havedSysc);
sysc = new BigDecimal(String.valueOf(sysc)).add(new BigDecimal(String.valueOf(havedSysc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
balanceMap.put(jqye,sysc);
}
log.info("balanceMap : [{}]",balanceMap);
@ -76,8 +79,10 @@ public class BatchAskForLeaveWorkFlowBackAction implements Action {
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);
// double updatedyxsc = Utils.subtract(havedyxsc,ztsc);
// double updatedwxsc = Utils.add(havedwxsc,ztsc);
double updatedyxsc = new BigDecimal(String.valueOf(havedyxsc)).subtract(new BigDecimal(String.valueOf(ztsc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
double updatedwxsc = new BigDecimal(String.valueOf(havedwxsc)).add(new BigDecimal(String.valueOf(ztsc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
log.info("updatedyxsc : [{}],id:[{}]",updatedyxsc,id);
String updateSql = "update uf_jcl_kq_jqye set wxsc=?,yxsc=? where id=?";
@ -86,8 +91,10 @@ public class BatchAskForLeaveWorkFlowBackAction implements Action {
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());
double updatedztsc = Utils.subtract(havedztsc,ztsc);
double updatedwxsc = Utils.add(havedwxsc,ztsc);
// double updatedztsc = Utils.subtract(havedztsc,ztsc);
// double updatedwxsc = Utils.add(havedwxsc,ztsc);
double updatedztsc = new BigDecimal(String.valueOf(havedztsc)).subtract(new BigDecimal(String.valueOf(ztsc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
double updatedwxsc = new BigDecimal(String.valueOf(havedwxsc)).add(new BigDecimal(String.valueOf(ztsc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
log.info("updatedwxsc : [{}],updatedztsc:[{}],id:[{}]",updatedwxsc,updatedztsc,id);
String updateSql = "update uf_jcl_kq_jqye set wxsc=?,ztsc=? where id=?";

@ -11,6 +11,9 @@ import weaver.general.Util;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
@ -95,7 +98,7 @@ public class BatchAskForLeaveWorkFlowSubmitAction implements Action {
String jqye = Util.null2String(data.get("jqye"));
double sysc = Double.valueOf(data.get("sysc").toString());
double havedSysc = balanceMap.get(jqye) == null ? 0 : Double.valueOf(balanceMap.get(jqye).toString());
sysc = Utils.add(sysc, havedSysc);
sysc = new BigDecimal(String.valueOf(sysc)).add(new BigDecimal(String.valueOf(havedSysc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
balanceMap.put(jqye, sysc);
}
log.info("balanceMap : [{}]",balanceMap);
@ -107,8 +110,10 @@ public class BatchAskForLeaveWorkFlowSubmitAction implements Action {
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());
double updatedztsc = Utils.add(havedztsc, ztsc);
double updatedwxsc = Utils.subtract(havedwxsc, ztsc);
// double updatedztsc = Utils.add(havedztsc, ztsc);
// double updatedwxsc = Utils.subtract(havedwxsc, ztsc);
double updatedztsc = new BigDecimal(String.valueOf(havedztsc)).add(new BigDecimal(String.valueOf(ztsc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
double updatedwxsc = new BigDecimal(String.valueOf(havedwxsc)).subtract(new BigDecimal(String.valueOf(ztsc)),new MathContext(5, RoundingMode.HALF_UP)).doubleValue();
String updateSql = "update uf_jcl_kq_jqye set wxsc=?,ztsc=? where id=?";
if (!DbTools.update(updateSql, updatedwxsc, updatedztsc, id)) {

@ -14,6 +14,7 @@ import lombok.extern.slf4j.Slf4j;
import weaver.general.TimeUtil;
import weaver.general.Util;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;
@ -54,7 +55,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,zdkcjcxxsc from uf_jcl_kq_kqxm where xmlx = ?";
sql = "select id,mc, bddrqlx, jbqsfzs, xzzjbsc, rzdjbxss, zzdjbxss, yzdjbxss, zysd, ccclfs,zdkcjcxxsc,sfkcxxdsc 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和姓名信息
@ -95,10 +96,11 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
int overtimeMinutes = DateUtil.getBetWeenMinutes(date + " " + startTime, realEndDate + " " + endTime);
detailItem.put("jbsc", String.format("%.2f", overtimeMinutes / 60.0));
//根据班次数据,设置归属日期
Map<String, List<Map<String, Object>>> bcDetailListToDateMap = new HashMap<>();
//获取当天班次id
String currentDayBcId = Util.null2String(dateToBcxxMap.get(date)).split("-")[0];
//获取当天班次开始时间和结束时间
String currentDayStartToEnd = getBcStartAndEndTime(date, currentDayBcId, workBdlxList);
String currentDayStartToEnd = getBcStartAndEndTime(date, currentDayBcId, workBdlxList, bcDetailListToDateMap);
String currentDayStartTime = !"".equals(currentDayStartToEnd) ? currentDayStartToEnd.split(",")[0] : "";
String currentDayEndTime = !"".equals(currentDayStartToEnd) ? currentDayStartToEnd.split(",")[1] : "";
//判断当天班次是否为休息班次、且“休息班打卡自动加班”未勾选
@ -107,7 +109,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//获取前1天班次id
String beforeDayBcId = Util.null2String(dateToBcxxMap.get(DateUtil.beforeDay(date, 1))).split("-")[0];
//获取前1天班次开始时间和结束时间
String beforeDayStartToEnd = getBcStartAndEndTime(DateUtil.beforeDay(date, 1), beforeDayBcId, workBdlxList);
String beforeDayStartToEnd = getBcStartAndEndTime(DateUtil.beforeDay(date, 1), beforeDayBcId, workBdlxList, bcDetailListToDateMap);
String beforeDayStartTime = !"".equals(beforeDayStartToEnd) ? beforeDayStartToEnd.split(",")[0] : "";
String beforeDayEndTime = !"".equals(beforeDayStartToEnd) ? beforeDayStartToEnd.split(",")[1] : "";
//判断前1天班次是否为休息班次、且“休息班打卡自动加班”未勾选
@ -116,7 +118,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//获取次日班次id
String nextDayBcId = Util.null2String(dateToBcxxMap.get(DateUtil.AfterDay(date, 1))).split("-")[0];
//获取次日班次开始时间和结束时间
String nextDayStartToEnd = getBcStartAndEndTime(DateUtil.AfterDay(date, 1), nextDayBcId, workBdlxList);
String nextDayStartToEnd = getBcStartAndEndTime(DateUtil.AfterDay(date, 1), nextDayBcId, workBdlxList, bcDetailListToDateMap);
String nextDayStartTime = !"".equals(nextDayStartToEnd) ? nextDayStartToEnd.split(",")[0] : "";
String nextDayEndTime = !"".equals(nextDayStartToEnd) ? nextDayStartToEnd.split(",")[1] : "";
//判断次日班次是否为休息班次、且“休息班打卡自动加班”未勾选
@ -133,8 +135,25 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
boolean nextDayOverLap = false;
//20240820需求变更非休息班次加班区间完全处于休息班段内时允许申请加班计划并在匹配加班类型时避开勾选了去除休息时段的加班类型
boolean onlyInRestPeriod = false;
//20240924需求变更区分“休息”、“就餐”、“休息和就餐”三类时段的时长和要求并且对加班区间的首尾如果有不许累计时长的以上三类区间要灵活修改加班区间的首尾时间点
boolean onlyInDinePeriod = false;
boolean onlyInRestAndDinePeriod = false;
boolean borderHaveRest = false;
boolean allowOvertimeSign = true;
Map<String, Object> overtimeBorderInfo = new HashMap<>();
overtimeBorderInfo.put("onlyInRestPeriod", false);
overtimeBorderInfo.put("onlyInDinePeriod", false);
overtimeBorderInfo.put("onlyInRestAndDinePeriod", false);
overtimeBorderInfo.put("borderHaveRest", false);
overtimeBorderInfo.put("allowOvertimeSign", true);
//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 (!"".equals(currentDayStartToEnd)) {
//1-加班时间段处于前一日下班后和当日上班前
beforeToCurrentDay = ("".equals(beforeDayEndTime) || beforeDayEndTime.compareTo(date + " " + startTime) <= 0) && currentDayStartTime.compareTo(realEndDate + " " + endTime) >=0;
@ -149,10 +168,16 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
int beforeDayDiffMinutes = !"".equals(beforeDayEndTime) ? DateUtil.getBetWeenMinutes(beforeDayEndTime, date + " " + startTime) : 9999;
int currentDayDiffMinutes = DateUtil.getBetWeenMinutes(realEndDate + " " + endTime, currentDayStartTime);
belongDate = currentDayDiffMinutes < beforeDayDiffMinutes ? date : DateUtil.beforeDay(date, 1);
//20240924需求变更判断加班区间是否与班次的休息或就餐班段有交集
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, date + " " + startTime, realEndDate + " " + endTime,
DateUtil.beforeDay(date, 1), date, null, false);
} else if (currentToNextDay) {
int nextDayDiffMinutes = !"".equals(nextDayStartTime) ? DateUtil.getBetWeenMinutes(realEndDate + " " + endTime, nextDayStartTime) : 9999;
int currentDayDiffMinutes = DateUtil.getBetWeenMinutes(currentDayEndTime, date + " " + startTime);
belongDate = currentDayDiffMinutes <= nextDayDiffMinutes ? date : DateUtil.AfterDay(date, 1);
//20240924需求变更判断加班区间是否与班次的休息或就餐班段有交集
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, date + " " + startTime, realEndDate + " " + endTime,
date, DateUtil.AfterDay(date, 1), null, false);
} else if (beforeToNextDay) {
int beforeDayDiffMinutes = !"".equals(beforeDayEndTime) ? DateUtil.getBetWeenMinutes(beforeDayEndTime, date + " " + startTime) : 9999;
int nextDayDiffMinutes = !"".equals(nextDayStartTime) ? DateUtil.getBetWeenMinutes(realEndDate + " " + endTime, nextDayStartTime) : 9999;
@ -162,58 +187,73 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
} else {
belongDate = beforeDayDiffMinutes <= nextDayDiffMinutes ? DateUtil.beforeDay(date, 1) : DateUtil.AfterDay(date, 1);
}
//20240924需求变更判断加班区间是否与班次的休息或就餐班段有交集
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, date + " " + startTime, realEndDate + " " + endTime,
DateUtil.beforeDay(date, 1), DateUtil.AfterDay(date, 1), null, false);
} else {
//20240812需求变更休息班次允许加班计划区间和班次班段区间有重叠
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需求变更。非休息班次出现重叠时间自动调整加班开始或结束时间并返回提示
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);
if (overtimeOnlyInRestRange(beforeDayBcId, date + " " + startTime, realEndDate + " " + endTime, DateUtil.beforeDay(date, 1))) {
onlyInRestPeriod = true;
} else {
//20240924需求变更区分“休息”、“就餐”、“休息和就餐”三类时段的时长和要求并且对加班区间的首尾如果有不许累计时长的以上三类区间要灵活修改加班区间的首尾时间点
//处理前一天
if (beforeDayOverLap) {
belongDate = DateUtil.beforeDay(date, 1);
if (!beforeDayRestBc) {
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, date + " " + startTime, realEndDate + " " + endTime,
null, null, belongDate, false);
onlyInRestPeriod = (boolean) overtimeBorderInfo.get("onlyInRestPeriod");
onlyInDinePeriod = (boolean) overtimeBorderInfo.get("onlyInDinePeriod");
onlyInRestAndDinePeriod = (boolean) overtimeBorderInfo.get("onlyInRestAndDinePeriod");
if (!onlyInRestPeriod && !onlyInDinePeriod && !onlyInRestAndDinePeriod) {
adjustInfo = doAdjust(adjustInfo, beforeDayStartTime, beforeDayEndTime);
}
} else {
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, date + " " + startTime, realEndDate + " " + endTime,
null, null, belongDate, true);
}
//处理当天
if(!currentDayRestBc && currentDayOverLap) {
belongDate = "".equals(belongDate) ? date : belongDate;
if (overtimeOnlyInRestRange(currentDayBcId, date + " " + startTime, realEndDate + " " + endTime, date)) {
onlyInRestPeriod = true;
} else {
}
//处理当天
if (currentDayOverLap) {
belongDate = "".equals(belongDate) ? date : belongDate;
if (!currentDayRestBc) {
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, date + " " + startTime, realEndDate + " " + endTime,
null, null, belongDate, false);
onlyInRestPeriod = (boolean) overtimeBorderInfo.get("onlyInRestPeriod");
onlyInDinePeriod = (boolean) overtimeBorderInfo.get("onlyInDinePeriod");
onlyInRestAndDinePeriod = (boolean) overtimeBorderInfo.get("onlyInRestAndDinePeriod");
if (!onlyInRestPeriod && !onlyInDinePeriod && !onlyInRestAndDinePeriod) {
adjustInfo = doAdjust(adjustInfo, currentDayStartTime, currentDayEndTime);
}
} else {
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, date + " " + startTime, realEndDate + " " + endTime,
null, null, belongDate, true);
}
//处理次日
if(!nextDayRestBc && nextDayOverLap) {
belongDate = "".equals(belongDate) ? DateUtil.AfterDay(date, 1) : belongDate;
if (overtimeOnlyInRestRange(nextDayBcId, date + " " + startTime, realEndDate + " " + endTime, DateUtil.AfterDay(date, 1))) {
onlyInRestPeriod = true;
} else {
}
//处理次日
if (nextDayOverLap) {
belongDate = "".equals(belongDate) ? DateUtil.AfterDay(date, 1) : belongDate;
if (!nextDayRestBc) {
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, date + " " + startTime, realEndDate + " " + endTime,
null, null, belongDate, false);
onlyInRestPeriod = (boolean) overtimeBorderInfo.get("onlyInRestPeriod");
onlyInDinePeriod = (boolean) overtimeBorderInfo.get("onlyInDinePeriod");
onlyInRestAndDinePeriod = (boolean) overtimeBorderInfo.get("onlyInRestAndDinePeriod");
if (!onlyInRestPeriod && !onlyInDinePeriod && !onlyInRestAndDinePeriod) {
adjustInfo = doAdjust(adjustInfo, nextDayStartTime, nextDayEndTime);
}
} else {
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, date + " " + startTime, realEndDate + " " + endTime,
null, null, belongDate, true);
}
//重置加班开始和结束时间、加班时长
detailItem.put("ksrq", adjustInfo.get("startDate"));
detailItem.put("kssj", adjustInfo.get("startTime"));
detailItem.put("jssj", adjustInfo.get("endTime"));
detailItem.put("jsrq", adjustInfo.get("endDate"));
overtimeMinutes = DateUtil.getBetWeenMinutes(adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"));
//4-非休息班次,出现重叠时间,属于不合理加班安排,返回提示”已自动调整开始和结束时间点“
if (!onlyInRestPeriod) {
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划区间和非休息班次班段出现时间重叠,已自动调整开始和结束时间点!");
}
}
//以上三天处理过后,还要考虑调整过加班起始时间后的区间,处于两天之间的情况,此处仅考虑非休息班次自动调整过加班开始、结束时间后处于两班次之间的情况
if ((beforeDayOverLap && !beforeDayRestBc) || (currentDayOverLap && !currentDayRestBc) || (nextDayOverLap && !nextDayRestBc)) {
overtimeBorderCheck(overtimeBorderInfo, bcDetailListToDateMap, adjustInfo.get("startDate") + " " + adjustInfo.get("startTime"),
adjustInfo.get("endDate") + " " + adjustInfo.get("endTime"),
belongDate, DateUtil.AfterDay(belongDate, 1), null, false);
}
overtimeMinutes = DateUtil.getBetWeenMinutes(adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"));
//5-加班区间和休息班次出现重叠,首次重叠的日期,即为归属日期;如果已有归属日,则比较当前日期和归属日谁更早
if (beforeDayRestBc && beforeDayOverLap) {
belongDate = DateUtil.beforeDay(date, 1);
@ -235,13 +275,19 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
List<Map<String, Object>> attendanceItemSetList = CommonUtil.getAttendanceItemsByEmpIdDate(empId, belongDate);
List<String> kqxmSetIds = attendanceItemSetList.stream().map(f->f.get("keyid").toString()).collect(Collectors.toList());
// log.info(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的可用考勤项目:" + kqxmSetIds);
onlyInRestPeriod = (boolean) overtimeBorderInfo.get("onlyInRestPeriod");
onlyInDinePeriod = (boolean) overtimeBorderInfo.get("onlyInDinePeriod");
onlyInRestAndDinePeriod = (boolean) overtimeBorderInfo.get("onlyInRestAndDinePeriod");
Map<String, Object> matchItemInfo = new HashMap<>();
for (Map<String, Object> attendanceItemInfo : jblxAttendanceList) {
//判断该加班类型考勤项目是否被该人员使用,且考勤项目的绑定的日期类型是否包含归属日期类型
if (kqxmSetIds.contains(Util.null2String(attendanceItemInfo.get("id")))
&& Util.null2String(attendanceItemInfo.get("bddrqlx")).contains(belongDateType)) {
//非休息班次,加班区间完全处于休息班段内时,在匹配加班类型时避开勾选了“是否扣除时间区间内的就餐时长”的加班类型
if (onlyInRestPeriod && "1".equals(Util.null2String(attendanceItemInfo.get("zdkcjcxxsc")))) {
//非休息班次,加班区间完全处于“就餐”或“休息和就餐”班段内时,在匹配加班类型时避开勾选了“是否扣除时间区间内的就餐时长”的加班类型
if ((onlyInDinePeriod || onlyInRestAndDinePeriod) && "1".equals(Util.null2String(attendanceItemInfo.get("zdkcjcxxsc")))) {
continue;
//非休息班次,加班区间完全处于“休息”或“休息和就餐”班段内时,在匹配加班类型时避开勾选了“是否扣除时间区间内的休息时长”的加班类型
} else if ((onlyInRestPeriod || onlyInRestAndDinePeriod) && "1".equals(Util.null2String(attendanceItemInfo.get("sfkcxxdsc")))) {
continue;
}
detailItem.put("jblx", Util.null2String(attendanceItemInfo.get("id")));
@ -255,92 +301,107 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
log.info(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划未匹配到合适的加班类型!");
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划未匹配到合适的加班类型!");
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) {
//最小加班分钟数大于单条明细的加班时长分钟数
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班分钟数小于加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的最小加班分钟数!");
continue;
}
log.info(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划匹配到:" + Util.null2String(matchItemInfo.get("mc")));
//20240924需求变更区分“休息”、“就餐”、“休息和就餐”三类时段的时长和要求并且对加班区间的首尾如果有不许累计时长的以上三类区间要灵活修改加班区间的首尾时间点
//根据sfkcxxdsc字段设置即“是否扣除时间区间内的休息时长”需要去除重叠的休息班次中的休息时段时长
String removeRestSc = Util.null2String(matchItemInfo.get("sfkcxxdsc"));
//20240816需求变更根据zdkcjcxxsc字段设置即“是否扣除时间区间内的就餐时长”需要去除重叠的休息班次中的就餐时段时长
String removeDineSc = Util.null2String(matchItemInfo.get("zdkcjcxxsc"));
//根据匹配的加班类型中的sfkcxxdsc字段和zdkcjcxxsc字段设置再次处理加班时长和加班区间
List<Map<String, Object>> borderOverlapBcDetails = (List<Map<String, Object>>) overtimeBorderInfo.get("borderOverlapBcDetails");
int restOverLapMinutes = 0;
if (borderOverlapBcDetails != null && borderOverlapBcDetails.size() > 0) {
restOverLapMinutes = countDineOrRestOverLapMinutes(borderOverlapBcDetails, adjustInfo, removeRestSc, removeDineSc);
}
overtimeMinutes = overtimeMinutes - restOverLapMinutes;
detailItem.put("jbsc", String.format("%.2f", overtimeMinutes / 60.0));
//重置加班开始和结束时间、加班时长
detailItem.put("ksrq", adjustInfo.get("startDate"));
detailItem.put("kssj", adjustInfo.get("startTime"));
detailItem.put("jssj", adjustInfo.get("endTime"));
detailItem.put("jsrq", adjustInfo.get("endDate"));
//对于不允许加班的情况,此处指非休息班次中,和非休息、就餐班段有重叠时
allowOvertimeSign = (boolean) overtimeBorderInfo.get("allowOvertimeSign");
if (!allowOvertimeSign) {
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班区间和工作班次的非休息/就餐班段有重叠!");
continue;
}
//单条明细的最小加班分钟数校验
String minMinutes = Util.null2String(matchItemInfo.get("jbqsfzs"));
if (!"".equals(minMinutes) && Integer.parseInt(minMinutes) > overtimeMinutes) {
//最小加班分钟数大于单条明细的加班时长分钟数
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班分钟数小于加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的最小加班分钟数!");
continue;
}
String limitTotalOvertimeSc = Util.null2String(matchItemInfo.get("xzzjbsc"));
if ("1".equals(limitTotalOvertimeSc)) {
String limitWorkDayHours = Util.null2String(matchItemInfo.get("rzdjbxss"));
String limitWeekHours = Util.null2String(matchItemInfo.get("zzdjbxss"));
String limitMonthHours = Util.null2String(matchItemInfo.get("yzdjbxss"));
String limitDealType = Util.null2String(matchItemInfo.get("ccclfs"));
boolean doLimitWorkDayHours = false;
boolean doLimitWeekHours = false;
boolean doLimitMonthHours = false;
//判断是否满足工作日加班最大小时数
boolean needCheckWorkDayHours = !"".equals(limitWorkDayHours) && (belongDateType.equals(DateTypeEnum.WORK_DAY.getKey()) || belongDateType.equals(DateTypeEnum.CHANGECLASS.getKey()));
if (needCheckWorkDayHours && Double.compare(Double.parseDouble(limitWorkDayHours), overtimeMinutes / 60.0) < 0) {
doLimitWorkDayHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的工作日加班最大小时数!");
}
String limitTotalOvertimeSc = Util.null2String(matchItemInfo.get("xzzjbsc"));
if ("1".equals(limitTotalOvertimeSc)) {
String limitWorkDayHours = Util.null2String(matchItemInfo.get("rzdjbxss"));
String limitWeekHours = Util.null2String(matchItemInfo.get("zzdjbxss"));
String limitMonthHours = Util.null2String(matchItemInfo.get("yzdjbxss"));
String limitDealType = Util.null2String(matchItemInfo.get("ccclfs"));
boolean doLimitWorkDayHours = false;
boolean doLimitWeekHours = false;
boolean doLimitMonthHours = false;
//判断是否满足工作日加班最大小时数
boolean needCheckWorkDayHours = !"".equals(limitWorkDayHours) && (belongDateType.equals(DateTypeEnum.WORK_DAY.getKey()) || belongDateType.equals(DateTypeEnum.CHANGECLASS.getKey()));
if (needCheckWorkDayHours && Double.compare(Double.parseDouble(limitWorkDayHours), overtimeMinutes / 60.0) < 0) {
doLimitWorkDayHours = true;
//判断是否满足周加班最大小时数
if (!"".equals(limitWeekHours)) {
int weekRank = DateUtil.weekRank(belongDate);
double maxWeekMinutes = Double.parseDouble(limitWeekHours) *60;
double weekOvertimeMinutes;
if (weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank) == null) {
String countStartDate = DateUtil.beforeDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01", 6);
String countEndDate = DateUtil.AfterDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-28", 9);
weekOvertimeMinutes = getWeekTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate);
} else {
weekOvertimeMinutes = weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank);
}
weekOvertimeInfo.put(belongDate.split("-")[0] + "" + weekRank, weekOvertimeMinutes + overtimeMinutes);
if (maxWeekMinutes - weekOvertimeMinutes - overtimeMinutes < 0) {
//达到周加班最大小时数
doLimitWeekHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的工作日加班最大小时数!");
+ Util.null2String(matchItemInfo.get("mc")) +"设置的加班最大小时数!");
}
//判断是否满足周加班最大小时数
if (!"".equals(limitWeekHours)) {
int weekRank = DateUtil.weekRank(belongDate);
double maxWeekMinutes = Double.parseDouble(limitWeekHours) *60;
double weekOvertimeMinutes;
if (weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank) == null) {
String countStartDate = DateUtil.beforeDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01", 6);
String countEndDate = DateUtil.AfterDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-28", 9);
weekOvertimeMinutes = getWeekTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate);
} else {
weekOvertimeMinutes = weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank);
}
weekOvertimeInfo.put(belongDate.split("-")[0] + "" + weekRank, weekOvertimeMinutes + overtimeMinutes);
if (maxWeekMinutes - weekOvertimeMinutes - overtimeMinutes < 0) {
//达到周加班最大小时数
doLimitWeekHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的周加班最大小时数!");
}
}
//判断是否满足月加班最大小时数
if (!"".equals(limitMonthHours)) {
String yearMonth = belongDate.substring(0, 7);
double maxMonthMinutes = Double.parseDouble(limitMonthHours) *60;
double monthOvertimeMinutes;
if (monthOvertimeInfo.get(yearMonth) == null) {
String countStartDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01";
String countEndDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-31";
monthOvertimeMinutes = getMonthTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate);
} else {
monthOvertimeMinutes = monthOvertimeInfo.get(yearMonth);
}
//判断是否满足月加班最大小时数
if (!"".equals(limitMonthHours)) {
String yearMonth = belongDate.substring(0, 7);
double maxMonthMinutes = Double.parseDouble(limitMonthHours) *60;
double monthOvertimeMinutes;
if (monthOvertimeInfo.get(yearMonth) == null) {
String countStartDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01";
String countEndDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-31";
monthOvertimeMinutes = getMonthTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate);
} else {
monthOvertimeMinutes = monthOvertimeInfo.get(yearMonth);
}
monthOvertimeInfo.put(yearMonth, monthOvertimeMinutes + overtimeMinutes);
if (maxMonthMinutes - monthOvertimeMinutes - overtimeMinutes < 0) {
//达到月加班最大小时数
doLimitMonthHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的月加班最大小时数!");
}
monthOvertimeInfo.put(yearMonth, monthOvertimeMinutes + overtimeMinutes);
if (maxMonthMinutes - monthOvertimeMinutes - overtimeMinutes < 0) {
//达到月加班最大小时数
doLimitMonthHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的月加班最大小时数!");
}
}
// //判断是否超出工作日、周、月最大小时数要求
// if ("1".equals(limitDealType) && (doLimitWorkDayHours || doLimitWeekHours || doLimitMonthHours)) {
// continue;
// }
}
}
//如果实际加班时长为0加班开始时间和结束时间置为初始值
if (overtimeMinutes == 0) {
detailItem.put("ksrq", date);
detailItem.put("kssj", startTime);
detailItem.put("jssj", endTime);
detailItem.put("jsrq", realEndDate);
}
overtimePlanDetailList.add(detailItem);
}
@ -377,6 +438,90 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
return Utils.removeTime(startTime, endTime, bcDetailData, date);
}
/**
*
* @param borderOverlapBcDetails
* @param adjustInfo
* @param removeRestSc
* @param removeDineSc
*/
private int countDineOrRestOverLapMinutes(List<Map<String, Object>> borderOverlapBcDetails, Map<String, String> adjustInfo, String removeRestSc, String removeDineSc) {
List<String> countBdlxList = new ArrayList<>();
if ("1".equals(removeRestSc) && "1".equals(removeDineSc)) {
countBdlxList.add(ClassSegmentTypeEnum.REST_AND_DINE.getKey());
countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey());
countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey());
} else if ("1".equals(removeRestSc)) {
countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey());
} else if ("1".equals(removeDineSc)) {
countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey());
} else {
return 0;
}
for (Map<String, Object> bcDetailItem : borderOverlapBcDetails) {
if (!countBdlxList.contains(bcDetailItem.get("bdlx").toString())) {
continue;
}
String dtkssj = Utils.getkssjTime(bcDetailItem, (String) bcDetailItem.get("bcBelongDate"));
String dtjssj = Utils.getjssjTime(bcDetailItem, (String) bcDetailItem.get("bcBelongDate"));
bcDetailItem.put("bdStartTime", dtkssj);
bcDetailItem.put("bdEndTime", dtjssj);
}
//筛选出处理过的班次明细数据,并根据开始时间排序
List<Map<String, Object>> countBcDetails = borderOverlapBcDetails.stream().filter(f -> f.get("bdStartTime") != null).collect(Collectors.toList());
if (countBcDetails.size() == 0) {
return 0;
}
countBcDetails = countBcDetails.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("bdStartTime").toString()).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
//合并相邻休息、就餐时段
List<Map<String, Object>> finalCountBcDetails = new ArrayList<>();
for (Map<String, Object> bcDetailItem : countBcDetails) {
if (finalCountBcDetails.size() == 0) {
finalCountBcDetails.add(bcDetailItem);
continue;
}
Map<String, Object> finalCountItem = finalCountBcDetails.get(finalCountBcDetails.size() - 1);
if (finalCountItem.get("bdEndTime").toString().equals(bcDetailItem.get("bdStartTime").toString())) {
finalCountItem.put("bdEndTime", bcDetailItem.get("bdEndTime"));
} else {
finalCountBcDetails.add(bcDetailItem);
}
}
//累计时间,并且调整加班区间
int countMinutes = 0;
String overtimeStartTime = adjustInfo.get("startWithAdjust");
String overtimeEndTime = adjustInfo.get("endWithAdjust");
String bdStartTime = "";
String bdEndTime = "";
for (Map<String, Object> bcDetailItem : finalCountBcDetails) {
if (overtimeStartTime.compareTo(overtimeEndTime) == 0) {
break;
}
bdStartTime = (String) bcDetailItem.get("bdStartTime");
bdEndTime = (String) bcDetailItem.get("bdEndTime");
countMinutes = countMinutes + DateUtil.getOverlappedMinutes(overtimeStartTime, overtimeEndTime, bdStartTime, bdEndTime);
//调整加班开始和结束时间
if (overtimeStartTime.compareTo(bdStartTime) >= 0 && overtimeStartTime.compareTo(bdEndTime) < 0) {
overtimeStartTime = bdEndTime;
}
if (overtimeEndTime.compareTo(bdStartTime) > 0 && overtimeEndTime.compareTo(bdEndTime) <= 0) {
overtimeEndTime = bdStartTime;
}
if (overtimeStartTime.compareTo(overtimeEndTime) > 0) {
overtimeEndTime = overtimeStartTime;
}
}
adjustInfo.put("startWithAdjust", overtimeStartTime);
adjustInfo.put("endWithAdjust", overtimeEndTime);
adjustInfo.put("startDate", overtimeStartTime.split(" ")[0]);
adjustInfo.put("startTime", overtimeStartTime.split(" ")[1]);
adjustInfo.put("endDate", overtimeEndTime.split(" ")[0]);
adjustInfo.put("endTime", overtimeEndTime.split(" ")[1]);
return countMinutes;
}
/**
* /
*/
@ -406,7 +551,92 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
}
/**
*
*
*/
private void overtimeBorderCheck(Map<String, Object> overtimeBorderInfo, Map<String, List<Map<String, Object>>> bcDetailListToDateMap,
String startTime, String endTime, String beforeDate, String afterDate, String overlapDate, boolean overlapRestBc) {
List<String> countBdlxList = new ArrayList<>();
countBdlxList.add(ClassSegmentTypeEnum.REST_AND_DINE.getKey());
countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey());
countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey());
List<Map<String, Object>> overlapBcDetailList = new ArrayList<>();
if (overlapDate == null) {
//如果重叠日期为null只需判断加班区间的首尾是否和班次的非工作时段有重叠
//处理加班区间首部的附近的班次数据
List<Map<String, Object>> beforeOvertimeBcDetailList = bcDetailListToDateMap.get(beforeDate);
if (beforeOvertimeBcDetailList != null && beforeOvertimeBcDetailList.size() > 0) {
beforeOvertimeBcDetailList = beforeOvertimeBcDetailList.stream().filter(e -> countBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
for (Map<String, Object> bcDetailItem : beforeOvertimeBcDetailList) {
int overlapMinutes = Utils.removeTime(startTime, endTime, Collections.singletonList(bcDetailItem), beforeDate);
if (overlapMinutes > 0) {
bcDetailItem.put("bcBelongDate", beforeDate);
overlapBcDetailList.add(bcDetailItem);
}
}
}
//处理加班区间尾部的附近的班次数据
List<Map<String, Object>> afterOvertimeBcDetailList = bcDetailListToDateMap.get(afterDate);
if (afterOvertimeBcDetailList != null && afterOvertimeBcDetailList.size() > 0) {
afterOvertimeBcDetailList = afterOvertimeBcDetailList.stream().filter(e -> countBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
for (Map<String, Object> bcDetailItem : afterOvertimeBcDetailList) {
int overlapMinutes = Utils.removeTime(startTime, endTime, Collections.singletonList(bcDetailItem), afterDate);
if (overlapMinutes > 0) {
bcDetailItem.put("bcBelongDate", afterDate);
overlapBcDetailList.add(bcDetailItem);
}
}
}
//处理重叠班段数据
if (overlapBcDetailList.size() > 0) {
overtimeBorderInfo.put("borderHaveRest", true);
overtimeBorderInfo.put("borderOverlapBcDetails", overlapBcDetailList);
}
} else {
//如果重叠日期不为null还需要区分重叠的班次是否为休息班次
List<Map<String, Object>> overlapOvertimeBcDetailList = bcDetailListToDateMap.get(overlapDate);
if (overlapOvertimeBcDetailList == null || overlapOvertimeBcDetailList.size() == 0) {
return;
}
overlapOvertimeBcDetailList = overlapOvertimeBcDetailList.stream().filter(e -> countBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
//处理加班区间重叠的班次数据
for (Map<String, Object> bcDetailItem : overlapOvertimeBcDetailList) {
int overlapMinutes = Utils.removeTime(startTime, endTime, Collections.singletonList(bcDetailItem), overlapDate);
if (overlapMinutes > 0) {
bcDetailItem.put("bcBelongDate", overlapDate);
overlapBcDetailList.add(bcDetailItem);
}
}
if (overlapBcDetailList.size() == 0) {
return;
}
List<Map<String, Object>> existOverlapBcDetailList = (List<Map<String, Object>>) overtimeBorderInfo.getOrDefault("borderOverlapBcDetails", new ArrayList<>());
existOverlapBcDetailList.addAll(overlapBcDetailList);
if (overlapRestBc) {
//休息班次时,需要判断开始或者结束是否处于班次的非工作时段
overtimeBorderInfo.put("overlapRestBcRest", true);
overtimeBorderInfo.put("borderOverlapBcDetails", existOverlapBcDetailList);
} else {
//非休息班次时,只需判断是不是只在就餐/休息班段内加班
int overRangeMinutes = DateUtil.getBetWeenMinutes(startTime, endTime);
if (overRangeMinutes != Utils.removeTime(startTime, endTime, overlapBcDetailList, overlapDate)) {
overtimeBorderInfo.put("allowOvertimeSign", false);
return;
}
List<String> bdlxList = overlapBcDetailList.stream().map(e->e.get("bdlx").toString()).collect(Collectors.toList());
if ((bdlxList.contains(ClassSegmentTypeEnum.REST_PERIOD.getKey()) && bdlxList.contains(ClassSegmentTypeEnum.DINING_PERIOD.getKey()))
|| bdlxList.contains(ClassSegmentTypeEnum.REST_AND_DINE.getKey())) {
overtimeBorderInfo.put("onlyInRestAndDinePeriod", true);
} else if (bdlxList.contains(ClassSegmentTypeEnum.REST_PERIOD.getKey())) {
overtimeBorderInfo.put("onlyInRestPeriod", true);
} else if (bdlxList.contains(ClassSegmentTypeEnum.DINING_PERIOD.getKey())) {
overtimeBorderInfo.put("onlyInDinePeriod", true);
}
}
}
}
/**
*
*/
private boolean overtimeOnlyInRestRange(String bcId, String startTime, String endTime, String date) {
int overRangeMinutes = DateUtil.getBetWeenMinutes(startTime, endTime);
@ -468,22 +698,23 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
return result;
}
public String getBcStartAndEndTime(String date, String currentDayBcId, List<String> workBdlxList) {
public String getBcStartAndEndTime(String date, String currentDayBcId, List<String> workBdlxList, Map<String, List<Map<String, Object>>> bcDetailListToDateMap) {
String startToEnd = "";
if (!"".equals(currentDayBcId)) {
//查询当天班次明细
String sql = "select id, bdlx, gsrq, kssj, jssj from uf_jcl_kq_bcxx_dt1 where mainid = " + currentDayBcId + " order by gsrq desc, kssj desc";
String sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + currentDayBcId + " order by gsrq desc, dtkssj desc";
List<Map<String, Object>> bcDetailData = DbTools.getSqlToList(sql);
bcDetailListToDateMap.put(date, new ArrayList<>(bcDetailData));
bcDetailData = bcDetailData.stream().filter(e -> workBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
if (bcDetailData.size() > 0) {
String endGsrqValue = Util.null2String(bcDetailData.get(0).get("gsrq"));
String lastJssj = Util.null2String(bcDetailData.get(0).get("jssj"));
String lastKssj = Util.null2String(bcDetailData.get(0).get("kssj"));
String lastJssj = Util.null2String(bcDetailData.get(0).get("dtjssj"));
String lastKssj = Util.null2String(bcDetailData.get(0).get("dtkssj"));
String bdEndDate = "2".equals(endGsrqValue) ? DateUtil.AfterDay(date,1) : ("0".equals(endGsrqValue) ? DateUtil.beforeDay(date,1) : date);
bdEndDate = lastKssj.compareTo(lastJssj) >= 0 ? DateUtil.AfterDay(bdEndDate,1) : bdEndDate;
String startGsrqValue = Util.null2String(bcDetailData.get(bcDetailData.size() - 1).get("gsrq"));
String firstKssj = Util.null2String(bcDetailData.get(bcDetailData.size() - 1).get("kssj"));
String firstKssj = Util.null2String(bcDetailData.get(bcDetailData.size() - 1).get("dtkssj"));
String bdStartDate = "2".equals(startGsrqValue) ? DateUtil.AfterDay(date,1) : ("0".equals(startGsrqValue) ? DateUtil.beforeDay(date,1) : date);
startToEnd = bdStartDate + " " + firstKssj + "," + bdEndDate + " " + lastJssj;
@ -518,7 +749,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
double totalMinutes = 0;
for (Map<String, Object> data:list){
String hsdw = data.get("hsdw").toString();
totalMinutes += Utils.getItemduration(1,AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8);
totalMinutes += Utils.getItemduration(0.1,AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8);
}
return totalMinutes;
}
@ -536,7 +767,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
double totalMinutes = 0;
for (Map<String, Object> data:list){
String hsdw = data.get("hsdw").toString();
totalMinutes += Utils.getItemduration(1,AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8);
totalMinutes += Utils.getItemduration(0.1,AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8);
}
return totalMinutes;

@ -10,6 +10,8 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -131,6 +133,9 @@ public class GetPersonDateBySuitOrganzation extends AbstractCommonCommand<Map<St
//人员分组假别假期规则id
Map<String,String> personGroupHolidayMap = (Map<String,String>)entry.getValue();
Set<String> userIds = personGroupUserIds.get(personGroupId);
if (userIds == null || userIds.size() == 0) {
continue;
}
for (String userId :userIds){
//人力资源原本已有的假期假别规则id
Map<String,String> psersonSet = personMap.get(userId) == null?null:(Map<String,String>)personMap.get(userId);
@ -156,6 +161,9 @@ public class GetPersonDateBySuitOrganzation extends AbstractCommonCommand<Map<St
//部门假别假期规则id
Map<String,String> departMentHolidayMap = (Map<String,String>)entry.getValue();
List<Map<String,Object>> userIds = hrmListGroupByDepart.get(departMentId);
if (userIds == null || userIds.size() == 0) {
continue;
}
for (Map<String,Object> userIdMap :userIds){
//人力资源原本已有的假期假别规则id
String userId = Util.null2String(userIdMap.get("id"));
@ -179,6 +187,9 @@ public class GetPersonDateBySuitOrganzation extends AbstractCommonCommand<Map<St
//分部假别假期规则id
Map<String,String> subCompanyHolidayMap = (Map<String,String>)entry.getValue();
List<Map<String,Object>> userIds = hrmListGroupBySubCompany.get(subCompanyId);
if (userIds == null || userIds.size() == 0) {
continue;
}
for (Map<String,Object> userIdMap :userIds){
//人力资源原本已有的假期假别规则id
String userId = Util.null2String(userIdMap.get("id"));

@ -506,20 +506,25 @@ public class Utils<T> {
*/
public static int removeTimeWithOvertimePlan(String kssj,String jssj,List<Map<String, Object>> overtimePlanList, Map<String, String> dateToBcxxMap){
//获取作用时段包含计划加班的加班类型、并且勾选了“是否扣除时间区间内的就餐时长”的考勤项目集合
String sql = "select id, mc, zysd, zdkcjcxxsc from uf_jcl_kq_kqxm where xmlx = ?";
//20241008逻辑变更区分休息、就餐时段增加字段“是否扣除时间区间内的休息段时长”
String sql = "select id, mc, zysd, zdkcjcxxsc, sfkcxxdsc from uf_jcl_kq_kqxm where xmlx = ?";
List<Map<String, Object>> jblxAttendanceList = DbTools.getSqlToList(sql, AttendanceItemTypeEnum.WORK_OVERTIME.getKey());
List<String> needDealJblxIdList = jblxAttendanceList.stream()
// List<String> needDealJblxIdList = jblxAttendanceList.stream()
// .filter(f -> Util.null2String(f.get("zysd")).contains(WorkForTimeEnum.PLAN_WORK_OVERTIME.getKey())
// && ("1".equals(Util.null2String(f.get("zdkcjcxxsc"))) || "1".equals(Util.null2String(f.get("sfkcxxdsc")))))
// .map(e->e.get("id").toString())
// .collect(Collectors.toList());
Map<String, Map<String, Object>> needDealJblxMap = jblxAttendanceList.stream()
.filter(f -> Util.null2String(f.get("zysd")).contains(WorkForTimeEnum.PLAN_WORK_OVERTIME.getKey())
&& "1".equals(Util.null2String(f.get("zdkcjcxxsc"))))
.map(e->e.get("id").toString())
.collect(Collectors.toList());
&& ("1".equals(Util.null2String(f.get("zdkcjcxxsc"))) || "1".equals(Util.null2String(f.get("sfkcxxdsc")))))
.collect(Collectors.toMap(e->e.get("id").toString(), e->e));
//对加班计划数据逐条判断是否已经去除休息、就餐时长
List<Map<String, Object>> newOvertimePlanList = new ArrayList<>();
if (dateToBcxxMap != null && dateToBcxxMap.size() > 0) {
for (Map<String, Object> overtimePlanItem : overtimePlanList) {
if (needDealJblxIdList.contains(Util.null2String(overtimePlanItem.get("jblx")))) {
List<Map<String, Object>> overtimePlanWithNoRest = removeRestRange(overtimePlanItem, dateToBcxxMap);
if (!"".equals(Util.null2String(overtimePlanItem.get("jblx"))) && needDealJblxMap.get(overtimePlanItem.get("jblx").toString()) != null) {
List<Map<String, Object>> overtimePlanWithNoRest = removeRestRange(overtimePlanItem, dateToBcxxMap, needDealJblxMap.get(overtimePlanItem.get("jblx").toString()));
if (overtimePlanWithNoRest.size() > 0) {
newOvertimePlanList.addAll(overtimePlanWithNoRest);
}
@ -559,17 +564,21 @@ public class Utils<T> {
/**
* //
* 20241008,
* @param overtimePlanItem
* @param dateToBcxxMap -
* @param jblxInfo
* @return
*/
private static List<Map<String, Object>> removeRestRange(Map<String, Object> overtimePlanItem, Map<String, String> dateToBcxxMap) {
private static List<Map<String, Object>> removeRestRange(Map<String, Object> overtimePlanItem, Map<String, String> dateToBcxxMap, Map<String, Object> jblxInfo) {
List<Map<String, Object>> result = new ArrayList<>();
String startDate = Util.null2String(overtimePlanItem.get("ksrq"));
String startTimePoint = Util.null2String(overtimePlanItem.get("kssj"));
String endDate = Util.null2String(overtimePlanItem.get("jsrq"));
String endTimePoint = Util.null2String(overtimePlanItem.get("jssj"));
String removeRestSc = Util.null2String(jblxInfo.get("sfkcxxdsc"));
String removeDineSc = Util.null2String(jblxInfo.get("zdkcjcxxsc"));
try {
//获取需要比较的班次中的休息/就餐时段
@ -578,7 +587,7 @@ public class Utils<T> {
for (String date : dateList) {
String bcId = dateToBcxxMap.getOrDefault(date, "");
bcId = "".equals(bcId) ? "" : bcId.split("-")[0];
List<Map<String, String>> bcRestRangeInfoItem = getBcRestRangeInfo(bcId, date);
List<Map<String, String>> bcRestRangeInfoItem = getBcRestRangeInfo(bcId, date, removeRestSc, removeDineSc);
if (bcRestRangeInfoItem.size() > 0) {
restRangeInfo.addAll(bcRestRangeInfoItem);
}
@ -602,7 +611,7 @@ public class Utils<T> {
//1-加班区间完全处于休息时段内
overtimeStart = overtimeEnd;
break;
} else if (overtimeStart.compareTo(restRangeStart) < 0 && overtimeEnd.compareTo(restRangeEnd) > 0) {
} else if (overtimeStart.compareTo(restRangeStart) <= 0 && overtimeEnd.compareTo(restRangeEnd) >= 0) {
//2-休息时段完全处于加班区间内
splitRangeItem = new HashMap<>();
splitRangeItem.put("startTime", overtimeStart);
@ -653,18 +662,28 @@ public class Utils<T> {
* /
* @param bcId id
* @param date
* @param removeRestSc
* @param removeDineSc
* @return
*/
private static List<Map<String, String>> getBcRestRangeInfo(String bcId, String date) {
private static List<Map<String, String>> getBcRestRangeInfo(String bcId, String date, String removeRestSc, String removeDineSc) {
List<Map<String, String>> result = new ArrayList<>();
List<String> countBdlxList = new ArrayList<>();
countBdlxList.add(ClassSegmentTypeEnum.REST_AND_DINE.getKey());
countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey());
countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey());
if ("1".equals(removeRestSc) && "1".equals(removeDineSc)) {
countBdlxList.add(ClassSegmentTypeEnum.REST_AND_DINE.getKey());
countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey());
countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey());
} else if ("1".equals(removeRestSc)) {
countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey());
} else if ("1".equals(removeDineSc)) {
countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey());
} else {
return result;
}
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());
List<Map<String, String>> result = new ArrayList<>();
Map<String, String> itemMap;
for (Map<String, Object> bcDetailItem : bcDetailData){
String dtkssj = Utils.getkssjTime(bcDetailItem, date);

Loading…
Cancel
Save