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.
353 lines
17 KiB
Java
353 lines
17 KiB
Java
package com.engine.attendance.attendanceanalysis.cmd.workovertime;
|
|
|
|
import com.engine.attendance.enums.*;
|
|
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 weaver.general.Util;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* 根据加班时间计算获得加班时长
|
|
*/
|
|
@Slf4j
|
|
public class GetOvertimeDurationCmd extends AbstractCommonCommand<Map<String, Object>> {
|
|
public GetOvertimeDurationCmd(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<Map<String,Object>> attendanceItems = (List<Map<String,Object>>)params.get("attendanceItems");
|
|
//排班
|
|
List<Map<String, Object>> scheduleResult = (List<Map<String,Object>>)params.get("scheduleResult");
|
|
//分析日期
|
|
String analysisDate = Util.null2String(params.get("analysisDate"));
|
|
//请假记录
|
|
List<Map<String,Object>> askForLeaveList = (List<Map<String,Object>>)params.get("askForLeaveList");
|
|
//请假项目
|
|
Map<String,Map<String,Object>> askForLeaveItems = (Map<String,Map<String,Object>>)params.get("askForLeaveItems");
|
|
//外出记录
|
|
List<Map<String,Object>> evectionList = (List<Map<String,Object>>)params.get("evectionList");
|
|
//外出项目
|
|
Map<String,Map<String,Object>> evectionItems = (Map<String,Map<String,Object>>)params.get("evectionItems");
|
|
//请假后消除的异常
|
|
List<Map<String,Object>> offsetAskForLeaveAnomaly = (List<Map<String,Object>>)params.get("offsetAskForLeaveAnomaly");
|
|
//出差外出后消除的异常
|
|
List<Map<String,Object>> offsetEvectionAnomaly = (List<Map<String,Object>>)params.get("offsetEvectionAnomaly");
|
|
//经过请假外出处理过的异常项目
|
|
List<Map<String,Object>> abnormalClockInList = (List<Map<String,Object>>)params.get("abnormalClockInList");
|
|
//不需要记录的异常项目
|
|
List<Map<String,Object>> notRecordAbnormalClockInList = (List<Map<String,Object>>)params.get("notRecordAbnormalClockInList");
|
|
//加班项目
|
|
List<Map<String, Object>> workTimeBeLateItems = (List<Map<String,Object>>)params.get("workTimeBeLateItems");
|
|
//打卡匹配
|
|
Map<String,Map<String,Object>> clcokInTimeMap = (Map<String,Map<String,Object>>)params.get("clcokInTimeMap");
|
|
//班次
|
|
Map<String, Object> scheduleMap = (Map<String, Object>)params.get("scheduleMap");
|
|
|
|
|
|
abnormalClockInList.addAll(notRecordAbnormalClockInList);
|
|
|
|
//总抵消异常
|
|
List<Map<String,Object>> anomalyList = Lists.newArrayList();
|
|
anomalyList.addAll(offsetEvectionAnomaly);
|
|
anomalyList.addAll(offsetAskForLeaveAnomaly);
|
|
|
|
|
|
String bdlx = Util.null2String(scheduleMap.get("bdlx"));
|
|
Map<String, Object> getWorkOverTimeParam = Maps.newHashMap();
|
|
//加班开始时间
|
|
String kssj = Utils.getkssjTime(scheduleMap, analysisDate);
|
|
//加班结束时间
|
|
String jssj = Utils.getjssjTime(scheduleMap, analysisDate);
|
|
|
|
//加班实际开始时间
|
|
String realityStartTime = "";
|
|
//加班实际结束时间
|
|
String realityEndime = "";
|
|
|
|
|
|
getWorkOverTimeParam.put("attendanceItems", attendanceItems);
|
|
getWorkOverTimeParam.put("rqlx", scheduleMap.get("rqlx"));
|
|
|
|
//开始必须打卡,当为加班计划类型的加班时已考勤项目设置为准
|
|
String ksjbbxydk = scheduleMap.get("ksdk").toString();
|
|
//结束必须打卡,当为加班计划类型的加班时已考勤项目设置为准
|
|
String jsjbbxydk = scheduleMap.get("jsdk").toString();
|
|
|
|
|
|
double jbsc = Double.valueOf(Util.null2String(scheduleMap.get("edxss")));
|
|
|
|
//提前打卡开始的时长计入加班
|
|
String tqdkjrjb = Util.null2String(workTimeBeLateItems.get(0).get("tqdkjrjb"));
|
|
//推后打卡结束的时长计入加班
|
|
String thdkjrjb = Util.null2String(workTimeBeLateItems.get(0).get("thdkjrjb"));
|
|
//结算加班时长不得超过申请的时长
|
|
String jbscbdccsqsc = Util.null2String(workTimeBeLateItems.get(0).get("jbscbdccsqsc"));
|
|
//是否扣除时间区间内的就餐休息时长
|
|
String zdkcjcxxsc = Util.null2String(workTimeBeLateItems.get(0).get("zdkcjcxxsc"));
|
|
//晚于开始时间忽略分钟数
|
|
String jbwdhlfzs = Util.null2String(workTimeBeLateItems.get(0).get("jbwdhlfzs")).equals("") ? "0" : Util.null2String(workTimeBeLateItems.get(0).get("jbwdhlfzs"));
|
|
//早于结束时间忽略分钟数
|
|
String jbzzhlfzs = Util.null2String(workTimeBeLateItems.get(0).get("jbzzhlfzs")).equals("") ? "0" : Util.null2String(workTimeBeLateItems.get(0).get("jbzzhlfzs"));
|
|
|
|
/**
|
|
* 获得实际加班时间
|
|
*/
|
|
if (CheckBoxEnum.CHECKED.getKey().equals(ksjbbxydk)) {
|
|
Map<String, Object> clcokInTimeData = clcokInTimeMap.get(kssj);
|
|
if (clcokInTimeData == null) {
|
|
log.debug("加班开始时间漏卡: {},clcokInTimeData:{}", kssj, clcokInTimeMap);
|
|
resultMap.put("jbsc","0");
|
|
return resultMap;
|
|
}
|
|
String hourTime = clcokInTimeData.get("signtime").toString();
|
|
if (hourTime.length() > 5) {
|
|
hourTime = hourTime.substring(0, 5);
|
|
}
|
|
String signTime = clcokInTimeData.get("signdate") + " " + hourTime;
|
|
realityStartTime = signTime;
|
|
} else {
|
|
realityStartTime = kssj;
|
|
}
|
|
if (CheckBoxEnum.CHECKED.getKey().equals(jsjbbxydk)) {
|
|
Map<String, Object> clcokInTimeData = clcokInTimeMap.get(jssj);
|
|
if (clcokInTimeData == null) {
|
|
log.debug("加班结束时间漏卡: {},clcokInTimeData:{}", jssj, clcokInTimeData);
|
|
resultMap.put("jbsc","0");
|
|
return resultMap;
|
|
}
|
|
String hourTime = clcokInTimeData.get("signtime").toString();
|
|
if (hourTime.length() > 5) {
|
|
hourTime = hourTime.substring(0, 5);
|
|
}
|
|
String signTime = clcokInTimeData.get("signdate") + " " + hourTime;
|
|
realityEndime = signTime;
|
|
} else {
|
|
realityEndime = jssj;
|
|
}
|
|
jbsc = jbsc * 60;
|
|
if (CheckBoxEnum.CHECKED.getKey().equals(tqdkjrjb)) {
|
|
//提前打卡开始的时长计入加班
|
|
if (DateUtil.getTime(realityStartTime).compareTo(DateUtil.getTime(kssj)) < 0) {
|
|
jbsc += DateUtil.getBetWeenMinutes(realityStartTime, kssj);
|
|
}
|
|
}
|
|
if (CheckBoxEnum.CHECKED.getKey().equals(thdkjrjb)) {
|
|
// 推后打卡结束的时长计入加班
|
|
if (DateUtil.getTime(realityEndime).compareTo(DateUtil.getTime(jssj)) > 0) {
|
|
jbsc += DateUtil.getBetWeenMinutes(jssj, realityEndime);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 当存在迟到项目时扣除异常时长,不存在时扣除实际迟到时间
|
|
*/
|
|
List<Map<String, Object>> beLateAbnormal = abnormalClockInList.stream().filter(e -> e.get("pointTime").equals(kssj)).collect(Collectors.toList());
|
|
double beLateTime = 0;
|
|
if (beLateAbnormal.size() > 0) {
|
|
String hsdw = Util.null2String(beLateAbnormal.get(0).get("hsdw"));
|
|
String itemduration = Util.null2String(beLateAbnormal.get(0).get("itemduration"));
|
|
AttendanceItemTypeEnum itemType = (AttendanceItemTypeEnum) beLateAbnormal.get(0).get("itemType");
|
|
if (itemType == AttendanceItemTypeEnum.MISSE_CARD) {
|
|
//早上漏卡
|
|
beLateTime = jbsc;
|
|
} else {
|
|
if (AccountingUnitEnum.DAY.getKey().equals(hsdw)) {
|
|
beLateTime = Integer.valueOf(scheduleMap.get("edsc").toString()) * Double.valueOf(itemduration);
|
|
} else if (AccountingUnitEnum.HOUR.getKey().equals(hsdw)) {
|
|
beLateTime = Double.valueOf(itemduration) * 60;
|
|
} else if (AccountingUnitEnum.MINUTES.getKey().equals(hsdw)) {
|
|
beLateTime = Double.valueOf(itemduration);
|
|
} else if (AccountingUnitEnum.ONCE.getKey().equals(hsdw)) {
|
|
beLateTime = jbsc;
|
|
}
|
|
}
|
|
} else {
|
|
if (DateUtil.getTime(realityStartTime).compareTo(DateUtil.getTime(kssj)) > 0) {
|
|
beLateTime = DateUtil.getBetWeenMinutes(kssj, realityStartTime);
|
|
List<Map<String, Object>> collect1 = anomalyList.stream().filter(e -> e.get("pointTime").equals(kssj)).collect(Collectors.toList());
|
|
|
|
if (!"".equals(jbwdhlfzs) && beLateTime < Integer.valueOf(jbwdhlfzs)) {
|
|
beLateTime = 0;
|
|
}
|
|
//当存在迟到异常被抵消的情况
|
|
if (collect1.size() > 0) {
|
|
beLateTime = 0;
|
|
}
|
|
|
|
}
|
|
}
|
|
/**
|
|
* 当存在早退项目时扣除异常时长,不存在时扣除实际早退时间
|
|
*/
|
|
List<Map<String, Object>> leaveEarlyAbnormal = abnormalClockInList.stream().filter(e -> e.get("pointTime").equals(jssj)).collect(Collectors.toList());
|
|
double leaveElaryTime = 0;
|
|
if (leaveEarlyAbnormal.size() > 0) {
|
|
String hsdw = Util.null2String(leaveEarlyAbnormal.get(0).get("hsdw"));
|
|
String itemduration = Util.null2String(leaveEarlyAbnormal.get(0).get("itemduration"));
|
|
AttendanceItemTypeEnum itemType = (AttendanceItemTypeEnum) leaveEarlyAbnormal.get(0).get("itemType");
|
|
if (itemType == AttendanceItemTypeEnum.MISSE_CARD) {
|
|
//下午漏卡
|
|
leaveElaryTime = jbsc;
|
|
|
|
} else {
|
|
if (AccountingUnitEnum.DAY.getKey().equals(hsdw)) {
|
|
leaveElaryTime = Integer.valueOf(scheduleMap.get("edsc").toString()) * Double.valueOf(itemduration);
|
|
} else if (AccountingUnitEnum.HOUR.getKey().equals(hsdw)) {
|
|
leaveElaryTime = Double.valueOf(itemduration) * 60;
|
|
} else if (AccountingUnitEnum.MINUTES.getKey().equals(hsdw)) {
|
|
leaveElaryTime = Double.valueOf(itemduration);
|
|
} else if (AccountingUnitEnum.ONCE.getKey().equals(hsdw)) {
|
|
leaveElaryTime = jbsc;
|
|
}
|
|
}
|
|
} else {
|
|
if (DateUtil.getTime(realityEndime).compareTo(DateUtil.getTime(jssj)) < 0) {
|
|
leaveElaryTime = DateUtil.getBetWeenMinutes(realityEndime, jssj);
|
|
List<Map<String, Object>> collect2 = anomalyList.stream().filter(e -> e.get("pointTime").equals(jssj)).collect(Collectors.toList());
|
|
if (!"".equals(jbzzhlfzs) && leaveElaryTime < Integer.valueOf(jbzzhlfzs)) {
|
|
leaveElaryTime = 0;
|
|
}
|
|
//当存在早退异常被抵消的情况
|
|
if (collect2.size() > 0) {
|
|
leaveElaryTime = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* 当存在请假时,考虑扣除请假时长
|
|
*/
|
|
int askForLeaveTime = removeAskForLeave(realityStartTime, realityEndime, Util.null2String(getWorkOverTimeParam.get("workfor"))
|
|
, bdlx, askForLeaveList, askForLeaveItems, offsetAskForLeaveAnomaly);
|
|
|
|
/**
|
|
* 当存在外出时,考虑扣除外出时长
|
|
*/
|
|
int evectionTime = removeEvection(realityStartTime, realityEndime, Util.null2String(getWorkOverTimeParam.get("workfor"))
|
|
, bdlx, evectionList, evectionItems, offsetEvectionAnomaly);
|
|
|
|
/**
|
|
* 加班时段所包含的就餐时段
|
|
*/
|
|
int dinnerTime = Utils.dinnerTime(realityStartTime, realityEndime, scheduleResult, analysisDate);
|
|
|
|
log.debug("未扣减过的加班时长: {}", jbsc);
|
|
log.debug("beLateTime :[{}],leaveElaryTime :[{}],askForLeaveTime:[{}],evectionTime:[{}],dinnerTime:[{}]", beLateTime, leaveElaryTime, askForLeaveTime, evectionTime, dinnerTime);
|
|
BigDecimal jbscbig = new BigDecimal(jbsc);
|
|
if (CheckBoxEnum.CHECKED.getKey().equals(zdkcjcxxsc)){
|
|
//扣除就餐时长
|
|
jbsc = jbscbig.subtract(new BigDecimal(beLateTime)).subtract(new BigDecimal(leaveElaryTime)).subtract(new BigDecimal(askForLeaveTime)).subtract(new BigDecimal(evectionTime)).subtract(new BigDecimal(dinnerTime)).intValue();
|
|
}else {
|
|
jbsc = jbscbig.subtract(new BigDecimal(beLateTime)).subtract(new BigDecimal(leaveElaryTime)).subtract(new BigDecimal(askForLeaveTime)).subtract(new BigDecimal(evectionTime)).intValue();
|
|
}
|
|
if (CheckBoxEnum.CHECKED.getKey().equals(jbscbdccsqsc)) {
|
|
if (jbsc > Double.valueOf(Util.null2String(scheduleMap.get("edxss"))) * 60) {
|
|
jbsc = Double.valueOf(Util.null2String(scheduleMap.get("edxss"))) * 60;
|
|
}
|
|
}
|
|
log.debug("扣减过的加班时长 :[{}]", jbsc);
|
|
resultMap.put("jbsc",jbsc);
|
|
resultMap.put("realityStartTime",realityStartTime);
|
|
resultMap.put("realityEndime",realityEndime);
|
|
|
|
return resultMap;
|
|
}
|
|
|
|
/**
|
|
* 请假影响加班时长
|
|
* @param kssj 加班开始时间
|
|
* @param jssj 加班结束时间
|
|
* @param workFor 作用时段
|
|
* @param askForLeaveList 请假集合
|
|
* @param askForLeaveItems 请假项目
|
|
* @return 请假在加班中所占时间
|
|
*/
|
|
public int removeAskForLeave(String kssj,String jssj,String workFor,String bdlx,List<Map<String, Object>> askForLeaveList,
|
|
Map<String,Map<String,Object>> askForLeaveItems,List<Map<String, Object>> offsetAskForLeaveAnomaly ){
|
|
int employTime = 0;
|
|
for (int i=0;i<askForLeaveList.size();i++){
|
|
//请假时长
|
|
String qjsc = Util.null2String(askForLeaveList.get(i).get("qjsc"));
|
|
//请假项目
|
|
Map<String,Object> askForLeaveItem = askForLeaveItems.get(askForLeaveList.get(i).get("jqlx"));
|
|
//作用时段
|
|
String zysd = Util.null2String(askForLeaveItem.get("zysd"));
|
|
// if (!zysd.contains(workFor) && !zysd.contains(WorkForTimeEnum.ALL_TIME.getKey())){
|
|
// continue;
|
|
// }
|
|
if ("".equals(Util.null2String(askForLeaveList.get(i).get("kssj"))) || "".equals(Util.null2String(askForLeaveList.get(i).get("jssj")))){
|
|
if (!"".equals(qjsc)){
|
|
//时长请假
|
|
if (offsetAskForLeaveAnomaly.size() > 0){
|
|
List<Map<String, Object>> list = offsetAskForLeaveAnomaly.stream().filter(e->bdlx.equals(e.get("bdlx"))).collect(Collectors.toList());
|
|
employTime += Math.round(list.size()/Double.valueOf(offsetAskForLeaveAnomaly.size()) *Double.valueOf(qjsc)*60);
|
|
}
|
|
}
|
|
}else {
|
|
//按照开始时间,结束时间请假
|
|
employTime +=Utils.getStartAndEndTime(kssj,jssj,askForLeaveList.get(i));
|
|
}
|
|
}
|
|
return employTime;
|
|
}
|
|
|
|
/**
|
|
* 外出影响加班时长
|
|
* @param kssj 加班开始时间
|
|
* @param jssj 加班结束时间
|
|
* @param evectionList 外出、请假集合
|
|
* @return
|
|
*/
|
|
public int removeEvection(String kssj,String jssj,String workFor,String bdlx,List<Map<String, Object>> evectionList,Map<String,
|
|
Map<String,Object>> evectionItems,List<Map<String, Object>> offsetEvectionAnomaly){
|
|
int askForLeaveTime=0;
|
|
for (int i=0;i<evectionList.size();i++){
|
|
//出差时长
|
|
String qjsc = Util.null2String(evectionList.get(i).get("ccsc"));
|
|
//出差项目
|
|
Map<String,Object> evectionItem = evectionItems.get(evectionList.get(i).get("cclx"));
|
|
//作用时段
|
|
String zysd = Util.null2String(evectionItem.get("zysd"));
|
|
// if (!zysd.contains(workFor) && !WorkForTimeEnum.ALL_TIME.getKey().equals(zysd)){
|
|
// continue;
|
|
// }
|
|
|
|
if ("".equals(Util.null2String(evectionList.get(i).get("kssj"))) || "".equals(Util.null2String(evectionList.get(i).get("jssj")))){
|
|
if (!"".equals(qjsc)){
|
|
if (offsetEvectionAnomaly.size() > 0){
|
|
List<Map<String, Object>> list = offsetEvectionAnomaly.stream().filter(e->bdlx.equals(e.get("bdlx"))).collect(Collectors.toList());
|
|
askForLeaveTime += Math.round(list.size()/Double.valueOf(offsetEvectionAnomaly.size()) *Double.valueOf(qjsc)*60);
|
|
}
|
|
}
|
|
}else {
|
|
//按照开始时间,结束时间请假
|
|
askForLeaveTime +=Utils.getStartAndEndTime(kssj,jssj,evectionList.get(i));
|
|
}
|
|
}
|
|
return askForLeaveTime;
|
|
}
|
|
|
|
|
|
}
|