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.

363 lines
21 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.engine.jucailinkq.attendance.attendanceanalysis.service.impl;
import com.engine.jucailinkq.attendance.attendanceanalysis.cmd.GetEvectionCmd;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.EvectionService;
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;
import com.google.common.collect.Maps;
import weaver.general.Util;
import java.time.ZoneOffset;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class EvectionServiceImpl extends Service implements EvectionService {
@Override
public Map<String,Object> evectionByTime(Map<String, Object> param) {
//人员迟到、早退、漏卡等记录
List<Map<String,Object>> abnormalClockInList = (List<Map<String,Object>>)param.get("abnormalClockInList");
//请假开始时间
String kssj = Util.null2String(param.get("kssj"));
//请假结束时间
String jssj = Util.null2String(param.get("jssj"));
//作用时段
String zysd = Util.null2String(param.get("zysd"));
//分析日期
String analysisDate = Util.null2String(param.get("analysisDate"));
//排班
List<Map<String,Object>> scheduleResult = (List<Map<String,Object>>)param.get("scheduleResult");
List<Map<String,Object>> offsetEvectionAnomaly = Lists.newArrayList();
for (int i=0;i<abnormalClockInList.size();i++){
String bdlx = Util.null2String(abnormalClockInList.get(i).get("bdlx"));
String classStartTime = Util.null2String(abnormalClockInList.get(i).get("classStartTime"));
String classEndTime = Util.null2String(abnormalClockInList.get(i).get("classEndTime"));
String betweenMinutes = Util.null2String(abnormalClockInList.get(i).get("betweenMinutes"));
if ((zysd.contains(Utils.getWorkFor(bdlx)) || zysd.contains(WorkForTimeEnum.ALL_TIME.getKey())) &&
!"".equals(classStartTime) && !"".equals(classEndTime)) {
Map<String,Object> leaveMap = Maps.newHashMap();
leaveMap.put("kssj",kssj);
leaveMap.put("jssj",jssj);
int betweenTime = Double.valueOf(betweenMinutes).intValue();
int intersectionTime = Utils.getIntersectionTime(classStartTime,classEndTime,leaveMap,scheduleResult,analysisDate);
if (betweenTime <= intersectionTime){
offsetEvectionAnomaly.add(abnormalClockInList.get(i));
}else {
String hsdw = Util.null2String(abnormalClockInList.get(i).get("hsdw"));
double hsl = Double.valueOf(Util.null2String(abnormalClockInList.get(i).get("hsl")));
double itemduration = Utils.getItemduration(hsl,hsdw,betweenTime-intersectionTime, AccountingUnitEnum.MINUTES,Double.valueOf(scheduleResult.get(0).get("edsc").toString()));
abnormalClockInList.get(i).put("itemduration",itemduration);
abnormalClockInList.get(i).put("betweenMinutes",betweenTime-intersectionTime);
}
}
}
abnormalClockInList.removeAll(offsetEvectionAnomaly);
Map<String,Object> resultMap = Maps.newHashMap();
resultMap.put("abnormalClockInList",abnormalClockInList);
resultMap.put("offsetEvectionAnomaly",offsetEvectionAnomaly);
return resultMap;
}
@Override
public Map<String,Object> evectionByDurationTime(Map<String, Object> param) {
//人员迟到、早退、漏卡等记录
List<Map<String,Object>> abnormalClockInList = (List<Map<String,Object>>)param.get("abnormalClockInList");
List<Map<String,Object>> forgetClockList = abnormalClockInList.stream().filter(e -> e.get("betweenMinutes") == null).collect(Collectors.toList());
abnormalClockInList = abnormalClockInList.stream().filter(e -> e.get("betweenMinutes") != null).collect(Collectors.toList());
abnormalClockInList = abnormalClockInList.stream().sorted(Comparator.comparing(e->Integer.valueOf(e.get("betweenMinutes").toString()))).collect(Collectors.toList());
//请假时长,单位小时
int ccsc = param.get("ccsc") == null?0:Double.valueOf(Math.ceil(Double.valueOf(param.get("ccsc").toString())*60)).intValue();
//同一天可抵消多个异常
List<Map<String,Object>> offsetEvectionAnomaly = Lists.newArrayList();
//作用时段
String zysd = Util.null2String(param.get("zysd"));
String tybcndbjlhbjs = Util.null2String(param.get("tybcndbjlhbjs"));
for (int i=0;i<abnormalClockInList.size();i++){
int time = Integer.valueOf(abnormalClockInList.get(i).get("betweenMinutes").toString());
String bdlx = Util.null2String(abnormalClockInList.get(i).get("bdlx"));
if (zysd.contains(Utils.getWorkFor(bdlx)) || zysd.contains(WorkForTimeEnum.ALL_TIME.getKey())){
if (ccsc >= time){
offsetEvectionAnomaly.add(abnormalClockInList.get(i));
ccsc = ccsc-time;
}else {
ccsc = 0;
time = time-ccsc;
abnormalClockInList.get(i).put("betweenMinutes",time);
}
}
}
abnormalClockInList.removeAll(offsetEvectionAnomaly);
// if (CheckBoxEnum.CHECKED.getKey().equals(tybcndbjlhbjs)){
// for (int i=abnormalClockInList.size() -1;i>=0;i--){
// int time = Integer.valueOf(abnormalClockInList.get(i).get("betweenMinutes").toString());
// String bdlx = Util.null2String(abnormalClockInList.get(i).get("bdlx"));
// if (ccsc > time && (zysd.contains(Utils.getWorkFor(bdlx)) || zysd.contains(WorkForTimeEnum.ALL_TIME.getKey()))){
// ccsc = ccsc-time;
// offsetEvectionAnomaly.add(abnormalClockInList.get(i));
// }
// }
// abnormalClockInList.removeAll(offsetEvectionAnomaly);
// }else{
// for (int i=abnormalClockInList.size() -1;i>=0;i--){
// int time = Integer.valueOf(abnormalClockInList.get(i).get("betweenMinutes").toString());
// String bdlx = Util.null2String(abnormalClockInList.get(i).get("bdlx"));
// if (ccsc > time && (zysd.contains(Utils.getWorkFor(bdlx)) || zysd.contains(WorkForTimeEnum.ALL_TIME.getKey()))){
// offsetEvectionAnomaly.add(abnormalClockInList.get(i));
// abnormalClockInList.remove(i);
// break;
// }
// }
// }
abnormalClockInList.addAll(forgetClockList);
Map<String,Object> resultMap = Maps.newHashMap();
resultMap.put("abnormalClockInList",abnormalClockInList);
resultMap.put("offsetEvectionAnomaly",offsetEvectionAnomaly);
return resultMap;
}
@Override
public Map<String,Object> evectionByHalfDay(Map<String, Object> param) {
Map<String,Object> resultMap = Maps.newHashMap();
//人员迟到、早退、漏卡等记录
List<Map<String,Object>> abnormalClockInList = (List<Map<String,Object>>)param.get("abnormalClockInList");
//班次
List<Map<String,Object>> scheduleResult = (List<Map<String,Object>>)param.get("scheduleResult");
//作用时段
String zysd = Util.null2String(param.get("zysd"));
//作用时段
String analysisDate = Util.null2String(param.get("analysisDate"));
//半天规则
String btgz = Util.null2String(scheduleResult.get(0).get("btgz"));
//额定时长
double edsc = Double.valueOf(scheduleResult.get(0).get("edsc").toString());
Map<String,Object> evectionItem = (Map<String,Object>)param.get("evectionItem");
//核算量
double hsl = Double.valueOf(Util.null2String(evectionItem.get("hsl")));
//核算单位
String hsdw = Util.null2String(evectionItem.get("hsdw"));
List<Map<String,Object>> offsetEvectionAnomaly = Lists.newArrayList();
List<String> classSegmens = Lists.newArrayList();
for (String str:zysd.split(",")){
classSegmens.add(Utils.getClassSegmenByWorkFor(str));
}
List<Map<String,Object>> abnormalList = Lists.newArrayList();
for (Map<String,Object> abnormalClock:abnormalClockInList){
if (classSegmens.contains(abnormalClock.get("bdlx"))){
abnormalList.add(abnormalClock);
}
}
double itemduration = 0;
if (btgz.equals(HalfDayRuleREnum.BY_CLASS_SET.getKey())){
//按班次设置
Map<String,Object> haveAbnormalScheduleMap = getHaveAbnormalScheduleMap(scheduleResult,abnormalList,analysisDate);
List<Map<String,Object>> haveAbnormalScheduleList = (List<Map<String,Object>>)haveAbnormalScheduleMap.get("haveAbnormalScheduleList");
Map<Map<String, Object>,List<Map<String,Object>>> haveAbnormalscheduleMapGroup = (Map<Map<String, Object>,List<Map<String,Object>>>)haveAbnormalScheduleMap.get("haveAbnormalscheduleMapGroup");
double restTime = 0.5;
if (haveAbnormalScheduleList == null || haveAbnormalScheduleList.size() == 0){
//当没有消除异常时默认额度时长一半、天数固定1天
if (hsdw.equals(AccountingUnitEnum.HOUR.getKey())){
itemduration = edsc*0.5;
}else if (hsdw.equals(AccountingUnitEnum.DAY.getKey())){
itemduration = 0.5;
}else if (hsdw.equals(AccountingUnitEnum.MINUTES.getKey())){
itemduration = edsc*30;
}else if (hsdw.equals(AccountingUnitEnum.ONCE.getKey())){
itemduration = 1;
}
}else {
for (int i=haveAbnormalScheduleList.size()-1;i>=0;i--){
double edts = Double.valueOf(haveAbnormalScheduleList.get(i).get("edts").toString());
restTime = Utils.subtract(restTime,edts);
if (restTime >=0){
offsetEvectionAnomaly.addAll(haveAbnormalscheduleMapGroup.get(haveAbnormalScheduleList.get(i)));
if (hsdw.equals(AccountingUnitEnum.HOUR.getKey())){
itemduration += Double.valueOf(haveAbnormalScheduleList.get(i).get("edxss").toString());
}else if (hsdw.equals(AccountingUnitEnum.DAY.getKey())){
itemduration = 0.5;
}else if (hsdw.equals(AccountingUnitEnum.MINUTES.getKey())){
itemduration += Double.valueOf(haveAbnormalScheduleList.get(i).get("edfzs").toString());
}else if (hsdw.equals(AccountingUnitEnum.ONCE.getKey())){
itemduration = 1;
}
}
}
}
}else if (btgz.equals(HalfDayRuleREnum.FIXED_DURATION.getKey())){
//取固定时间
//分隔时间点
String fgsjd = Util.null2String(scheduleResult.get(0).get("fgsjd"));
fgsjd = analysisDate +" "+fgsjd;
String finalFgsjd = fgsjd;
List<Map<String,Object>> beforeAbnormalList = abnormalList.stream().filter(e-> DateUtil.getTime(e.get("pointTime").toString()).compareTo(DateUtil.getTime(finalFgsjd)) <=0).collect(Collectors.toList());
List<Map<String,Object>> afterAbnormalList = abnormalList.stream().filter(e->DateUtil.getTime(e.get("pointTime").toString()).compareTo(DateUtil.getTime(finalFgsjd)) >0).collect(Collectors.toList());
boolean ifBefore = false;
if (beforeAbnormalList.size() > afterAbnormalList.size()){
offsetEvectionAnomaly.addAll(beforeAbnormalList);
ifBefore=true;
}else if (beforeAbnormalList.size() < afterAbnormalList.size()){
offsetEvectionAnomaly.addAll(afterAbnormalList);
}else {
Map<String,Object> beforeHaveAbnormalScheduleMap = getHaveAbnormalScheduleMap(scheduleResult,beforeAbnormalList,analysisDate);
List<Map<String,Object>> beforehaveAbnormalScheduleList = (List<Map<String,Object>>)beforeHaveAbnormalScheduleMap.get("haveAbnormalScheduleList");
double beforeTotalAbnormalMinute = beforehaveAbnormalScheduleList.stream().mapToDouble(e->Double.valueOf(e.get("totalAbnormalMinute").toString())).sum();
Map<String,Object> afterHaveAbnormalScheduleMap = getHaveAbnormalScheduleMap(scheduleResult,afterAbnormalList,analysisDate);
List<Map<String,Object>> afterhaveAbnormalScheduleList = (List<Map<String,Object>>)afterHaveAbnormalScheduleMap.get("haveAbnormalScheduleList");
double afterTotalAbnormalMinute = afterhaveAbnormalScheduleList.stream().mapToDouble(e->Double.valueOf(e.get("totalAbnormalMinute").toString())).sum();
if (beforeTotalAbnormalMinute > afterTotalAbnormalMinute || beforeTotalAbnormalMinute == afterTotalAbnormalMinute){
offsetEvectionAnomaly.addAll(beforeAbnormalList);
ifBefore=true;
}else if (beforeTotalAbnormalMinute < afterTotalAbnormalMinute){
offsetEvectionAnomaly.addAll(afterAbnormalList);
}
}
if (hsdw.equals(AccountingUnitEnum.DAY.getKey())){
itemduration=0.5;
}else if (hsdw.equals(AccountingUnitEnum.ONCE.getKey())){
itemduration=1;
}else {
String keyName="";
if (hsdw.equals(AccountingUnitEnum.MINUTES.getKey())){
keyName="edfzs";
}else{
keyName="edxss";
}
if (ifBefore){
List<Map<String,Object>> beforeScheduleList = scheduleResult.stream().filter(e-> DateUtil.getTime(Utils.getkssjTime(e,analysisDate)).compareTo(DateUtil.getTime(finalFgsjd))<=0 && classSegmens.contains(e.get("bdlx"))).collect(Collectors.toList());
for (int i=0;i<beforeScheduleList.size();i++){
if (i == beforeScheduleList.size()-1){
if (keyName.equals("edfzs")){
itemduration+=DateUtil.getBetWeenMinutes(Utils.getkssjTime(beforeScheduleList.get(i),analysisDate),fgsjd);
}else if (keyName.equals("edxss")){
itemduration+=Utils.divide(DateUtil.getBetWeenMinutes(Utils.getkssjTime(beforeScheduleList.get(i),analysisDate),fgsjd),60);
}
}else {
itemduration+=Double.valueOf(beforeScheduleList.get(i).get(keyName).toString());
}
}
}else {
List<Map<String,Object>> afterScheduleList = scheduleResult.stream().filter(e-> DateUtil.getTime(Utils.getjssjTime(e,analysisDate)).compareTo(DateUtil.getTime(finalFgsjd))>=0 && classSegmens.contains(e.get("bdlx"))).collect(Collectors.toList());
for (int i=0;i<afterScheduleList.size();i++){
if (i == 0){
if (keyName.equals("edfzs")){
itemduration+=DateUtil.getBetWeenMinutes(fgsjd,Utils.getjssjTime(afterScheduleList.get(i),analysisDate));
}else if (keyName.equals("edxss")){
itemduration+=Utils.divide(DateUtil.getBetWeenMinutes(fgsjd,Utils.getjssjTime(afterScheduleList.get(i),analysisDate)),60);
}
}else {
itemduration+=Double.valueOf(afterScheduleList.get(i).get(keyName).toString());
}
}
}
}
}
AccountingUnitEnum itemdurationType = null;
if (hsdw.equals(AccountingUnitEnum.HOUR.getKey())){
itemdurationType = AccountingUnitEnum.HOUR;
}else if (hsdw.equals(AccountingUnitEnum.DAY.getKey())){
itemdurationType = AccountingUnitEnum.DAY;
}else if (hsdw.equals(AccountingUnitEnum.MINUTES.getKey())){
itemdurationType = AccountingUnitEnum.MINUTES;
}else if (hsdw.equals(AccountingUnitEnum.ONCE.getKey())){
itemdurationType = AccountingUnitEnum.ONCE;
}
itemduration = Utils.getItemduration(hsl,hsdw,itemduration,itemdurationType,Double.valueOf(scheduleResult.get(0).get("edsc").toString()));
abnormalClockInList.removeAll(offsetEvectionAnomaly);
abnormalClockInList = getAbnormalClockInList(abnormalClockInList,offsetEvectionAnomaly);
resultMap.put("offsetEvectionAnomaly",offsetEvectionAnomaly);
resultMap.put("abnormalClockInList",abnormalClockInList);
resultMap.put("itemduration",itemduration);
return resultMap;
}
@Override
public Map<String, Object> getEvection(Map<String, Object> param) {
return commandExecutor.execute(new GetEvectionCmd(param));
}
/**
* 根据班段获得对应的异常
* @param scheduleResult
* @param abnormalClockInList
* @param analysisDate
* @return
*/
public Map<String,Object> getHaveAbnormalScheduleMap(List<Map<String,Object>> scheduleResult,List<Map<String,Object>> abnormalClockInList,String analysisDate){
Map<Map<String, Object>,List<Map<String,Object>>> scheduleMapGroup = Maps.newHashMap();
List<Map<String,Object>> haveAbnormalScheduleList = Lists.newArrayList();
for (Map<String, Object> scheduleMap :scheduleResult){
if (scheduleMap.get("edts") == null || Double.valueOf(scheduleMap.get("edts").toString()) == 0){
continue;
}
List<Map<String,Object>> list = Utils.getAbnormalListBySchedule(scheduleMap,abnormalClockInList,analysisDate);
if (list.size() > 0){
double totalTime=0;
for (Map<String,Object> abnormal:list){
AttendanceItemTypeEnum itemType = (AttendanceItemTypeEnum)abnormal.get("itemType");
if (itemType == AttendanceItemTypeEnum.MISSE_CARD){
totalTime = Double.valueOf(scheduleMap.get("edxss").toString())*60;
break;
}
int betweenMinutes = Integer.valueOf(Util.null2String(abnormal.get("betweenMinutes")==null?"0":abnormal.get("betweenMinutes")));
totalTime+=betweenMinutes;
}
scheduleMap.put("totalAbnormalMinute",totalTime);
haveAbnormalScheduleList.add(scheduleMap);
scheduleMapGroup.put(scheduleMap,list);
}
}
haveAbnormalScheduleList = haveAbnormalScheduleList.stream().sorted(Comparator.comparing(e->Double.valueOf(e.get("totalAbnormalMinute").toString()))).collect(Collectors.toList());
Map<String,Object> resultMap = Maps.newHashMap();
resultMap.put("haveAbnormalScheduleList",haveAbnormalScheduleList);
resultMap.put("haveAbnormalscheduleMapGroup",scheduleMapGroup);
return resultMap;
}
/**
* 当消除的异常中存在record为true需要记录的异常时查找符合条件的record为false的异常记录替代消除的异常
* @param abnormalClockInList
* @param offsetEvectionAnomaly
* @return
*/
public List<Map<String,Object>> getAbnormalClockInList(List<Map<String,Object>> abnormalClockInList,List<Map<String,Object>> offsetEvectionAnomaly){
abnormalClockInList = abnormalClockInList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("pointTime").toString()).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
for (Map<String,Object> offsetAbnormal:offsetEvectionAnomaly){
if ((boolean)offsetAbnormal.get("record")){
AttendanceItemTypeEnum itemType = (AttendanceItemTypeEnum)offsetAbnormal.get("itemType");
String classStartTime = Util.null2String(offsetAbnormal.get("classStartTime"));
String classEndTime = Util.null2String(offsetAbnormal.get("classEndTime"));
if (abnormalClockInList.size() > 0 && !"".equals(classStartTime) && !"".equals(classEndTime)){
for (int i = abnormalClockInList.size()-1;i>=0;i--){
if (!(boolean)abnormalClockInList.get(i).get("record") && abnormalClockInList.get(i).get("itemType") == itemType &&
DateUtil.getTime(classStartTime).compareTo(DateUtil.getTime(abnormalClockInList.get(i).get("pointTime").toString())) <= 0 &&
DateUtil.getTime(classEndTime).compareTo(DateUtil.getTime(abnormalClockInList.get(i).get("pointTime").toString())) >=0){
abnormalClockInList.get(i).put("record",true);
break;
}
}
}
}
}
return abnormalClockInList;
}
}