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.

398 lines
22 KiB
Java

package com.engine.attendance.attendanceanalysis.wrapper;
import com.engine.attendance.attendanceanalysis.dto.clockpoint.ClockPointDTO;
import com.engine.attendance.attendanceanalysis.service.ComprehensiveWorkingHourService;
import com.engine.attendance.attendanceanalysis.service.UtilService;
import com.engine.attendance.attendanceanalysis.service.impl.ComprehensiveWorkingHourServiceImpl;
import com.engine.attendance.attendanceanalysis.service.impl.UtilServiceImpl;
import com.engine.attendance.enums.CheckBoxEnum;
import com.engine.attendance.enums.ClassSegmentTypeEnum;
import com.engine.common.util.CommonUtil;
import com.engine.common.util.DateUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.common.util.Utils;
import com.engine.core.impl.Service;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
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;
/**
* 考勤分析主题逻辑
*/
@Slf4j
public class AttendanceAnalysisWrapper extends Service {
private UtilService utilService = ServiceUtil.getService(UtilServiceImpl.class);
private UpdateAttendanceResultWrapper updateAttendanceResultWrapper = ServiceUtil.getService(UpdateAttendanceResultWrapper.class);
private ComprehensiveWorkingHourService comprehensiveWorkingHourService = ServiceUtil.getService(ComprehensiveWorkingHourServiceImpl.class);
/**
* 考勤分析主逻辑入口
*
* @param userId 人员id
* @param dataList 打卡数据
* @param attendanceItems 考勤项目
*/
public void attendanceAnalysis(String userId, String nowDate, List<Map<String, Object>> dataList, List<Map<String, Object>> attendanceItems, List<Map<String, Object>> workHourItems, Map<String, Map<String, Object>> clockInTimeMap, List<Map<String, Object>> attendaceResult) {
log.info("***********analysis userId:{} start***********", userId);
log.info("clockInTimeDate : [{}]", dataList);
String beforeFourDayDate = DateUtil.beforeDay(nowDate, 4);
String beforeTwoDayDate = DateUtil.beforeDay(nowDate, 2);
String beforeOneDayDate = DateUtil.beforeDay(nowDate, 1);
/** 打卡数据 */
Map<String, List<Map<String, Object>>> collect = Maps.newHashMap();
if (dataList != null && dataList.size() > 0) {
collect = dataList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("signdate"))));
}
/** 获取人员班次*/
Map<String, Object> classesParamMap = Maps.newHashMap();
classesParamMap.put("tableName", "uf_pbjg");
classesParamMap.put("startDate", beforeFourDayDate);
classesParamMap.put("endDate", nowDate);
classesParamMap.put("pblx", "0");
classesParamMap.put("pbdx", userId);
classesParamMap.put("current", "1");
classesParamMap.put("pageSize", 9999);
classesParamMap.put("recurrence", 1);
classesParamMap.put("clockInTimeMap", clockInTimeMap);
classesParamMap.put("attendanceItems", attendanceItems);
classesParamMap.put("clockInData", dataList);
Map<String, Object> schedulMap = utilService.getSchedulingInFormation(classesParamMap);
Map<String, List<Map<String, Object>>> schedulingResultsMap = (Map<String, List<Map<String, Object>>>) schedulMap.get("schedulingResultsMap");
/**计算获取前一天和第二天打卡数据*/
Map<String, Object> getClockTimeParam = Maps.newHashMap();
getClockTimeParam.put("date", beforeOneDayDate);
getClockTimeParam.put("clockInTimeList", dataList);
getClockTimeParam.put("clockInTimeCollect", collect);
getClockTimeParam.put("schedulingResultCollect", schedulingResultsMap);
getClockTimeParam.put("clockInTimeMap", clockInTimeMap);
getClockTimeParam.put("userId", userId);
Map<String, List<Map<String, Object>>> attendaceResultMap = Maps.newHashMap();
if (attendaceResult != null && attendaceResult.size() > 0) {
attendaceResultMap = attendaceResult.stream().collect(Collectors.groupingBy(e -> e.get("rq").toString()));
}
List<Map<String, Object>> beforeOneDayDateattendaceResult = attendaceResultMap.get(beforeOneDayDate);
if (beforeOneDayDateattendaceResult == null || beforeOneDayDateattendaceResult.size() == 0 || (!CheckBoxEnum.CHECKED.getKey().equals(beforeOneDayDateattendaceResult.get(0).get("sgsj")) &&
!"3".equals(beforeOneDayDateattendaceResult.get(0).get("sjzt")))) {
//前一天打卡数据
List<Map<String, Object>> beforeOneDayClockInTimeList = utilService.getClockInTime(getClockTimeParam);
//分析前一天考勤
Map<String, Object> recordDataTime1 = analysis(userId, beforeOneDayDate, beforeOneDayClockInTimeList, schedulingResultsMap.get(beforeOneDayDate), attendanceItems, workHourItems,(Map<String,Object>)schedulMap.get("clockInTimeDataMap"));
clockInTimeMap.put(beforeOneDayDate, recordDataTime1);
}
getClockTimeParam.put("date", beforeTwoDayDate);
List<Map<String, Object>> beforeTwoDayDateattendaceResult = attendaceResultMap.get(beforeTwoDayDate);
if (beforeTwoDayDateattendaceResult == null || beforeTwoDayDateattendaceResult.size() == 0 || (!CheckBoxEnum.CHECKED.getKey().equals(beforeTwoDayDateattendaceResult.get(0).get("sgsj")) &&
!"3".equals(beforeTwoDayDateattendaceResult.get(0).get("sjzt")))) {
//前第二天打卡数据
List<Map<String, Object>> beforeTwoDayClockInTimeList = utilService.getClockInTime(getClockTimeParam);
log.debug("beforeTwoDayClockInTimeList : [{}]", beforeTwoDayClockInTimeList);
//分析前第二天考勤
Map<String, Object> recordDataTime2 = analysis(userId, beforeTwoDayDate, beforeTwoDayClockInTimeList, schedulingResultsMap.get(beforeTwoDayDate), attendanceItems, workHourItems,(Map<String,Object>)schedulMap.get("clockInTimeDataMap"));
clockInTimeMap.put(beforeTwoDayDate, recordDataTime2);
}
}
/**
* 考勤分析主逻辑入口
*
* @param userId 人员id
* @param analysisDate 分析日期
* @param dataList 需要包含分析日期以及分析日期前后2天的3天打卡数据
* @param attendanceItems 人员考勤项目
*/
public void attendanceAnalysisForApi(String userId, String analysisDate, List<Map<String, Object>> dataList, List<Map<String, Object>> attendanceItems, Map<String, Object> schedulMap, List<Map<String, Object>> workHourItems, Map<String, Map<String, Object>> clockInTimeMap,List<Map<String,Object>> attendaceResult) {
log.info("***********analysis userId:{},analysisDate:{} start***********", userId, analysisDate);
log.info("clockInTimeDate : [{}]", dataList);
log.info("attendaceResult : [{}]",attendaceResult);
if (attendaceResult!=null && attendaceResult.size()>0 && (CheckBoxEnum.CHECKED.getKey().equals(attendaceResult.get(0).get("sgsj")) ||
"3".equals(attendaceResult.get(0).get("sjzt")))) {
return;
}
Map<String, List<Map<String, Object>>> collect = Maps.newHashMap();
if (dataList != null && dataList.size() > 0) {
collect = dataList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("signdate"))));
}
Map<String, List<Map<String, Object>>> schedulingResultsMap = (Map<String, List<Map<String, Object>>>) schedulMap.get("schedulingResultsMap");
Map<String, Object> getClockTimeParam = Maps.newHashMap();
getClockTimeParam.put("date", analysisDate);
getClockTimeParam.put("clockInTimeList", dataList);
getClockTimeParam.put("schedulingResultCollect", schedulingResultsMap);
getClockTimeParam.put("clockInTimeMap", clockInTimeMap);
getClockTimeParam.put("clockInTimeCollect", collect);
getClockTimeParam.put("userId", userId);
//打卡数据
List<Map<String, Object>> clockInTimeList = utilService.getClockInTime(getClockTimeParam);
Map<String, Object> recordDataTime = analysis(userId, analysisDate, clockInTimeList, schedulingResultsMap.get(analysisDate), attendanceItems, workHourItems,(Map<String,Object>)schedulMap.get("clockInTimeDataMap"));
clockInTimeMap.put(analysisDate, recordDataTime);
}
/**
* 分析数据
*
* @param userId 分析人员
* @param analysisDate 分析日期
* @param clockInTimeList 打卡数据
* @param scheduleResult 班次
* @param attendanceItems 考勤项目
*/
public Map<String, Object> analysis(String userId, String analysisDate, List<Map<String, Object>> clockInTimeList, List<Map<String, Object>> scheduleResult, List<Map<String, Object>> attendanceItems, List<Map<String, Object>> workHourItems
,Map<String,Object> clockInTimeDataMap) {
Map<String, Object> recordParam = Maps.newHashMap();
Map<String, String> formModeIdMap = Utils.getFormmodeIdMap();
recordParam.put("userId", userId);
recordParam.put("analysisDate", analysisDate);
recordParam.put("classInfo", scheduleResult);
recordParam.put("formmodeIdMap", formModeIdMap);
recordParam.put("attendanceDuration", 0);
recordParam.put("modeId", formModeIdMap.get("uf_jcl_kq_cqjg"));
Map<String, Object> workingHourparam = Maps.newHashMap();
workingHourparam.put("clockInTimeCollect", clockInTimeList);
workingHourparam.put("analysisDate", analysisDate);
workingHourparam.put("userId", userId);
workingHourparam.put("attendanceItems", attendanceItems);
workingHourparam.put("scheduleResult", scheduleResult);
/**
* 津贴
*/
Map<String, Object> allowanceMap = updateAttendanceResultWrapper.allowanceHandle(recordParam);
if (workHourItems != null && workHourItems.size() > 0) {
workingHourparam.put("workHourItem", workHourItems.get(0));
String ifPriority = Util.null2String(workHourItems.get(0).get("hlpbyxsyzhgs"));
//核算工时的日期类型
String hsgsdrqlx = Util.null2String(workHourItems.get(0).get("hsgsdrqlx"));
String rqlx = Utils.getDateType(analysisDate, Util.null2String(workHourItems.get(0).get("qyrl")));
if (CheckBoxEnum.CHECKED.getKey().equals(ifPriority) && CommonUtil.ifContainStr(hsgsdrqlx, rqlx, ",")) {
comprehensiveWorkingHourService.excuteByWorkHour(workingHourparam);
return null;
}
}
if (scheduleResult == null || scheduleResult.size() == 0) {
//没有排班
Map<String, Object> params = Maps.newHashMap();
params.put("userId", userId);
params.put("analysisDate", analysisDate);
params.put("clockInTimeCollect", clockInTimeList);
params.put("modeId", formModeIdMap.get("uf_jcl_kq_cqjg"));
params.put("workHourItems", workHourItems);
params.put("attendanceItems", attendanceItems);
params.put("allowanceMap", allowanceMap);
updateAttendanceResultWrapper.recordNoClass(params);
return null;
}
recordParam.put("rqlx", scheduleResult.get(0).get("rqlx"));
//休息班次,休息班打卡自动加班不算自动加班,扣除原有的工作时段
if (scheduleResult.get(0).get("sfxx") != null && CheckBoxEnum.CHECKED.getKey().equals(scheduleResult.get(0).get("sfxx")) &&
scheduleResult.get(0).get("xxbdkzdjb") != null && CheckBoxEnum.UNCHECKED.getKey().equals(scheduleResult.get(0).get("xxbdkzdjb"))) {
List<Map<String,Object>> overTimePlanList = scheduleResult.stream().filter(e->e.get("bdlx").equals(ClassSegmentTypeEnum.OVERTIME_PLAN.getKey())).collect(Collectors.toList());
if (overTimePlanList.size() >0){
scheduleResult = scheduleResult.stream().filter(e->ClassSegmentTypeEnum.OVERTIME_PLAN.getKey().equals(e.get("bdlx")) || Utils.ifRestClassSegment(e.get("bdlx").toString()) || Utils.ifAskforOrEvctionClassSegment(e.get("bdlx").toString())).collect(Collectors.toList());
}else {
//没有加班计划,直接记为休息
updateAttendanceResultWrapper.recordRest(recordParam);
return null;
}
}
List<Map<String, Object>> askForLeaveAndEvctionSchedule = Lists.newArrayList();
//请假记录
Map<String, Object> askForLeaveDataMap = updateAttendanceResultWrapper.getAskForLeave(workingHourparam);
if (askForLeaveDataMap.get("alldayVaction") != null) {
//全天请假
recordParam.put("cqzt", CheckBoxEnum.UNCHECKED.getKey());
recordParam.put("recordData", askForLeaveDataMap.get("alldayVaction"));
utilService.recordItem(recordParam);
return null;
}
askForLeaveAndEvctionSchedule.addAll((List<Map<String, Object>>) askForLeaveDataMap.get("askForLeaveSchedule"));
//出差记录
Map<String, Object> evectionDataMap = updateAttendanceResultWrapper.getEvection(workingHourparam);
if (evectionDataMap.get("alldayEvection") != null) {
//全天出差
recordParam.put("cqzt", CheckBoxEnum.UNCHECKED.getKey());
recordParam.put("recordData", evectionDataMap.get("alldayEvection"));
utilService.recordItem(recordParam);
return null;
}
askForLeaveAndEvctionSchedule.addAll((List<Map<String, Object>>) evectionDataMap.get("evectionSchedule"));
if (askForLeaveAndEvctionSchedule.size() > 0) {
askForLeaveAndEvctionSchedule = mergeAskForLeaveAndEvctionSchedule(askForLeaveAndEvctionSchedule, analysisDate);
}
Map<String, Object> clcokInTimeDataParam = Maps.newHashMap();
clcokInTimeDataParam.put("analysisDate", analysisDate);
clcokInTimeDataParam.put("scheduleResult", scheduleResult);
clcokInTimeDataParam.put("clockInTimeList", clockInTimeList);
clcokInTimeDataParam.put("askForLeaveAndEvctionSchedule", askForLeaveAndEvctionSchedule);
//打卡卡点以及匹配的打卡时间
List<ClockPointDTO> clcokInTimeData = null;
if (clockInTimeDataMap.get(analysisDate) != null){
clcokInTimeData = (List<ClockPointDTO>)clockInTimeDataMap.get(analysisDate);
}else {
clcokInTimeData = utilService.getClockInPointCmd(clcokInTimeDataParam);
}
Map<String, Object> recordAbnormalParam = Maps.newHashMap();
recordAbnormalParam.put("clcokInTimeData", clcokInTimeData);
recordAbnormalParam.put("attendanceItems", attendanceItems);
recordAbnormalParam.put("scheduleResult", scheduleResult);
recordAbnormalParam.put("analysisDate", analysisDate);
recordAbnormalParam.put("userId", userId);
recordAbnormalParam.put("rqlx", scheduleResult.get(0).get("rqlx"));
recordAbnormalParam.put("formmodeIdMap", formModeIdMap);
/**
* 计算是否考勤异常,是否有早退、迟到、漏卡的情况
*
**/
recordAbnormalParam.put("askForLeaveList", askForLeaveDataMap.get("askForLeaveList"));
recordAbnormalParam.put("askForLeaveItems", askForLeaveDataMap.get("askForLeaveItems"));
recordAbnormalParam.put("evectionList", evectionDataMap.get("evectionList"));
recordAbnormalParam.put("evectionItems", evectionDataMap.get("evectionItems"));
List<Map<String, Object>> abnormalClockInList = updateAttendanceResultWrapper.recordAbnormalClockIn(recordAbnormalParam);
//需要记录的异常卡点
List<Map<String, Object>> needRecordAbnormalClockInList = abnormalClockInList.stream().filter(e -> (boolean) e.get("record")).collect(Collectors.toList());
//不需要记录的异常卡点
List<Map<String, Object>> notRecordAbnormalClockInList = abnormalClockInList.stream().filter(e -> !(boolean) e.get("record")).collect(Collectors.toList());
/**
* 出勤津贴
*/
recordAbnormalParam.put("abnormalClockInList", needRecordAbnormalClockInList);
recordAbnormalParam.put("notRecordAbnormalClockInList", notRecordAbnormalClockInList);
String ifnotWork = Util.null2String(allowanceMap.get("ifnotWork"));
if (!"".equals(ifnotWork)) {
//次日免班
recordParam.put("recordData", Lists.newArrayList());
recordParam.put("recordDataTime", Maps.newHashMap());
recordParam.put("attendanceDuration", scheduleResult.get(0).get("edsc").toString());
recordParam.put("cqzt", CheckBoxEnum.UNCHECKED.getKey());
utilService.recordItem(recordParam);
return null;
}
if (!"".equals(Util.null2String(allowanceMap.get("delayMinute")))) {
recordAbnormalParam.put("delayMinute", allowanceMap.get("delayMinute"));
updateAttendanceResultWrapper.removeAbnormal(recordAbnormalParam);
}
/**
* 请假
*/
Map<String, Object> vactionMap = updateAttendanceResultWrapper.recordAskForLeave(recordAbnormalParam);
List<Map<String, Object>> abnormalClockInListByAskForLeave = (List<Map<String, Object>>) vactionMap.get("abnormalClockInList");
List<Map<String, Object>> vactionList = (List<Map<String, Object>>) vactionMap.get("resultList");
recordAbnormalParam.put("offsetAskForLeaveAnomaly", vactionMap.get("offsetAskForLeaveAnomaly"));
log.debug("请假后消除的异常 : [{}]", vactionMap.get("offsetAskForLeaveAnomaly"));
/**
* 出差、外出
*/
recordAbnormalParam.put("abnormalClockInList", abnormalClockInListByAskForLeave);
Map<String, Object> recordEvection = updateAttendanceResultWrapper.recordEvection(recordAbnormalParam);
List<Map<String, Object>> abnormalClockInListByEvction = (List<Map<String, Object>>) recordEvection.get("abnormalClockInList");
List<Map<String, Object>> evectionResultList = (List<Map<String, Object>>) recordEvection.get("resultList");
recordAbnormalParam.put("abnormalClockInList", abnormalClockInListByEvction);
recordAbnormalParam.put("offsetEvectionAnomaly", recordEvection.get("offsetEvectionAnomaly"));
log.debug("出差外出后消除的异常 : [{}]", recordEvection.get("offsetEvectionAnomaly"));
/**
* 加班
*/
List<Map<String, Object>> recordWorkOverTime = updateAttendanceResultWrapper.recordWorkOverTime(recordAbnormalParam);
/**
* 计算出勤时长
*/
double attendanceDuration = utilService.computeAttendanceDuration(recordAbnormalParam);
/**
* 入库
*/
List<Map<String, Object>> recordData = Lists.newArrayList();
recordData.addAll(vactionList);
recordData.addAll(evectionResultList);
abnormalClockInListByEvction = abnormalClockInListByEvction.stream().filter(e -> (boolean) e.get("record")).collect(Collectors.toList());
recordData.addAll(abnormalClockInListByEvction);
recordData.addAll(recordWorkOverTime);
recordParam.put("recordData", recordData);
recordParam.put("recordDataTime", utilService.getNeedRecordClockInTime(clcokInTimeData));
recordParam.put("attendanceDuration", attendanceDuration);
log.info("recordParam : {}", recordParam);
if (abnormalClockInListByEvction.size() > 0) {
recordParam.put("cqzt", CheckBoxEnum.CHECKED.getKey());
} else {
recordParam.put("cqzt", CheckBoxEnum.UNCHECKED.getKey());
}
//休息班次,休息班打卡自动加班不算自动加班,且为正常
if (scheduleResult.get(0).get("sfxx") != null && CheckBoxEnum.CHECKED.getKey().equals(scheduleResult.get(0).get("sfxx"))) {
recordParam.put("sfxx", CheckBoxEnum.CHECKED.getKey());
recordParam.put("cqzt", CheckBoxEnum.UNCHECKED.getKey());
recordParam.put("attendanceDuration", 0);
}
utilService.recordItem(recordParam);
return (Map<String, Object>) recordParam.get("recordDataTime");
}
/**
* 合并请假或出差
*
* @param askForLeaveAndEvctionSchedule
* @param analysisDate
* @return
*/
public List<Map<String, Object>> mergeAskForLeaveAndEvctionSchedule(List<Map<String, Object>> askForLeaveAndEvctionSchedule, String analysisDate) {
askForLeaveAndEvctionSchedule = askForLeaveAndEvctionSchedule.stream().sorted(Comparator.comparing(e -> DateUtil.getTime(Utils.getkssjTime(e, analysisDate)).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
for (int i = 0; i < askForLeaveAndEvctionSchedule.size() - 1; i++) {
String beforeDtkssj = askForLeaveAndEvctionSchedule.get(i).get("dtkssj").toString();
String beforeDtjssj = askForLeaveAndEvctionSchedule.get(i).get("dtjssj").toString();
for (int j = i + 1; j < askForLeaveAndEvctionSchedule.size(); j++) {
String dtkssj = askForLeaveAndEvctionSchedule.get(j).get("dtkssj").toString();
String dtjssj = askForLeaveAndEvctionSchedule.get(j).get("dtjssj").toString();
if (beforeDtjssj.equals(dtkssj)) {
askForLeaveAndEvctionSchedule.get(i).put("dtjssj", dtjssj);
askForLeaveAndEvctionSchedule.get(i).put("jsdk", askForLeaveAndEvctionSchedule.get(j).get("jsdk"));
askForLeaveAndEvctionSchedule.get(i).put("thfghlfzs", askForLeaveAndEvctionSchedule.get(j).get("thfghlfzs"));
askForLeaveAndEvctionSchedule.remove(askForLeaveAndEvctionSchedule.get(j));
j--;
i--;
}
}
}
return askForLeaveAndEvctionSchedule;
}
}