diff --git a/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/GetClockInTimeListCmd.java b/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/GetClockInTimeListCmd.java index 90d0ce1..d98d74e 100644 --- a/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/GetClockInTimeListCmd.java +++ b/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/GetClockInTimeListCmd.java @@ -164,6 +164,36 @@ public class GetClockInTimeListCmd extends AbstractCommonCommand0){ + for (int i=1;i<=8;i++){ + String in = Util.null2String(clockIntime.get("j"+i)); + String out = Util.null2String(clockIntime.get("c"+i)); + if (!"".equals(in) && !"NULL".equals(in)){ + if (DateUtil.getTime(in).compareTo(DateUtil.getTime(lastestTime)) <= 0){ + mark = true; + lastestTime = in; + } + break; + }else if (!"".equals(out) && !"NULL".equals(out)){ + if (DateUtil.getTime(out).compareTo(DateUtil.getTime(lastestTime)) <= 0){ + mark = true; + lastestTime = out; + } + break; + } + } + } + if (mark){ + lastestTime = DateUtil.beforeSeconds(lastestTime,1); + } + } + log.debug("earliestTime :[{}],lastestTime: [{}]",earliestTime,lastestTime); String finalEarliestTime = earliestTime; String finalLastestTime = lastestTime; diff --git a/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/RecordDataCmd.java b/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/RecordDataCmd.java index 6aa9da0..8768797 100644 --- a/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/RecordDataCmd.java +++ b/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/RecordDataCmd.java @@ -384,12 +384,15 @@ public class RecordDataCmd extends AbstractCommonCommand> { if (newDataList != null && newDataList.size() > 0 && newDataList.get(0).size() > 1){ double totalKtsc = newDataList.stream().mapToDouble(e->Double.valueOf(e.get("ktsc").toString())).sum(); double totalJxsc = newDataList.stream().mapToDouble(e->Double.valueOf(e.get("jxsc").toString())).sum(); + double totalWxsc = newDataList.stream().mapToDouble(e->Double.valueOf(e.get("wxsc").toString())).sum(); + Map newData = newDataList.get(0); List> oldData = oldHolidayGroupByType.get(jblx); if (oldData == null || oldData.size() == 0){ newData.put("ktsc",totalKtsc); newData.put("jxsc",totalJxsc); + newData.put("wxsc",totalWxsc); beforeHolidays.put(newData.get("jqid").toString(),DbTools.getSqlToList(queryHolidaySql,newData.get("ygid"),newData.get("jqid"))); //老数据不存在,新数据存在。新增数据 insertList.add(newData); diff --git a/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/getclockInpoint/AdjustLastWorkPointCmd.java b/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/getclockInpoint/AdjustLastWorkPointCmd.java new file mode 100644 index 0000000..2dee0a0 --- /dev/null +++ b/src/com/engine/jucailinkq/attendance/attendanceanalysis/cmd/getclockInpoint/AdjustLastWorkPointCmd.java @@ -0,0 +1,54 @@ +package com.engine.jucailinkq.attendance.attendanceanalysis.cmd.getclockInpoint; + +import com.engine.jucailinkq.attendance.attendanceanalysis.cmd.getclockInpoint.biz.AbstractAdjustClockPointAction; +import com.engine.jucailinkq.attendance.attendanceanalysis.dto.clockpoint.ClockPointDTO; +import com.engine.jucailinkq.attendance.attendanceanalysis.dto.clockpoint.ClockPointInfo; +import com.engine.jucailinkq.attendance.enums.ClassSegmentTypeEnum; +import com.engine.jucailinkq.attendance.enums.ClockPointEnum; +import com.engine.jucailinkq.common.util.DateUtil; + +import java.time.ZoneOffset; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class AdjustLastWorkPointCmd extends AbstractAdjustClockPointAction { + @Override + public List execute(ClockPointInfo clockPointInfo) { + + //卡点集合 + List clcokInPointList = clockPointInfo.getClcokInPointList(); + String analysisDate = clockPointInfo.getAnalysisDate(); + + clcokInPointList = clcokInPointList.stream().sorted(Comparator.comparing(e-> DateUtil.getTime(e.getClassTime()).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList()); + + + + int lastWorkPoint = clcokInPointList.size()-3; + if (lastWorkPoint >0 && clcokInPointList.get(lastWorkPoint).getPointType().equals(ClockPointEnum.END) &&(clcokInPointList.get(lastWorkPoint).getClassSegmentType().equals(ClassSegmentTypeEnum.WORK_TIME.getKey()) || + clcokInPointList.get(lastWorkPoint).getClassSegmentType().equals(ClassSegmentTypeEnum.OVERTIME_PLAN.getKey()))){ + ClockPointDTO lastWorkClockPoint = clcokInPointList.get(lastWorkPoint); + String lastclassTime = lastWorkClockPoint.getClassTime(); + Map signClockMap = null; + for (int i=clcokInPointList.size()-1;i>lastWorkPoint;i--){ + signClockMap = clcokInPointList.get(i).getClockTime(); + if (signClockMap != null){ + break; + } + } + if (signClockMap != null && DateUtil.getTime(lastclassTime).compareTo(DateUtil.getTime(signClockMap.get("signdate")+" "+signClockMap.get("signtime"))) >0){ + lastWorkClockPoint.setClockTime(signClockMap); + lastWorkClockPoint.setTimeType(ClockPointEnum.BEFORE); + lastWorkClockPoint.setElasticTime(null); + lastWorkClockPoint.setResetCard(true); + for (int i=lastWorkPoint+1;i0 && endClockPointDTO.get(0).isResetCard() && scheduleMap.get("beforeClassSegment").equals(ClassSegmentTypeEnum.WORK_TIME.getKey())){ + dinnerTime=0; + } + log.debug("未扣减过的加班时长: {}", jbsc); log.debug("beLateTime :[{}],leaveElaryTime :[{}],askForLeaveTime:[{}],evectionTime:[{}],dinnerTime:[{}]", beLateTime, leaveElaryTime, askForLeaveTime, evectionTime, dinnerTime); BigDecimal jbscbig = new BigDecimal(jbsc); diff --git a/src/com/engine/jucailinkq/attendance/attendanceanalysis/dto/clockpoint/ClockPointDTO.java b/src/com/engine/jucailinkq/attendance/attendanceanalysis/dto/clockpoint/ClockPointDTO.java index 6468dcb..21b0913 100644 --- a/src/com/engine/jucailinkq/attendance/attendanceanalysis/dto/clockpoint/ClockPointDTO.java +++ b/src/com/engine/jucailinkq/attendance/attendanceanalysis/dto/clockpoint/ClockPointDTO.java @@ -53,5 +53,5 @@ public class ClockPointDTO { /** * 来源卡点,当record为false时,该值才有值 */ - private ClockPointDTO resourceClockPointDTO; + private boolean resetCard; } diff --git a/src/com/engine/jucailinkq/attendance/attendanceanalysis/service/impl/AbnormalAttendanceServiceImpl.java b/src/com/engine/jucailinkq/attendance/attendanceanalysis/service/impl/AbnormalAttendanceServiceImpl.java index 8e37e7c..de29f71 100644 --- a/src/com/engine/jucailinkq/attendance/attendanceanalysis/service/impl/AbnormalAttendanceServiceImpl.java +++ b/src/com/engine/jucailinkq/attendance/attendanceanalysis/service/impl/AbnormalAttendanceServiceImpl.java @@ -4,6 +4,7 @@ import com.engine.jucailinkq.attendance.attendanceanalysis.cmd.item.*; import com.engine.jucailinkq.attendance.attendanceanalysis.dto.clockpoint.ClockPointDTO; import com.engine.jucailinkq.attendance.attendanceanalysis.service.AbnormalAttendanceService; import com.engine.jucailinkq.attendance.enums.*; +import com.engine.jucailinkq.common.util.DateUtil; import com.engine.jucailinkq.common.util.Utils; import com.engine.core.impl.Service; import com.google.common.collect.Lists; @@ -59,7 +60,12 @@ public class AbnormalAttendanceServiceImpl extends Service implements AbnormalAt if (clcokInTimedto.getElasticTime() != null && !"".equals(clcokInTimedto.getElasticTime())){ classStartTime = clcokInTimedto.getElasticTime(); } - int between = Utils.removeRestTime(classStartTime,clockInTime,scheduleResult,analysisDate); + int between = 0; + if (clcokInTimedto.isResetCard()){ + between = DateUtil.getBetWeenMinutes(classStartTime,clockInTime); + }else { + between = Utils.removeRestTime(classStartTime,clockInTime,scheduleResult,analysisDate); + } if (between == 0){ return resultList; } @@ -222,8 +228,14 @@ public class AbnormalAttendanceServiceImpl extends Service implements AbnormalAt if (clockPointDTO.getElasticTime() != null && !"".equals(clockPointDTO.getElasticTime())){ classEndTime = clockPointDTO.getElasticTime(); } + int between = 0; + if (clockPointDTO.isResetCard()){ + between = DateUtil.getBetWeenMinutesOver(clockInTime,classEndTime); + }else { + between = Utils.removeRestTimeForLeaveEarly(clockInTime,classEndTime,scheduleResult,analysisDate); + + } - int between = Utils.removeRestTime(clockInTime,classEndTime,scheduleResult,analysisDate); if (between == 0){ return resultList; } diff --git a/src/com/engine/jucailinkq/attendance/attendanceanalysis/service/impl/ShiftServiceImpl.java b/src/com/engine/jucailinkq/attendance/attendanceanalysis/service/impl/ShiftServiceImpl.java index 89b0bc3..39ad5c3 100644 --- a/src/com/engine/jucailinkq/attendance/attendanceanalysis/service/impl/ShiftServiceImpl.java +++ b/src/com/engine/jucailinkq/attendance/attendanceanalysis/service/impl/ShiftServiceImpl.java @@ -80,12 +80,8 @@ public class ShiftServiceImpl extends Service implements ShiftService { result = compareMap; continue; } - //1-比较各候选班次实际打卡正常的时间点个数B String resultB = Util.null2String(result.get("judgePartB")); - if (!resultB.equals(compareB)) { - result = Double.valueOf(resultB) < Double.valueOf(compareB) ? compareMap : result; - continue; - } + //2-B相同时,比较B/A最大。各候选班次(结合了请假、出差、加班等)需要打卡的时间点个数A String resultA = Util.null2String(result.get("judgePartA")); String compareA = Util.null2String(compareMap.get("judgePartA")); @@ -95,6 +91,13 @@ public class ShiftServiceImpl extends Service implements ShiftService { result = resultBDividedA < compareBDividedA ? compareMap : result; continue; } + + //1-比较各候选班次实际打卡正常的时间点个数B + if (!resultB.equals(compareB)) { + result = Double.valueOf(resultB) < Double.valueOf(compareB) ? compareMap : result; + continue; + } + //3-B/A相同时C最小。异常总分钟数C String resultC = Util.null2String(result.get("judgePartC")); String compareC = Util.null2String(compareMap.get("judgePartC")); diff --git a/src/com/engine/jucailinkq/attendance/attendanceanalysis/wrapper/UpdateAttendanceResultWrapper.java b/src/com/engine/jucailinkq/attendance/attendanceanalysis/wrapper/UpdateAttendanceResultWrapper.java index a0eb544..69f9a9b 100644 --- a/src/com/engine/jucailinkq/attendance/attendanceanalysis/wrapper/UpdateAttendanceResultWrapper.java +++ b/src/com/engine/jucailinkq/attendance/attendanceanalysis/wrapper/UpdateAttendanceResultWrapper.java @@ -355,7 +355,12 @@ public class UpdateAttendanceResultWrapper extends Service { timeMinutes = qjscMinute; } log.debug("recordAskForLeave timeMinutes :[{}] ,hsl:{},hsdw",timeMinutes,hsl,hsdw); - itemduration = Utils.getItemduration(hsl,hsdw,timeMinutes,AccountingUnitEnum.MINUTES,Double.valueOf(scheduleResult.get(0).get("edsc").toString())); + if (hsdw.equals(AccountingUnitEnum.HOUR.getKey()) && timeMinutes==qjscMinute){ + itemduration = Double.valueOf(qjsc); + }else { + itemduration = Utils.getItemduration(hsl,hsdw,timeMinutes,AccountingUnitEnum.MINUTES,Double.valueOf(scheduleResult.get(0).get("edsc").toString())); + + } param.put("kssj",kssj); param.put("jssj",jssj); if (abnormalClockInList.size()>0){ @@ -366,7 +371,7 @@ public class UpdateAttendanceResultWrapper extends Service { } if (sffzcx.equals(CheckBoxEnum.CHECKED.getKey())){ //按时间区间请假时 将连接的同一类型时段设置一种假别 计算出分钟时长后按核算量算出核算时长及单位即可 - Map proportionMap = Utils.getAskLeaveAndEvctionProportion(kssj,jssj,scheduleResult,analysisDate); + Map proportionMap = Utils.getAskLeaveAndEvctionProportion(kssj,jssj,scheduleResult,analysisDate,zdycbcndfgzsd); for (Map.Entry entry: proportionMap.entrySet()){ String bdlx = entry.getKey(); int betweenTimes = Integer.valueOf(entry.getValue().toString()); @@ -560,7 +565,7 @@ public class UpdateAttendanceResultWrapper extends Service { if (sffzcx.equals(CheckBoxEnum.CHECKED.getKey())){ //按时间区间请假时 将连接的同一类型时段设置一种假别 计算出分钟时长后按核算量算出核算时长及单位即可 - Map proportionMap = Utils.getAskLeaveAndEvctionProportion(kssj,jssj,scheduleResult,analysisDate); + Map proportionMap = Utils.getAskLeaveAndEvctionProportion(kssj,jssj,scheduleResult,analysisDate,zdycbcndfgzsd); for (Map.Entry entry: proportionMap.entrySet()){ String bdlx = entry.getKey(); int betweenTimes = Integer.valueOf(entry.getValue().toString()); 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 a7963f7..a6b9910 100644 --- a/src/com/engine/jucailinkq/attendance/workflow/service/impl/AskForLeaveServiceImpl.java +++ b/src/com/engine/jucailinkq/attendance/workflow/service/impl/AskForLeaveServiceImpl.java @@ -309,34 +309,35 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic entry.getValue(), editedEmpLeaveInfo.get(entry.getKey()), jbIdToHsdw, empIdToDateRatedHours.get(entry.getKey())); } if (detailListItem.size() > 0) { - Map>> detailGroup = detailListItem.stream().collect(Collectors.groupingBy(e->Util.null2String(e.get("ksrq"))+"&"+Util.null2String(e.get("jsrq")))); - List> newDetailListItem = Lists.newArrayList(); - for (Map.Entry>> detailEntry :detailGroup.entrySet()){ - String date = detailEntry.getKey(); - List> detailList = detailEntry.getValue(); - if (detailList.size() > 1){ - String jqye = ""; - double qjsc = 0; - for (Map map:detailList){ - if (!Util.null2String(map.get("jqye")).equals("")){ - jqye += map.get("jqye")+","; - } - qjsc +=Double.valueOf(map.get("qjsc")); - } - if (!jqye.equals("")){ - jqye = jqye.substring(0,jqye.length()-1); - } - detailList.get(0).put("jqye",jqye); - detailList.get(0).put("qjsc",Util.null2String(qjsc)); - detailList.get(0).put("qjlx",holidayPriorityItemList.get(holidayPriorityItemList.size()-1).get("id").toString()); - detailList.get(0).put("qjlxName",holidayPriorityItemList.get(holidayPriorityItemList.size()-1).get("mc").toString()); - newDetailListItem.add(detailList.get(0)); - }else { - newDetailListItem.addAll(detailList); - } - } - - completeLeaveDetailList.addAll(newDetailListItem); + completeLeaveDetailList.addAll(detailListItem); +// Map>> detailGroup = detailListItem.stream().collect(Collectors.groupingBy(e->Util.null2String(e.get("ksrq"))+"&"+Util.null2String(e.get("jsrq")))); +// List> newDetailListItem = Lists.newArrayList(); +// for (Map.Entry>> detailEntry :detailGroup.entrySet()){ +// String date = detailEntry.getKey(); +// List> detailList = detailEntry.getValue(); +// if (detailList.size() > 1){ +// String jqye = ""; +// double qjsc = 0; +// for (Map map:detailList){ +// if (!Util.null2String(map.get("jqye")).equals("")){ +// jqye += map.get("jqye")+","; +// } +// qjsc +=Double.valueOf(map.get("qjsc")); +// } +// if (!jqye.equals("")){ +// jqye = jqye.substring(0,jqye.length()-1); +// } +// detailList.get(0).put("jqye",jqye); +// detailList.get(0).put("qjsc",Util.null2String(qjsc)); +// detailList.get(0).put("qjlx",holidayPriorityItemList.get(holidayPriorityItemList.size()-1).get("id").toString()); +// detailList.get(0).put("qjlxName",holidayPriorityItemList.get(holidayPriorityItemList.size()-1).get("mc").toString()); +// newDetailListItem.add(detailList.get(0)); +// }else { +// newDetailListItem.addAll(detailList); +// } +// } +// +// completeLeaveDetailList.addAll(newDetailListItem); } } @@ -1325,7 +1326,11 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic if (leaveHours > 0) { holidayPriorityItemList = holidayPriorityItemList.stream().filter(f -> !checkAmountJqIdList.contains(f.get("id").toString())).collect(Collectors.toList()); if (holidayPriorityItemList.size() == 0) { - errorMessage.add(empName + "_" + ksrq + "假期余额不足!"); + if (leaveDurationMap.get("minLeaveDurationSign") != null){ + errorMessage.add(empName + "_" + ksrq + "不满足请假最小单位"+leaveDurationMap.get("minLeaveDurationSign")+"小时"); + }else { + errorMessage.add(empName + "_" + ksrq + "假期余额不足!"); + } matchResultSign = false; } boolean jqlxEdited = false; @@ -1353,7 +1358,9 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic if (jqlxEdited) { //人员id+日期+假期类型三种条件约束唯一性 message = message + "_" + ksrq + "本流程中已存在一笔该请假类型的请假明细!"; - } else { + } else if (leaveDurationMap.get("minLeaveDurationSign") != null){ + message = message + "_" + ksrq + "不满足请假最小单位"+leaveDurationMap.get("minLeaveDurationSign")+"小时"; + }else { //假期余额不足 message = message + "_" + ksrq + "假期余额不足!"; } @@ -1785,10 +1792,11 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic //2-如果编辑记录中不存在,则需要判断是否满足最小使用时长 if (!minLeaveDurationSign) { String minLeaveDuration = Util.null2String(holidayBalance.get("minLeaveDuration")); - minLeaveDurationSign = "".equals(minLeaveDuration) || totalLeaveDuration >= Double.parseDouble(minLeaveDuration); + minLeaveDurationSign = "".equals(minLeaveDuration) || leaveHours >= Double.parseDouble(minLeaveDuration); } //不满足最小使用时长,直接执行下一条 if (!minLeaveDurationSign) { + leaveDurationMap.put("minLeaveDurationSign",Double.valueOf(holidayBalance.get("minLeaveDuration").toString())); continue; } //额定未休时长 diff --git a/src/com/engine/jucailinkq/common/util/DateUtil.java b/src/com/engine/jucailinkq/common/util/DateUtil.java index e352529..fe3785a 100644 --- a/src/com/engine/jucailinkq/common/util/DateUtil.java +++ b/src/com/engine/jucailinkq/common/util/DateUtil.java @@ -91,6 +91,10 @@ public class DateUtil { LocalDateTime localDateTime = DateUtil.getTime(time); return localDateTime.plusSeconds(seconds).format(yyyyMMddHHmmss); } + public static String beforeSeconds(String time,long seconds){ + LocalDateTime localDateTime = DateUtil.getTime(time); + return localDateTime.minusSeconds(seconds).format(yyyyMMddHHmmss); + } public static String nowMonth(String time){ LocalDateTime localDateTime = LocalDate.parse(time, yyyyMMdd).atStartOfDay(); @@ -276,6 +280,21 @@ public class DateUtil { long daysBetween = ChronoUnit.MINUTES.between(startDate, endDate); return Math.toIntExact(daysBetween); } + /** + * 获得当前时间相差的分钟数 + * @param startTime 开始时间 yyyy-MM-dd + * @return + */ + public static int getBetWeenMinutesOver(String startTime,String endTime){ + LocalDateTime startDate = DateUtil.getTime(startTime); + LocalDateTime endDate = DateUtil.getTime(endTime); + + long daysBetween = ChronoUnit.MINUTES.between(startDate, endDate); + if (daysBetween == 0 && startDate.compareTo(endDate)<0){ + daysBetween=1; + } + return Math.toIntExact(daysBetween); + } /** * 获得两个时间相差的小时 diff --git a/src/com/engine/jucailinkq/common/util/Utils.java b/src/com/engine/jucailinkq/common/util/Utils.java index 789f363..029e947 100644 --- a/src/com/engine/jucailinkq/common/util/Utils.java +++ b/src/com/engine/jucailinkq/common/util/Utils.java @@ -460,6 +460,22 @@ public class Utils { } return betweenMinutes; } + /** + * 请假、外出时间扣出休息时间 + * @param kssj 开始时间 + * @param jssj 结束时间 + * @param scheduleResult 班次 + * @return + */ + public static int removeRestTimeForLeaveEarly(String kssj,String jssj,List> scheduleResult,String analysisDate){ + scheduleResult = scheduleResult.stream().filter(e -> ClassSegmentTypeEnum.REST_AND_DINE.getKey().equals(e.get("bdlx")) || + ClassSegmentTypeEnum.REST_PERIOD.getKey().equals(e.get("bdlx")) || ClassSegmentTypeEnum.DINING_PERIOD.getKey().equals(e.get("bdlx"))).collect(Collectors.toList()); + int betweenMinutes = DateUtil.getBetWeenMinutesOver(kssj,jssj)-removeTime(kssj,jssj,scheduleResult,analysisDate); + if (betweenMinutes < 0){ + betweenMinutes = 0; + } + return betweenMinutes; + } /** * 开始时间和结束时间在所给班次中的占比时间 @@ -704,8 +720,11 @@ public class Utils { * @param analysisDate * @return */ - public static Map getAskLeaveAndEvctionProportion(String kssj,String jssj,List> scheduleResult,String analysisDate){ + public static Map getAskLeaveAndEvctionProportion(String kssj,String jssj,List> scheduleResult,String analysisDate,String zdycbcndfgzsd){ Map resultMap = Maps.newHashMap(); + List> restSchedules = scheduleResult.stream().filter(e->(Utils.ifRestClassSegment(e.get("bdlx").toString()))).collect(Collectors.toList()); + + for (Map restSchedule :scheduleResult){ String dtkssj = Utils.getkssjTime(restSchedule,analysisDate); String dtjssj = Utils.getjssjTime(restSchedule,analysisDate); @@ -729,6 +748,11 @@ public class Utils { log.debug("请假时间在休息时间中间"); } if (betweenMinutes > 0){ + if (zdycbcndfgzsd.equals(CheckBoxEnum.CHECKED.getKey())){ + int restBetWeenMinute = removeTime(dtkssj,dtjssj,restSchedules,analysisDate); + betweenMinutes = betweenMinutes-restBetWeenMinute; + } + if (resultMap.get(restSchedule.get("bdlx")) == null){ resultMap.put(restSchedule.get("bdlx").toString(),betweenMinutes); }else {