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.

367 lines
17 KiB
Java

package com.engine.attendance.attendanceanalysis.service.impl;
import com.engine.attendance.attendanceanalysis.cmd.item.AbsenteeismItemCmd;
import com.engine.attendance.attendanceanalysis.cmd.item.BeLateItemCmd;
import com.engine.attendance.attendanceanalysis.cmd.item.LeaveEarlyItemCmd;
import com.engine.attendance.attendanceanalysis.service.ComprehensiveWorkingHourService;
import com.engine.attendance.attendanceanalysis.service.UtilService;
import com.engine.attendance.enums.AccountingUnitEnum;
import com.engine.attendance.enums.CheckBoxEnum;
import com.engine.attendance.enums.SystemItemEnum;
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 com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.ZoneOffset;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
public class ComprehensiveWorkingHourServiceImpl extends Service implements ComprehensiveWorkingHourService {
private UtilService utilService = ServiceUtil.getService(UtilServiceImpl.class);
@Override
public Map<String, Object> excuteByWorkHour(Map<String, Object> param) {
Map<String, Object> resultMap = Maps.newHashMap();
//按照日期分割的打卡时间
List<Map<String,Object>> clockInTimeList = (List<Map<String,Object>>) param.get("clockInTimeCollect");
//分析日期
String analysisDate = Util.null2String(param.get("analysisDate"));
//人员
String userId = Util.null2String(param.get("userId"));
//考勤项目
List<Map<String,Object>> attendanceItems = (List<Map<String,Object>>)param.get("attendanceItems");
//综合工时
Map<String,Object> workHourItem = (Map<String,Object>)param.get("workHourItem");
//日工作时长不足,核算异常
String rgzscbzhsyc= Util.null2String(workHourItem.get("rgzscbzhsyc"));
//日最晚打卡报到时间
String rzwdkbdsj = Util.null2String(workHourItem.get("rzwdkbdsj"));
//日工作时长要求
double rgzscyq = Double.valueOf(Util.null2String(workHourItem.get("rgzscyq")));
//累计出勤时长的核算分钟数
int ljcqscdhsfzs = Integer.valueOf(Util.null2String(workHourItem.get("ljcqscdhsfzs")));
//超出日工作时长要求,计入出勤 时长
String ccrgzscyqjrcqsc = Util.null2String(workHourItem.get("ccrgzscyqjrcqsc"));
//日最长工作时长
double rzcgzsc = Double.valueOf(Util.null2String(workHourItem.get("rzcgzsc")));
//核算工时的日期类型
String hsgsdrqlx = Util.null2String(workHourItem.get("hsgsdrqlx"));
String cqzt = "0";
String rqlx = Utils.getDateType(analysisDate,Util.null2String(workHourItem.get("qyrl")));
if (!CommonUtil.ifContainStr(hsgsdrqlx,rqlx,",")){
log.info("userId :[{}],analysisDate :[{}] 综合工时执行的日期不在设置的日期类型内",userId,analysisDate);
resultMap.put("message","综合工时执行的日期不在设置的日期类型内");
return resultMap;
}
//异常项目
List<Map<String, Object>> recordDataList = Lists.newArrayList();
clockInTimeList = getClockInDataByRule(param);
int betweenMinute = getDurationMinute(clockInTimeList);
if (betweenMinute == 0 || clockInTimeList.size()==0){
if (rgzscbzhsyc.equals(CheckBoxEnum.CHECKED.getKey())){
//记漏打卡项目
Map<String, Object> itemMap = Maps.newHashMap();
itemMap.put("item", SystemItemEnum.MISSING_CLOCK_IN.getKey());
itemMap.put("itemduration","1");
recordDataList.add(itemMap);
}
}
double adjustBetWeenMinute = Utils.getItemdurationDown(ljcqscdhsfzs, AccountingUnitEnum.MINUTES.getKey(),betweenMinute,AccountingUnitEnum.MINUTES);
double adjustBetweenHour = new BigDecimal(adjustBetWeenMinute).divide(new BigDecimal(60),2, RoundingMode.HALF_UP).doubleValue();
log.info("betweenMinute : [{}],adjustBetWeenMinute: [{}],betweenHour:[{}]",betweenMinute,adjustBetWeenMinute,adjustBetweenHour);
if (clockInTimeList.size() > 0){
String reportTime = clockInTimeList.get(0).get("signdate")+" "+clockInTimeList.get(0).get("signtime");
int lateDurationTime = 0;
int earlyLeaveMinute = 0;
Map<String,Object> abnormalParams = Maps.newHashMap();
abnormalParams.put("attendanceItems",attendanceItems);
abnormalParams.put("rqlx",rqlx);
if (!"".equals(rzwdkbdsj)){
String lastReportTime = Utils.installTime(analysisDate,rzwdkbdsj);
if (Utils.dateGreaterThan(reportTime,lastReportTime)){
//迟到
lateDurationTime = DateUtil.getBetWeenMinutes(lastReportTime,reportTime);
}
}
if ((betweenMinute+lateDurationTime) < (rgzscyq*60)){
//早退
earlyLeaveMinute = Double.valueOf(rgzscyq*60-(betweenMinute+lateDurationTime)).intValue();
}
log.info("lateDurationTime : [{}],earlyLeaveMinute:[{}]",lateDurationTime,earlyLeaveMinute);
if (rgzscbzhsyc.equals(CheckBoxEnum.CHECKED.getKey())){
if (lateDurationTime > 0){
//计入迟到项目
abnormalParams.put("time",lateDurationTime);
Map<String,Object> result = commandExecutor.execute(new BeLateItemCmd(abnormalParams));
List<Map<String,Object>> workTimeBeLateItems = (List<Map<String,Object>>)result.get("attendanceItems");
if (workTimeBeLateItems.size() == 0){
workTimeBeLateItems = (List<Map<String,Object>>)commandExecutor.execute(new AbsenteeismItemCmd(abnormalParams)).get("attendanceItems");
}
if (workTimeBeLateItems.size() > 0){
double hsl = Double.valueOf(Util.null2String(workTimeBeLateItems.get(0).get("hsl")));
String hsdw = Util.null2String(workTimeBeLateItems.get(0).get("hsdw"));
double itemduration = Utils.getItemduration(hsl,hsdw,lateDurationTime,AccountingUnitEnum.MINUTES);
Map<String, Object> itemMap = Maps.newHashMap();
itemMap.put("item", workTimeBeLateItems.get(0).get("key"));
itemMap.put("itemduration",itemduration);
recordDataList.add(itemMap);
}
}
if (earlyLeaveMinute > 0){
//计早退项目
abnormalParams.put("time",lateDurationTime);
Map<String,Object> result = commandExecutor.execute(new LeaveEarlyItemCmd(abnormalParams));
List<Map<String,Object>> workTimeBeLateItems = (List<Map<String,Object>>)result.get("attendanceItems");
if (workTimeBeLateItems.size() == 0){
workTimeBeLateItems = (List<Map<String,Object>>)commandExecutor.execute(new AbsenteeismItemCmd(abnormalParams)).get("attendanceItems");
}
if (workTimeBeLateItems.size() > 0){
double hsl = Double.valueOf(Util.null2String(workTimeBeLateItems.get(0).get("hsl")));
String hsdw = Util.null2String(workTimeBeLateItems.get(0).get("hsdw"));
double itemduration = Utils.getItemduration(hsl,hsdw,earlyLeaveMinute,AccountingUnitEnum.MINUTES);
Map<String, Object> itemMap = Maps.newHashMap();
itemMap.put("item", workTimeBeLateItems.get(0).get("key"));
itemMap.put("itemduration",itemduration);
recordDataList.add(itemMap);
}
}
}
}
//超出日工作时长要求,计入出勤 时长,否则最大为日工作时长要求
if (CheckBoxEnum.CHECKED.getKey().equals(ccrgzscyqjrcqsc)){
if (adjustBetweenHour > rzcgzsc){
adjustBetweenHour = rzcgzsc;
}
}else {
if (adjustBetweenHour > rgzscyq){
adjustBetweenHour=rgzscyq;
}
}
if (recordDataList.size() > 0){
cqzt="1";
}
Map<String,Object> recordParam = Maps.newHashMap();
recordParam.put("userId",userId);
recordParam.put("analysisDate",analysisDate);
recordParam.put("recordData",recordDataList);
recordParam.put("rqlx",rqlx);
recordParam.put("classInfo",Lists.newArrayList());
recordParam.put("recordDataTime",getRecordDataTime(clockInTimeList));
recordParam.put("attendanceDuration",adjustBetweenHour);
recordParam.put("formmodeIdMap",Utils.getFormmodeIdMap());
recordParam.put("cqzt",cqzt);
resultMap.put("recordParam",recordParam);
utilService.recordItem(recordParam);
return resultMap;
}
/**
* 根据综合工时规则获取打卡时间
* @param param
* @return
*/
public List<Map<String,Object>> getClockInDataByRule(Map<String, Object> param){
//按照日期分割的打卡时间
List<Map<String,Object>> clockInTimeList = (List<Map<String,Object>>) param.get("clockInTimeCollect");
//分析日期
String analysisDate = Util.null2String(param.get("analysisDate"));
//综合工时
Map<String,Object> workHourItem = (Map<String,Object>)param.get("workHourItem");
//最早打卡上班的开始时间
String zzdksbdkssj = Util.null2String(workHourItem.get("zzdksbdkssj"));
//最晚打卡下班的开始时间
String zwdkxbdkssj = Util.null2String(workHourItem.get("zwdkxbdkssj"));
//日工作时长计算规则
String rgzscjsgz = Util.null2String(workHourItem.get("rgzscjsgz"));
//调整上班开始到
String dzsbksd = Util.null2String(workHourItem.get("dzsbksd"));
//误打卡忽略分钟数
int wdkhlfzs = Util.null2String(workHourItem.get("wdkhlfzs")).equals("")?1:Integer.valueOf(Util.null2String(workHourItem.get("wdkhlfzs")));
String startTime = analysisDate+" "+zzdksbdkssj;
String endTime = analysisDate+" "+zwdkxbdkssj;
if ("".equals(zwdkxbdkssj)){
endTime = DateUtil.AfterDay(analysisDate,1)+" "+zzdksbdkssj;
endTime = DateUtil.beforeMinutes(endTime,1);
}
if (DateUtil.getTime(startTime).compareTo(DateUtil.getTime(endTime)) >=0){
endTime = DateUtil.AfterDay(analysisDate,1) +" "+zwdkxbdkssj;
}
String finalEndTime = endTime;
clockInTimeList = clockInTimeList.stream().filter(e -> {
String signdate = Util.null2String(e.get("signdate"));
String signtime = Util.null2String(e.get("signtime"));
String time = signdate +" "+signtime;
return DateUtil.getTime(startTime).compareTo(DateUtil.getTime(time)) <=0 && DateUtil.getTime(finalEndTime).compareTo(DateUtil.getTime(time)) >=0;
}).collect(Collectors.toList());
clockInTimeList = clockInTimeList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("signdate")+" "+e.get("signtime")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
if (clockInTimeList.size() == 0){
return clockInTimeList;
}
List<Map<String,Object>> newClockInTimeList = Lists.newArrayList();
if ("0".equals(rgzscjsgz)){
//最早最晚打卡间隔时长
newClockInTimeList.add(clockInTimeList.get(0));
newClockInTimeList.add(clockInTimeList.get(clockInTimeList.size()-1));
}else if ("1".equals(rgzscjsgz)){
//依次累加成对打卡间隔时长
if (clockInTimeList.size() > 1){
//数据清洗
Set<Map<String,Object>> needRemoveData = Sets.newHashSet();
for (int i=0;i<clockInTimeList.size()-1;i++){
String time1 = clockInTimeList.get(i).get("signdate")+" "+clockInTimeList.get(i).get("signtime");
for (int j=i+1;j<clockInTimeList.size();j++){
String time2 = clockInTimeList.get(j).get("signdate")+" "+clockInTimeList.get(j).get("signtime");
if (DateUtil.getBetWeenMinutes(time1,time2) <wdkhlfzs){
needRemoveData.add(clockInTimeList.get(j));
}
}
}
for (Map<String,Object> map:needRemoveData){
clockInTimeList.remove(map);
}
}
if (clockInTimeList.size() %2 == 1){
clockInTimeList.remove(clockInTimeList.size()-1);
newClockInTimeList = clockInTimeList;
}else {
newClockInTimeList = clockInTimeList;
}
}
if (newClockInTimeList.size() > 0){
String time = newClockInTimeList.get(0).get("signdate")+" "+newClockInTimeList.get(0).get("signtime");
int minute = DateUtil.getTime(time).getMinute();
int hour = DateUtil.getTime(time).getHour();
if ("1".equals(dzsbksd)){
//整点
if (minute > 0){
hour=hour+1;
}
String hourstr = DateUtil.getTimeStr(hour);
newClockInTimeList.get(0).put("signtime",hourstr+":00");
}else if ("2".equals(dzsbksd)){
//半点
String minuteStr = "";
if (minute < 30){
minuteStr = "30";
}else if (minute > 30){
minuteStr = "00";
hour = hour+1;
}
String hourstr = DateUtil.getTimeStr(hour);
newClockInTimeList.get(0).put("signtime",hourstr+":"+minuteStr);
}else if ("3".equals(dzsbksd)){
//15分钟
if (minute%15 > 0){
minute = (minute/15)*15+15;
if (minute == 60){
minute = 0;
hour = hour+1;
}
}
String hourstr = DateUtil.getTimeStr(hour);
String minutestr = DateUtil.getTimeStr(minute);
newClockInTimeList.get(0).put("signtime",hourstr+":"+minutestr);
}
if (newClockInTimeList.size() > 1){
String firstSignDate = newClockInTimeList.get(0).get("signdate")+" "+newClockInTimeList.get(0).get("signtime");
String twoSignDate = newClockInTimeList.get(1).get("signdate")+" "+newClockInTimeList.get(1).get("signtime");
//当调整后第一笔上班时间超过第二比那么去除这2比记录
if (DateUtil.getTime(firstSignDate).compareTo(DateUtil.getTime(twoSignDate)) >=0){
newClockInTimeList.remove(0);
newClockInTimeList.remove(0);
}
}
}
log.info("newClockInTimeList : [{}]",newClockInTimeList);
return newClockInTimeList;
}
/**
* 获得打卡时间两两直接的时间
* @param clockInTimeList 打卡时间
* @return 分钟数
*/
public int getDurationMinute(List<Map<String,Object>> clockInTimeList){
if (clockInTimeList.size() == 0){
return 0;
}
int logarithm = clockInTimeList.size()/2;
int betweenMinute = 0;
for (int i =0;i<logarithm;i++){
int index1 = i*2;
int index2 = index1+1;
String time1 = clockInTimeList.get(index1).get("signdate") +" "+clockInTimeList.get(index1).get("signtime");
String time2 = clockInTimeList.get(index2).get("signdate") +" "+clockInTimeList.get(index2).get("signtime");
betweenMinute += DateUtil.getBetWeenMinutes(time1,time2);
}
log.info("betweenMinute : [{}]",betweenMinute);
return betweenMinute;
}
/**
* 获得进出时间
* @param clockInTimeList
* @return
*/
public Map<String,Object> getRecordDataTime(List<Map<String,Object>> clockInTimeList){
Map<String,Object> resultMap = Maps.newHashMap();
if (clockInTimeList.size() == 0){
return resultMap;
}
int logarithm = clockInTimeList.size()/2;
for (int i =0;i<logarithm;i++){
int index1 = i*2;
int index2 = index1+1;
resultMap.put("j"+(i+1),"'"+clockInTimeList.get(index1).get("signtime")+"'");
resultMap.put("c"+(i+1),"'"+clockInTimeList.get(index2).get("signtime")+"'");
}
log.info("betweenMinute : [{}]",resultMap);
return resultMap;
}
}