diff --git a/src/com/engine/jucailinkq/attendance/workflow/service/impl/AskForLeaveServiceImpl.java b/src/com/engine/jucailinkq/attendance/workflow/service/impl/AskForLeaveServiceImpl.java index 8835fbf..b775b5d 100644 --- a/src/com/engine/jucailinkq/attendance/workflow/service/impl/AskForLeaveServiceImpl.java +++ b/src/com/engine/jucailinkq/attendance/workflow/service/impl/AskForLeaveServiceImpl.java @@ -432,7 +432,7 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic if (countBdlxList.contains(ClassSegmentTypeEnum.OVERTIME_PLAN.getKey())) { sql = "select b.jbry,b.ksrq,b.kssj,b.jblx,b.jsrq,b.jssj,b.jbsc,b.gsrq from uf_jcl_kq_jbjh a left join uf_jcl_kq_jbjh_dt1 b on a.id=b.mainid where b.jbry =? and b.ksrq>=? and b.jsrq<=? and (b.jbcx=0 or b.jbcx is null) and a.jlzt=1"; List> overtimePlanList = DbTools.getSqlToList(sql, leaveEmpId, DateUtil.beforeDay(leaveDate,1), DateUtil.AfterDay(endDate,1)); - int scMinutesInOvertimePlan = Utils.removeTimeWithOvertimePlan(leaveDate + " " + startTime, endDate + " " + endTime, overtimePlanList); + int scMinutesInOvertimePlan = Utils.removeTimeWithOvertimePlan(leaveDate + " " + startTime, endDate + " " + endTime, overtimePlanList, dateToBcxxMap); scMinutes = scMinutes + scMinutesInOvertimePlan; } if (scMinutes > 0) { @@ -547,7 +547,7 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic if (countBdlxList.contains(ClassSegmentTypeEnum.OVERTIME_PLAN.getKey())) { sql = "select b.jbry,b.ksrq,b.kssj,b.jblx,b.jsrq,b.jssj,b.jbsc,b.gsrq from uf_jcl_kq_jbjh a left join uf_jcl_kq_jbjh_dt1 b on a.id=b.mainid where b.jbry =? and b.ksrq>=? and b.jsrq<=? and (b.jbcx=0 or b.jbcx is null) and a.jlzt=1"; List> overtimePlanList = DbTools.getSqlToList(sql, leaveEmpId, DateUtil.beforeDay(startDate,1), DateUtil.AfterDay(endDate,1)); - int scMinutesInOvertimePlan = Utils.removeTimeWithOvertimePlan(startDate + " " + startTime, endDate + " " + endTime, overtimePlanList); + int scMinutesInOvertimePlan = Utils.removeTimeWithOvertimePlan(startDate + " " + startTime, endDate + " " + endTime, overtimePlanList, dateToBcxxMap); scMinutes = scMinutes + scMinutesInOvertimePlan; } if (scMinutes > 0) { diff --git a/src/com/engine/jucailinkq/attendance/workflow/service/impl/BusinessTripsApplyServiceImpl.java b/src/com/engine/jucailinkq/attendance/workflow/service/impl/BusinessTripsApplyServiceImpl.java index d83af1c..2498ef3 100644 --- a/src/com/engine/jucailinkq/attendance/workflow/service/impl/BusinessTripsApplyServiceImpl.java +++ b/src/com/engine/jucailinkq/attendance/workflow/service/impl/BusinessTripsApplyServiceImpl.java @@ -393,7 +393,7 @@ public class BusinessTripsApplyServiceImpl extends Service implements BusinessTr if (countBdlxList.contains(ClassSegmentTypeEnum.OVERTIME_PLAN.getKey())) { sql = "select b.jbry,b.ksrq,b.kssj,b.jblx,b.jsrq,b.jssj,b.jbsc,b.gsrq from uf_jcl_kq_jbjh a left join uf_jcl_kq_jbjh_dt1 b on a.id=b.mainid where b.jbry =? and b.ksrq>=? and b.jsrq<=? and (b.jbcx=0 or b.jbcx is null) and a.jlzt=1"; List> overtimePlanList = DbTools.getSqlToList(sql, ccEmpId, DateUtil.beforeDay(ccDate,1), DateUtil.AfterDay(endDate,1)); - int scMinutesInOvertimePlan = Utils.removeTimeWithOvertimePlan(ccDate + " " + startTime, endDate + " " + endTime, overtimePlanList); + int scMinutesInOvertimePlan = Utils.removeTimeWithOvertimePlan(ccDate + " " + startTime, endDate + " " + endTime, overtimePlanList, dateToBcxxMap); scMinutes = scMinutes + scMinutesInOvertimePlan; } if (scMinutes > 0) { @@ -521,7 +521,7 @@ public class BusinessTripsApplyServiceImpl extends Service implements BusinessTr if (countBdlxList.contains(ClassSegmentTypeEnum.OVERTIME_PLAN.getKey())) { sql = "select b.jbry,b.ksrq,b.kssj,b.jblx,b.jsrq,b.jssj,b.jbsc,b.gsrq from uf_jcl_kq_jbjh a left join uf_jcl_kq_jbjh_dt1 b on a.id=b.mainid where b.jbry =? and b.ksrq>=? and b.jsrq<=? and (b.jbcx=0 or b.jbcx is null) and a.jlzt=1"; List> overtimePlanList = DbTools.getSqlToList(sql, ccEmpId, DateUtil.beforeDay(startDate,1), DateUtil.AfterDay(endDate,1)); - int scMinutesInOvertimePlan = Utils.removeTimeWithOvertimePlan(startDate + " " + startTime, endDate + " " + endTime, overtimePlanList); + int scMinutesInOvertimePlan = Utils.removeTimeWithOvertimePlan(startDate + " " + startTime, endDate + " " + endTime, overtimePlanList, dateToBcxxMap); scMinutes = scMinutes + scMinutesInOvertimePlan; } if (scMinutes > 0) { diff --git a/src/com/engine/jucailinkq/common/util/Utils.java b/src/com/engine/jucailinkq/common/util/Utils.java index 748d35d..2feec89 100644 --- a/src/com/engine/jucailinkq/common/util/Utils.java +++ b/src/com/engine/jucailinkq/common/util/Utils.java @@ -23,6 +23,7 @@ import java.math.RoundingMode; import java.net.JarURLConnection; import java.net.URL; import java.net.URLDecoder; +import java.text.ParseException; import java.time.ZoneOffset; import java.util.*; import java.util.jar.JarEntry; @@ -439,10 +440,35 @@ public class Utils { * @param overtimePlanList * @return */ - public static int removeTimeWithOvertimePlan(String kssj,String jssj,List> overtimePlanList){ + public static int removeTimeWithOvertimePlan(String kssj,String jssj,List> overtimePlanList, Map dateToBcxxMap){ + //获取作用时段包含计划加班的加班类型、并且勾选了“是否扣除时间区间内的就餐时长”的考勤项目集合 + String sql = "select id, mc, zysd, zdkcjcxxsc from uf_jcl_kq_kqxm where xmlx = ?"; + List> jblxAttendanceList = DbTools.getSqlToList(sql, AttendanceItemTypeEnum.WORK_OVERTIME.getKey()); + List needDealJblxIdList = 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()); + + //对加班计划数据逐条判断是否已经去除休息、就餐时长 + List> newOvertimePlanList = new ArrayList<>(); + if (dateToBcxxMap != null && dateToBcxxMap.size() > 0) { + for (Map overtimePlanItem : overtimePlanList) { + if (needDealJblxIdList.contains(Util.null2String(overtimePlanItem.get("jblx")))) { + List> overtimePlanWithNoRest = removeRestRange(overtimePlanItem, dateToBcxxMap); + if (overtimePlanWithNoRest.size() > 0) { + newOvertimePlanList.addAll(overtimePlanWithNoRest); + } + } else { + newOvertimePlanList.add(overtimePlanItem); + } + } + } else { + newOvertimePlanList = overtimePlanList; + } + //遍历新的加班计划数据 int betweenMinutes = 0; - log.debug("removeTimeWithOvertimePlan overtimePlanList : {}", overtimePlanList); - for (Map overtimePlanItem : overtimePlanList){ + for (Map overtimePlanItem : newOvertimePlanList) { String dtkssj = overtimePlanItem.get("ksrq") + " " + overtimePlanItem.get("kssj"); String dtjssj = overtimePlanItem.get("jsrq") + " " + overtimePlanItem.get("jssj"); @@ -467,6 +493,126 @@ public class Utils { return betweenMinutes; } + /** + * 去除加班计划中的休息/就餐时段,即将加班计划时段拆分为不含休息/就餐时段的多组加班计划数据 + * @param overtimePlanItem 加班计划信息 + * @param dateToBcxxMap 日期-班次信息映射 + * @return + */ + private static List> removeRestRange(Map overtimePlanItem, Map dateToBcxxMap) { + List> 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")); + + try { + //获取需要比较的班次中的休息/就餐时段 + List> restRangeInfo = new ArrayList<>(); + List dateList = DateUtil.getDatesBetween(DateUtil.beforeDay(startDate, 1), DateUtil.AfterDay(endDate, 1)); + for (String date : dateList) { + String bcId = dateToBcxxMap.getOrDefault(date, ""); + bcId = "".equals(bcId) ? "" : bcId.split("-")[0]; + List> bcRestRangeInfoItem = getBcRestRangeInfo(bcId, date); + if (bcRestRangeInfoItem.size() > 0) { + restRangeInfo.addAll(bcRestRangeInfoItem); + } + } + if (restRangeInfo.size() > 0) { + String overtimeStart = startDate + " " + startTimePoint; + String overtimeEnd = endDate + " " + endTimePoint; + restRangeInfo.sort(Comparator.comparing(o->o.get("startTime"))); + String restRangeStart; + String restRangeEnd; + List> splitRangeInfo = new ArrayList<>(); + Map splitRangeItem; + for (Map restRange : restRangeInfo) { + restRangeStart = Util.null2String(restRange.get("startTime")); + restRangeEnd = Util.null2String(restRange.get("endTime")); + if ("".equals(restRangeStart) || "".equals(restRangeEnd)) { + continue; + } + //分情况处理休息/就餐时段和加班区间的交集情况 + if (restRangeStart.compareTo(overtimeStart) <= 0 && restRangeEnd.compareTo(overtimeEnd) >= 0) { + //1-加班区间完全处于休息时段内 + overtimeStart = overtimeEnd; + break; + } else if (overtimeStart.compareTo(restRangeStart) < 0 && overtimeEnd.compareTo(restRangeEnd) > 0) { + //2-休息时段完全处于加班区间内 + splitRangeItem = new HashMap<>(); + splitRangeItem.put("startTime", overtimeStart); + splitRangeItem.put("endTime", restRangeStart); + splitRangeInfo.add(splitRangeItem); + //更新加班开始时间 + overtimeStart = restRangeEnd; + } else if (restRangeStart.compareTo(overtimeStart) < 0 && restRangeEnd.compareTo(overtimeStart) > 0 && restRangeEnd.compareTo(overtimeEnd) < 0) { + //3仅仅休息时段尾部部分处于加班区间内 + //更新加班开始时间 + overtimeStart = restRangeEnd; + } else if (restRangeStart.compareTo(overtimeStart) > 0 && restRangeStart.compareTo(overtimeEnd) < 0 && restRangeEnd.compareTo(overtimeEnd) > 0) { + //4仅仅休息时段首部部分处于加班区间内 + splitRangeItem = new HashMap<>(); + splitRangeItem.put("startTime", overtimeStart); + splitRangeItem.put("endTime", restRangeStart); + splitRangeInfo.add(splitRangeItem); + break; + } + } + //判断加班区间除去被拆分的前部分,是否还有剩余尾部 + if (overtimeStart.compareTo(overtimeEnd) < 0) { + splitRangeItem = new HashMap<>(); + splitRangeItem.put("startTime", overtimeStart); + splitRangeItem.put("endTime", overtimeEnd); + splitRangeInfo.add(splitRangeItem); + } + //对于被拆分的加班时间段,处理成新的多组加班计划明细 + Map newOvertimePlanItem; + for (Map item : splitRangeInfo) { + newOvertimePlanItem = new HashMap<>(overtimePlanItem); + newOvertimePlanItem.put("ksrq", item.get("startTime").split(" ")[0]); + newOvertimePlanItem.put("kssj", item.get("startTime").split(" ")[1]); + newOvertimePlanItem.put("jsrq", item.get("endTime").split(" ")[0]); + newOvertimePlanItem.put("jssj", item.get("endTime").split(" ")[1]); + result.add(newOvertimePlanItem); + } + } else { + result.add(overtimePlanItem); + } + } catch (Exception e) { + log.error("removeRestRange error:{}",e.getMessage()); + } + return result; + } + + /** + * 获取对应日期班次中的休息/就餐时段信息 + * @param bcId 班次id + * @param date 日期 + * @return + */ + private static List> getBcRestRangeInfo(String bcId, String date) { + List 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> bcDetailData = DbTools.getSqlToList(sql); + bcDetailData = bcDetailData.stream().filter(e -> countBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList()); + + List> result = new ArrayList<>(); + Map itemMap; + for (Map bcDetailItem : bcDetailData){ + String dtkssj = Utils.getkssjTime(bcDetailItem, date); + String dtjssj = Utils.getjssjTime(bcDetailItem, date); + itemMap = new HashMap<>(); + itemMap.put("startTime", dtkssj); + itemMap.put("endTime", dtjssj); + result.add(itemMap); + } + return result; + } + /** * 开始时间和结束时间在班段类型中所占的时间 * @param kssj