You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
9.4 KiB
Java

package com.engine.attendance.attendanceanalysis.cmd.getclockInpoint;
import com.engine.attendance.attendanceanalysis.dto.ClockPointDTO;
import com.engine.attendance.enums.ClassSegmentTypeEnum;
import com.engine.attendance.enums.ClockPointEnum;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.common.util.DateUtil;
import com.engine.common.util.Utils;
import com.engine.core.interceptor.CommandContext;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 在连续的工作、加班时间段只准首尾打卡的情况下
* 加班和工作时段连着时,需根据打卡情况变动规则
*
*/
@Slf4j
public class AdjustByWorkOverTimeCmd extends AbstractCommonCommand<Map<String, Object>> {
public AdjustByWorkOverTimeCmd(Map<String, Object> params) {
this.params = params;
}
@Override
public BizLogContext getLogContext() {
return null;
}
@Override
public Map<String, Object> execute(CommandContext commandContext) {
Map<String,Object> resultMap = Maps.newHashMap();
List<ClockPointDTO> clcokInPointList = (List<ClockPointDTO>)params.get("clcokInPointList");
List<Map<String, Object>> scheduleResult = (List<Map<String, Object>>)params.get("scheduleResult");
scheduleResult = scheduleResult.stream().filter(e -> !ClassSegmentTypeEnum.ASK_FOR_LEAVE.getKey().equals(e.get("bdlx")) && !ClassSegmentTypeEnum.EVECTION.getKey().equals(e.get("bdlx"))).collect(Collectors.toList());
String analysisDate = params.get("analysisDate").toString();
List<Map<String, Object>> askForLeaveAndEvctionScheduleList = (List<Map<String, Object>>)params.get("askForLeaveAndEvctionScheduleList");
List<ClockPointDTO> adjustClcokInPointList = Lists.newArrayList();
for (int i=0;i<clcokInPointList.size();i++){
ClockPointDTO clockPointDTO = clcokInPointList.get(i);
//班次时间
String classTime = clockPointDTO.getClassTime();
String classSegmentType = clockPointDTO.getClassSegmentType();
//当为加班卡点时
if (Utils.ifOverTimeClassSegment(classSegmentType)){
int scheduleIndex = getScheduleIndex(classTime,scheduleResult,analysisDate);
if (clockPointDTO.getPointType() == ClockPointEnum.END){
int adjustScheduleIndex = getBeforeAccordWithScheduleIndex(clcokInPointList,scheduleIndex,scheduleResult,clockPointDTO.getClockTime(),analysisDate);
if (adjustScheduleIndex<scheduleIndex){
//将原先的打卡调整为该班段的结束打卡卡点
Map<String, Object> adjustScheduleMap = scheduleResult.get(adjustScheduleIndex);
String jssj = Utils.getjssjTime(adjustScheduleMap,analysisDate);
//原先卡点不计异常
clockPointDTO.setRecord(false);
ClockPointDTO adjustClockPointDTO = ClockPointDTO.builder().classTime(jssj).pointType(ClockPointEnum.END).timeType(clockPointDTO.getTimeType())
.classSegmentType(adjustScheduleMap.get("bdlx").toString()).clockTime(clockPointDTO.getClockTime()).record(true).build();
adjustClcokInPointList.add(adjustClockPointDTO);
}
}else if (clockPointDTO.getPointType() == ClockPointEnum.START){
//上班卡
int adjustScheduleIndex = getAfterAccordWithScheduleIndex(clcokInPointList,scheduleIndex,scheduleResult,clockPointDTO.getClockTime(),analysisDate);
if (adjustScheduleIndex>scheduleIndex){
//将原先的打卡调整为该班段的结束打卡卡点
Map<String, Object> adjustScheduleMap = scheduleResult.get(adjustScheduleIndex);
String kssj = Utils.getkssjTime(adjustScheduleMap,analysisDate);
//原先卡点不计异常
clockPointDTO.setRecord(false);
ClockPointDTO adjustClockPointDTO = ClockPointDTO.builder().classTime(kssj).pointType(ClockPointEnum.START).timeType(clockPointDTO.getTimeType())
.classSegmentType(adjustScheduleMap.get("bdlx").toString()).clockTime(clockPointDTO.getClockTime()).record(true).build();
adjustClcokInPointList.add(adjustClockPointDTO);
}
}
}
}
adjustClcokInPointList.addAll(clcokInPointList);
log.info("AdjustByWorkOverTimeCmd : [{}]",adjustClcokInPointList);
resultMap.put("clcokInPointList",adjustClcokInPointList);
return resultMap;
}
/**
* 往前递归排班
* @param scheduleIndex
* @param scheduleResult
* @param clockTimeMap 打卡集合
* @return
*/
public int getBeforeAccordWithScheduleIndex(List<ClockPointDTO> clcokInPointList,int scheduleIndex,List<Map<String, Object>> scheduleResult,Map<String, Object> clockTimeMap,String analysisDate){
if (scheduleIndex == 0){
return scheduleIndex;
}
Map<String, Object> scheduleMap = scheduleResult.get(scheduleIndex);
Map<String, Object> beforeScheduleMap = scheduleResult.get(scheduleIndex-1);
String dtkssj = Utils.getkssjTime(scheduleMap,analysisDate);
String beforeDtjssj = Utils.getjssjTime(beforeScheduleMap,analysisDate);
ClockPointDTO nowclockPointDTO = null;
for (ClockPointDTO clockPointDTO :clcokInPointList){
if (clockPointDTO.getClassTime().equals(dtkssj)){
nowclockPointDTO = clockPointDTO;
}
}
String beforeClassSegment = scheduleMap.get("bdlx").toString();
String clockTime = clockTimeMap == null?"" : clockTimeMap.get("signdate")+" "+clockTimeMap.get("signtime");
if (Utils.ifRestClassSegment(beforeClassSegment) || DateUtil.getTime(beforeDtjssj).compareTo(DateUtil.getTime(dtkssj)) != 0 || scheduleMap.get("bdlx").equals(ClassSegmentTypeEnum.WORK_TIME.getKey()) ||
(nowclockPointDTO != null && nowclockPointDTO.getTimeType() != ClockPointEnum.EMPTY)){
//前一个班段为休息班段、与前一个班段不连续时、当前班次为工作时段,不作处理直接返回
return scheduleIndex;
}
if (clockTimeMap == null || DateUtil.getTime(clockTime).compareTo(DateUtil.getTime(dtkssj)) <0){
//当前加班为漏卡或者打卡时间小于加班开始时间进行往前递归
scheduleIndex--;
return getBeforeAccordWithScheduleIndex(clcokInPointList,scheduleIndex,scheduleResult,clockTimeMap,analysisDate);
}else {
return scheduleIndex;
}
}
/**
* 往后递归排班
* @param scheduleIndex
* @param scheduleResult
* @param clockTimeMap 打卡集合
* @return
*/
public int getAfterAccordWithScheduleIndex(List<ClockPointDTO> clcokInPointList,int scheduleIndex,List<Map<String, Object>> scheduleResult,Map<String, Object> clockTimeMap,String analysisDate){
if (scheduleIndex == scheduleResult.size()-1){
return scheduleIndex;
}
Map<String, Object> scheduleMap = scheduleResult.get(scheduleIndex);
Map<String, Object> afterScheduleMap = scheduleResult.get(scheduleIndex+1);
String dtjssj = Utils.getjssjTime(scheduleMap,analysisDate);
String afterDtkssj = Utils.getkssjTime(afterScheduleMap,analysisDate);
String afterClassSegment = scheduleMap.get("bdlx").toString();
String clockTime = clockTimeMap == null?"" : clockTimeMap.get("signdate")+" "+clockTimeMap.get("signtime");
ClockPointDTO nowclockPointDTO = null;
for (ClockPointDTO clockPointDTO :clcokInPointList){
if (clockPointDTO.getClassTime().equals(dtjssj)){
nowclockPointDTO = clockPointDTO;
}
}
if (Utils.ifRestClassSegment(afterClassSegment) || DateUtil.getTime(afterDtkssj).compareTo(DateUtil.getTime(dtjssj)) != 0 || scheduleMap.get("bdlx").equals(ClassSegmentTypeEnum.WORK_TIME.getKey()) ||
(nowclockPointDTO != null && nowclockPointDTO.getTimeType() != ClockPointEnum.EMPTY)){
//后一个班段为休息班段、与后一个上班段不连续时、当前班次为工作时段,不作处理直接返回
return scheduleIndex;
}
if (clockTimeMap == null || DateUtil.getTime(clockTime).compareTo(DateUtil.getTime(dtjssj)) >0){
//当前加班为漏卡或者打卡时间小于加班开始时间进行往前递归
scheduleIndex++;
return getAfterAccordWithScheduleIndex(clcokInPointList,scheduleIndex,scheduleResult,clockTimeMap,analysisDate);
}else {
return scheduleIndex;
}
}
public int getScheduleIndex(String time,List<Map<String, Object>> scheduleResult,String analysisDate){
for (int i =0;i<scheduleResult.size();i++){
String dtkssj = Utils.getkssjTime(scheduleResult.get(i),analysisDate);
String dtjssj = Utils.getjssjTime(scheduleResult.get(i),analysisDate);
if (dtkssj.equals(time) || dtjssj.equals(time)){
return i;
}
}
return -1;
}
}