From 526607fefd70a5e90f2e71a81ce6fb22561fedad Mon Sep 17 00:00:00 2001 From: chenwei <3291673014@qq.com> Date: Fri, 22 Sep 2023 16:14:38 +0800 Subject: [PATCH] =?UTF-8?q?24=E5=B0=8F=E6=97=B6=E5=88=B6=E7=8F=AD=E6=AC=A1?= =?UTF-8?q?=E5=9C=A8=E8=80=83=E5=8B=A4=E6=95=B0=E6=8D=AE=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...veShiftManagementBaseFormCmdIntercept.java | 10 +- src/com/engine/kq/biz/KQFormatData.java | 1192 +++++++++++++++++ 2 files changed, 1197 insertions(+), 5 deletions(-) create mode 100644 src/com/engine/kq/biz/KQFormatData.java diff --git a/src/com/customization/csxg/SaveShiftManagementBaseFormCmdIntercept.java b/src/com/customization/csxg/SaveShiftManagementBaseFormCmdIntercept.java index fd2c768..a78ad76 100644 --- a/src/com/customization/csxg/SaveShiftManagementBaseFormCmdIntercept.java +++ b/src/com/customization/csxg/SaveShiftManagementBaseFormCmdIntercept.java @@ -59,15 +59,15 @@ public class SaveShiftManagementBaseFormCmdIntercept extends AbstractCommandProx Integer is24HourView = Util.getIntValue(Util.null2String(jsonObj.get("is24HourView"))); basebean.writeLog("is24HourView: " + is24HourView); - String syncIs24Sql = "update kq_ShiftManagement set is24HourView = ? where id = ? ";//同步是否24小时制字段值 + if ( is24HourView ==-1 || is24HourView ==0) {//否 basebean.writeLog("is24HourView do 0 "); - - rs.executeUpdate(syncIs24Sql,0,shifMaId); + String syncIs24NoSql = "update kq_ShiftManagement set is24HourView = ? where id = ? ";//同步是否24小时制字段值 + rs.executeUpdate(syncIs24NoSql,0,shifMaId); } else { basebean.writeLog("is24HourView do 1 "); - - rs.executeUpdate(syncIs24Sql,1,shifMaId); + String syncIs24Sql = "update kq_ShiftManagement set is24HourView = ?,worktime = ? where id = ? ";//同步是否24小时制与worktime字段值 + rs.executeUpdate(syncIs24Sql,1,"1440",shifMaId); } } diff --git a/src/com/engine/kq/biz/KQFormatData.java b/src/com/engine/kq/biz/KQFormatData.java new file mode 100644 index 0000000..08bf7f4 --- /dev/null +++ b/src/com/engine/kq/biz/KQFormatData.java @@ -0,0 +1,1192 @@ +package com.engine.kq.biz; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.engine.kq.biz.chain.shiftinfo.ShiftInfoBean; +import com.engine.kq.entity.KQShiftRuleEntity; +import com.engine.kq.entity.TimeScopeEntity; +import com.engine.kq.entity.WorkTimeEntity; +import com.engine.kq.enums.FlowReportTypeEnum; +import com.engine.kq.log.KQLog; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.googlecode.aviator.AviatorEvaluator; +import com.googlecode.aviator.Expression; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import weaver.common.DateUtil; +import weaver.conn.BatchRecordSet; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.general.InitServer; +import weaver.general.Util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 考勤数据格式化 + */ +public class KQFormatData extends BaseBean { + private String today = DateUtil.getCurrentDate(); + private KQLog kqLog = new KQLog(); + private boolean writeLog = false; + private LinkedHashMap logInfo = new LinkedHashMap<>(); + + /*** + * 该方法不允许直接调用 + * @param userId + * @param kqDate + * @return + */ + public Map formatKqDate(String userId, String kqDate) { + BaseBean basebean = new BaseBean(); + + List> lsParam = new ArrayList<>(); + //非工作日处理 + List nonlsParam = null; + Map resultMap = new HashMap<>(); + BatchRecordSet bRs = new BatchRecordSet(); + com.engine.kq.biz.KQGroupComInfo kqGroupComInfo = new KQGroupComInfo(); + RecordSet rs = new RecordSet(); + String sql = ""; + try { + kqLog.info("formatKqDate in userId=" + userId + "kqDate==" + kqDate); + if (DateUtil.timeInterval(kqDate, today) < 0) {//今天之后的无需处理 + kqLog.info("今天之后的无需处理的数据:resourceid=="+userId+"kqdate=="+kqDate+"today=="+today); + return resultMap; + } + String uuid = UUID.randomUUID().toString(); + com.engine.kq.biz.KQFormatFreeData kqFormatFreeData = new KQFormatFreeData(); + com.engine.kq.biz.KQWorkTime kqWorkTime = new com.engine.kq.biz.KQWorkTime(); + kqWorkTime.setIsFormat(true); + String kqDateNext = DateUtil.addDate(kqDate, 1); + + com.engine.kq.biz.KQFlowDataBiz kqFlowDataBiz = new KQFlowDataBiz.FlowDataParamBuilder().resourceidParam(userId).fromDateParam(kqDate).toDateParam(kqDateNext).build(); + Map workFlowInfo = new HashMap<>();//userid|date--工作流程 + kqFlowDataBiz.getAllFlowData(workFlowInfo,false); + WorkTimeEntity workTime = kqWorkTime.getWorkTime(userId, kqDate); + kqLog.info("userId:"+userId+":kqDate:"+kqDate+":formatKqDate workTime=" + JSONObject.toJSONString(workTime)+"::uuid::"+uuid); + kqLog.info("userId:"+userId+":kqDate:"+kqDate+":formatKqDate workFlowInfo=" + JSONObject.toJSONString(workFlowInfo)+"::uuid::"+uuid); + + if(this.writeLog) { + logInfo.put("userId",userId); + logInfo.put("kqDate",kqDate); + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(16253,weaver.general.ThreadVarLanguage.getLang())+"",workTime); + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(126871,weaver.general.ThreadVarLanguage.getLang())+"",workFlowInfo); + } + + new com.engine.kq.biz.KQFormatBiz().delFormatData(userId, kqDate); + + String excludecount = Util.null2String(kqGroupComInfo.getExcludecount(workTime.getGroupId()));//是否参与考勤报表统计 + if (workTime.getIsExclude()) {//无需考勤人员没有异常状态 + if(!excludecount.equals("1")){ + kqLog.info("无需考勤人员没有异常状态 workTime.getIsExclude()="+workTime.getIsExclude()+"excludecount=="+excludecount); + return resultMap; + } + } + if( Util.null2String(workTime.getGroupId()).length()==0){ + //没有考勤组不需格式化 + return resultMap; + } + if (workTime == null || workTime.getWorkMins() == 0) { + kqLog.info("workTime == null || workTime.getWorkMins() == 0 插入空记录"); + nonlsParam = new ArrayList<>(); + formatNonWork(userId, kqDate,nonlsParam,workTime, workFlowInfo); + + if(!nonlsParam.isEmpty()){ + sql = " insert into kq_format_detail(resourceid,kqdate,groupid,serialnumber,signindate,signintime,signinid,signoutdate,signouttime,signoutid,leaveMins,leaveinfo,evectionMins,outMins)values(?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + rs.executeUpdate(sql, nonlsParam); + + sql = " insert into kq_format_total(resourceid,kqdate,subcompanyid,departmentid,jobtitle,groupid,serialid,workdays," + + " workmins,attendancedays,attendancemins,signdays,signmins,belate,belatemins,gravebelate,gravebelatemins,leaveeearly,leaveearlymins," + + " graveleaveearly,graveleaveearlymins,absenteeism,absenteeismmins,forgotcheck, forgotcheckMins,leaveMins,evectionMins,outMins)" + + " select a.resourceid,kqdate,b.subcompanyid1,b.departmentid,b.jobtitle,groupid,serialid," + + " case when sum(workmins)>0 then 1 end as workdays, sum(workmins) as workmins," + + " 0 as attendancedays, sum(attendanceMins) as attendanceMins," + + " 0 as signdays, sum(signmins) as signmins," + + " sum(case when belatemins> 0 then 1 else 0 end) as belate,sum(belatemins) as belatemins," + + " sum(case when graveBeLateMins> 0 then 1 else 0 end) as graveBeLate,sum(graveBeLateMins) as graveBeLateMins," + + " sum(case when leaveearlymins> 0 then 1 else 0 end) as leaveearly,sum(leaveearlymins) as leaveearlymins," + + " sum(case when graveLeaveEarlyMins> 0 then 1 else 0 end) as graveLeaveEarly,sum(graveLeaveEarlyMins) as graveLeaveEarlyMins," + + " sum(case when absenteeismmins> 0 then 1 else 0 end) as absenteeism,sum(absenteeismmins) as absenteeismmins," + + " sum(case when forgotcheckmins> 0 then 1 else 0 end) as forgotcheck,sum(forgotcheckmins) as forgotcheckmins, " + + " sum(leaveMins) as leaveMins, sum(evectionMins) as evectionMins, sum(outMins) as outMins" + + " from kq_format_detail a, hrmresource b" + + " where a.resourceid = b.id and resourceid =? and kqdate=?" + + " group by resourceid,kqdate,b.subcompanyid1,b.departmentid,b.jobtitle,groupid,serialid,workmins"; + rs.executeUpdate(sql, userId, kqDate); + } + }else{ + Map definedFieldInfo = new com.engine.kq.biz.KQFormatBiz().getDefinedField(); + String definedField = ""; + String definedParam = ""; + String definedParamSum = ""; + if (workTime.getKQType().equals("3")) {//自由工时 + lsParam.addAll(kqFormatFreeData.format(userId, kqDate, workFlowInfo)); + } else { + definedField = Util.null2String(definedFieldInfo.get("definedField")); + definedParam = Util.null2String(definedFieldInfo.get("definedParam")); + definedParamSum = Util.null2String(definedFieldInfo.get("definedParamSum")); + lsParam.addAll(format(userId, kqDate, workTime, workFlowInfo,uuid)); + } + + if (lsParam.size() > 0) { + sql = " insert into kq_format_detail( " + + " resourceid,kqdate,groupid,serialid,serialnumber,workbegindate,workbegintime,workenddate,workendtime,workmins," + + " signindate,signintime,signinid,signoutdate,signouttime,signoutid,signMins," + + " attendanceMins,belatemins,graveBeLateMins,leaveearlymins,graveLeaveEarlyMins,absenteeismmins,forgotcheckMins," + + " leaveMins,leaveinfo,evectionMins,outMins,forgotbeginworkcheckmins,otherinfo"+(definedField.length()>0?","+definedField+"":"")+") " + + " values(?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?"+(definedField.length()>0?","+definedParam+"":"")+")"; + + basebean.writeLog("insert into kq_format_detail: " + sql); + + for (int i = 0; i < lsParam.size(); i++) { + List param = lsParam.get(i); + basebean.writeLog("insert into kq_format_detail param: " + param); + boolean isok = rs.executeUpdate(sql, param); + kqLog.info("插入记录:userId:"+userId+":kqDate:"+kqDate+":param:"+JSON.toJSONString(param)+":isok:"+isok+"::uuid::"+uuid); + } + + sql = " insert into kq_format_total(resourceid,kqdate,subcompanyid,departmentid,jobtitle,groupid,serialid,workdays,workmins," + + " attendancedays,attendancemins,signdays,signmins,belate,belatemins,gravebelate,gravebelatemins,leaveeearly,leaveearlymins,graveleaveearly," + + " graveleaveearlymins,absenteeism,absenteeismmins,forgotcheck,forgotcheckmins," + + " leaveMins,evectionMins,outMins,forgotbeginworkcheck,forgotbeginworkcheckmins"+(definedField.length()>0?","+definedField+"":"")+") " + + " select a.resourceid,kqdate,b.subcompanyid1,b.departmentid,b.jobtitle,groupid,serialid," + + " case when sum(workmins)>0 then 1 end as workdays, sum(workmins) as workmins," + + " cast(sum(attendanceMins)AS decimal(10, 2))/sum(workmins) as attendancedays, sum(attendanceMins) as attendanceMins," + + " cast(sum(signmins)AS decimal(10, 2))/sum(workmins) as signdays, sum(signmins) as signmins," + + " sum(case when belatemins> 0 then 1 else 0 end) as belate,sum(belatemins) as belatemins," + + " sum(case when graveBeLateMins> 0 then 1 else 0 end) as graveBeLate,sum(graveBeLateMins) as graveBeLateMins," + + " sum(case when leaveearlymins> 0 then 1 else 0 end) as leaveearly,sum(leaveearlymins) as leaveearlymins," + + " sum(case when graveLeaveEarlyMins> 0 then 1 else 0 end) as graveLeaveEarly,sum(graveLeaveEarlyMins) as graveLeaveEarlyMins, " + + " sum(case when absenteeismmins> 0 then 1 else 0 end) as absenteeism,sum(absenteeismmins) as absenteeismmins," + + " sum(case when forgotcheckmins> 0 then 1 else 0 end) as forgotcheck,sum(forgotcheckmins) as forgotcheckmins,sum(leaveMins) as leaveMins," + + " sum(evectionMins) as evectionMins,sum(outMins) as outMins, " + + " sum(case when forgotbeginworkcheckmins> 0 then 1 else 0 end) as forgotbeginworkcheck,sum(forgotbeginworkcheckmins) as forgotbeginworkcheckmins " + + (definedField.length()>0?","+definedParamSum+"":"")+ + " from kq_format_detail a, hrmresource b" + + " where a.resourceid = b.id and resourceid = ? and kqdate=?" + + " group by resourceid,kqdate,b.subcompanyid1,b.departmentid,b.jobtitle,groupid,serialid"; + rs.executeUpdate(sql, userId, kqDate); + + //考勤二开--24小时制班次修改考勤报表的旷工次数列 + //start + recalculationTimes(userId,kqDate); + //end + } + } + }catch (Exception e) { + writeLog(e); + kqLog.info(e); + } + return resultMap; + } + + /** + * 考勤二开--24小时制班次对考勤汇总报表的旷工次数列的影响 + * 逻辑说明:多工作时间段的24小时制班次,由于客户需求,将第一次打卡和最后一次打卡算旷工次数,中间的打卡不算 + * @param userId + * @param kqDate + * @return + */ + public boolean recalculationTimes(String userId,String kqDate){ + + boolean result = false; + + RecordSet rs = new RecordSet(); + RecordSet rsS = new RecordSet(); + + //获取当前考勤汇总报表的数据--旷工次数 + String acqKqDatasSql = "select absenteeism,serialid from kq_format_total where resourceid = ? and kqdate =?"; + rs.executeQuery(acqKqDatasSql,userId,kqDate); + while (rs.next()) { + Integer absenteeism = Util.getIntValue(Util.null2String(rs.getString("absenteeism"))); + Integer serialid = Util.getIntValue(Util.null2String(rs.getString("serialid"))); + if (absenteeism > 1) { + //判断是否为24小时制班次 + Integer is24HourView = -1; + String judSerSql = "select is24HourView from kq_ShiftManagement where id = ? "; + rsS.executeQuery(judSerSql,serialid); + while (rsS.next()) { + is24HourView = Util.getIntValue(Util.null2String("is24HourView")); + } + if ( is24HourView == -1) {//是24小时制班次 + absenteeism = 1 ; + String modifySql = " update kq_format_total set absenteeism = ? where resourceid = ? and kqdate = ?"; + result = rs.executeUpdate(modifySql, absenteeism, userId, kqDate); + } + } + } + + return result; + } + + + + + public List> format(String userId, String kqDate, WorkTimeEntity workTime, + Map workFlowInfo, String uuid) { + List> lsParam = new ArrayList<>(); + List params = null; + try { + com.engine.kq.biz.KQSettingsComInfo kqSettingsComInfo = new KQSettingsComInfo(); + String nosign_is_absent = Util.null2String(kqSettingsComInfo.getMain_val("nosign_is_absent"),"1"); + com.engine.kq.biz.KQTimesArrayComInfo kqTimesArrayComInfo = new com.engine.kq.biz.KQTimesArrayComInfo(); + com.engine.kq.biz.KQFormatShiftRule kqFormatShiftRule = new KQFormatShiftRule(); + String preDate = DateUtil.addDate(kqDate, -1);//上一天日期 + String nextDate = DateUtil.addDate(kqDate, 1);//下一天日期 + String dateKey = userId + "|" + kqDate; + String nextDateKey = userId + "|" + nextDate; + ArrayList hostIps = InitServer.getRealIp(); + kqLog.info("format in >>>>>userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid); + boolean oneSign = false; + List lsSignTime = new ArrayList<>(); + List lsWorkTime = new ArrayList<>(); + List lsRestTime = new ArrayList<>(); + List workFlow = null; + + //24小时班次制处理 + RecordSet rsC = new RecordSet(); + //首先判断是否为24小时班次制 + Integer is24HourView = -1; + String serialId = workTime.getSerialId(); + String checkSerialSql = "select is24HourView from kq_ShiftManagement where id = ?"; + rsC.executeQuery(checkSerialSql,serialId); + while (rsC.next()) { + is24HourView = Util.getIntValue(Util.null2String(rsC.getString("is24HourView"))); + } + + if (workTime != null) { + lsSignTime = workTime.getSignTime();//允许打卡时间 + lsWorkTime = workTime.getWorkTime();//工作时间 + lsRestTime = workTime.getRestTime();//休息时段时间 + oneSign = lsWorkTime!=null&&lsWorkTime.size()==1; + } + + int[] dayMins = new int[2880];//一天所有分钟数 + Arrays.fill(dayMins, -1); + // 一天4次打卡单独做判断,如果是上午下班打卡和下午上班打卡时间重叠,那么上午的下班卡取最早的,下午的上班卡取最晚的。用shiftCount是否等于-1判断,-1就走标准不重叠。2就表示重叠走新的逻辑 + int shiftCount = lsWorkTime == null ? 0 : lsWorkTime.size(); + int shiftI = 0; + String signEndDateTimeZero = ""; + for (int i = 0; lsWorkTime != null && i < lsWorkTime.size(); i++) { + shiftI = i; + TimeScopeEntity signTimeScope = lsSignTime.get(i); + TimeScopeEntity workTimeScope = lsWorkTime.get(i); + String signBeginDateTime = signTimeScope.getBeginTimeAcross() ? nextDate : kqDate; + if(signTimeScope.isBeginTimePreAcross()){ + signBeginDateTime = preDate; + } + signBeginDateTime+=" "+kqTimesArrayComInfo.turn48to24Time(signTimeScope.getBeginTime())+":00"; + String signEndDateTime = signTimeScope.getEndTimeAcross() ? nextDate : kqDate; + signEndDateTime+=" "+kqTimesArrayComInfo.turn48to24Time(signTimeScope.getEndTime())+":59"; + if (shiftCount == 2 && shiftI == 0) { + signEndDateTimeZero = signEndDateTime; + } + if (shiftCount == 2 && shiftI == 1) { + shiftCount = signBeginDateTime.compareTo(signEndDateTimeZero) <= 0 ? shiftCount : -1; + } + } + //客户版本有过二开,不兼容此逻辑,单独修改,屏蔽掉这个 + shiftCount=-1; + for (int i = 0; lsWorkTime != null && i < lsWorkTime.size(); i++) { + shiftI = i; + params = new ArrayList<>(); + TimeScopeEntity signTimeScope = lsSignTime.get(i); + TimeScopeEntity workTimeScope = lsWorkTime.get(i); + //TimeScopeEntity restTimeScope = lsRestTime.isEmpty()?null:lsRestTime.get(i); + String workBeginTime = Util.null2String(workTimeScope.getBeginTime()); + String ori_workBeginTime = workBeginTime; + int workBeginIdx = kqTimesArrayComInfo.getArrayindexByTimes(workBeginTime); + boolean workBenginTimeAcross = workTimeScope.getBeginTimeAcross(); + String workEndTime = Util.null2String(workTimeScope.getEndTime()); + String ori_workEndTime = workEndTime; + int workEndIdx = kqTimesArrayComInfo.getArrayindexByTimes(workEndTime); + boolean workEndTimeAcross = workTimeScope.getEndTimeAcross(); + int workMins = workTimeScope.getWorkMins(); + + String workBeginDate = workBenginTimeAcross ? nextDate : kqDate; + String workEndDate = workEndTimeAcross ? nextDate : kqDate; + + if(is24HourView == 1) {//是 + if ( i < lsWorkTime.size() - 1 ) { + TimeScopeEntity nextParam = lsWorkTime.get(i + 1); + String nextWorkbegintime = Util.null2String(nextParam.getBeginTime()); + Integer betwMins = getTime(workBeginDate+" "+workEndTime, workEndDate+" "+nextWorkbegintime); + workMins = workMins+betwMins; + //将改工作时段的结束index加上休息时段的长 + workEndIdx = workEndIdx + betwMins; + } + } + + Arrays.fill(dayMins, workBeginIdx, workEndIdx, 1);//工作时段标识 1 + + int beginIdx = 0; + int endIdx = 0; + int checkIn = 0;//签到 + int checkOut = 0;//签退 + String signInId = "";//签到ID + String signInDate = "";//签到日期 + String signInTime = "";//签到日期 + String signOutId = "";//签退ID + String signOutDate = "";//签退ID + String signOutTime = "";//签退时间 + int earlyInMins = 0;//早到分钟数 + int lateOutMins = 0;//晚走分钟数 + int signMins = 0;//签到签退时长 + int tmpAttendanceMins = 0;//出勤分钟数(流程抵扣来的) + int attendanceMins = 0;//出勤时长 + int beLateMins = 0;//迟到时长 + int graveBeLateMins = 0;//严重迟到时长 + int leaveEarlyMins = 0;//早退时长 + int graveLeaveEarlyMins = 0;//严重早退时长 + int absenteeismMins = 0;//旷工时长 + int leaveMins = 0;//请假时长 + Map leaveInfo = new HashMap<>();//请假信息 + Map otherinfo = new HashMap<>();//存一些用得到的信息 + int evectionMins = 0;//出差时长 + int outMins = 0;//公出时长 + int otherMins = 0;//异常流程时长 + int forgotCheckMins = 0;//漏签时长 + int forgotBeginWorkCheckMins = 0;//上班漏签 + int signInTimeIndx = -1; + int flowSignInTimeIndx = -1; + int signInTimeOutdx = -1; + //用来计算实际打卡时长用的 + int signInTimeIndx4Sign = -1; + int signInTimeOutdx4Sign = -1; + + String signBeginDateTime = signTimeScope.getBeginTimeAcross() ? nextDate : kqDate; + if(signTimeScope.isBeginTimePreAcross()){ + signBeginDateTime = preDate; + } + signBeginDateTime+=" "+kqTimesArrayComInfo.turn48to24Time(signTimeScope.getBeginTime())+":00"; + String signEndDateTime = signTimeScope.getEndTimeAcross() ? nextDate : kqDate; + signEndDateTime+=" "+kqTimesArrayComInfo.turn48to24Time(signTimeScope.getEndTime())+":59"; + String workBeginDateTime = workTimeScope.getBeginTimeAcross() ? nextDate : kqDate; + workBeginDateTime+=" "+kqTimesArrayComInfo.turn48to24Time(workTimeScope.getBeginTime())+":00"; + String workEndDateTime = workTimeScope.getEndTimeAcross() ? nextDate : kqDate; + workEndDateTime+=" "+kqTimesArrayComInfo.turn48to24Time(workTimeScope.getEndTime())+":00"; + + kqLog.info("signBeginDateTime" + signBeginDateTime+"::userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid); + kqLog.info("signEndDateTime" + signEndDateTime+"::userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid); + kqLog.info("workBeginDateTime" + workBeginDateTime+"::userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid); + kqLog.info("workEndDateTime" + workEndDateTime+"::userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid); + + Map shifRuleMap = Maps.newHashMap(); + if(oneSign){ + //个性化设置只支持一天一次上下班 + ShiftInfoBean shiftInfoBean = new ShiftInfoBean(); + shiftInfoBean.setSplitDate(kqDate); + shiftInfoBean.setShiftRuleMap(workTime.getShiftRuleInfo()); + shiftInfoBean.setSignTime(lsSignTime); + shiftInfoBean.setWorkTime(lsWorkTime); + List logList = Lists.newArrayList(); + KQShiftRuleInfoBiz.getShiftRuleInfo(shiftInfoBean, userId, shifRuleMap,logList); + if(!shifRuleMap.isEmpty()){ + if(!logList.isEmpty()){ + otherinfo.put("logList", logList); + } + otherinfo.put("shiftRule", shifRuleMap); + if(shifRuleMap.containsKey("shift_beginworktime")){ + String shift_beginworktime = Util.null2String(shifRuleMap.get("shift_beginworktime")); + if(shift_beginworktime.length() > 0){ + workBeginTime = Util.null2String(shift_beginworktime); + workBeginIdx = kqTimesArrayComInfo.getArrayindexByTimes(workBeginTime); + workTimeScope.setBeginTime(workBeginTime); + workTimeScope.setBeginTimeAcross(workBeginIdx>=1440?true:false); + } + } + if(shifRuleMap.containsKey("shift_endworktime")){ + String shift_endworktime = Util.null2String(shifRuleMap.get("shift_endworktime")); + if(shift_endworktime.length() > 0){ + workEndTime = Util.null2String(shift_endworktime); + workEndIdx = kqTimesArrayComInfo.getArrayindexByTimes(workEndTime); + workTimeScope.setEndTime(workEndTime); + workTimeScope.setEndTimeAcross(workEndIdx>=1440?true:false); + } + } + } + kqLog.info("个性化之后 signBeginDateTime" + signBeginDateTime); + kqLog.info("个性化之后 signEndDateTime" + signEndDateTime); + kqLog.info("个性化之后 workBeginDateTime" + workBeginDateTime); + kqLog.info("个性化之后 workEndDateTime" + workEndDateTime); + } + + //获取班次打卡数据 + List lsCheckInfo = new com.engine.kq.biz.KQFormatSignData().getSignInfo(userId,signTimeScope,workTimeScope,kqDate,preDate,nextDate,kqTimesArrayComInfo,hostIps,uuid,shiftCount,shiftI); + kqLog.info("lsCheckInfo" + JSONObject.toJSONString(lsCheckInfo)+"::userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid); + if(this.writeLog) { + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005297,weaver.general.ThreadVarLanguage.getLang())+"",signBeginDateTime); + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005298,weaver.general.ThreadVarLanguage.getLang())+"",signEndDateTime); + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(1940,weaver.general.ThreadVarLanguage.getLang())+"",workBeginDateTime); + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005299,weaver.general.ThreadVarLanguage.getLang())+"",workEndDateTime); + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005300,weaver.general.ThreadVarLanguage.getLang())+"",lsCheckInfo); + } + for (int j = 0; lsCheckInfo != null && j < lsCheckInfo.size(); j++) { + Map checkInfo = (Map) lsCheckInfo.get(j); + String signStatus = Util.null2String(checkInfo.get("signStatus")); + String signId = Util.null2String(checkInfo.get("signId")); + String signDate = Util.null2String(checkInfo.get("signDate")); + String signTime = Util.null2String(checkInfo.get("signTime")); + String deduct_signintime = Util.null2String(checkInfo.get("deduct_signintime")); + String deduct_signofftime = Util.null2String(checkInfo.get("deduct_signofftime")); + String flow_signInTime = ""; + String flow_signOutTime = ""; + if(kqDate.compareTo(signDate) < 0)endIdx+=1440; + if (signTime.length() > 8) { + signTime = signTime.substring(0, 8); + } + if (checkInfo.get("signType").equals("1")) {//签到 + checkIn++; + //如果流程抵扣存在,打卡时长也存在,那么相互比较得到出勤时长和打卡时长 暂不这样处理,还是按照漏签的逻辑来处理 + if(signTime.length() > 0){ + signInTimeIndx4Sign = kqTimesArrayComInfo.getArrayindexByTimes(signTime); + } + signInId = signId; + signInDate = signDate; + signInTime = signTime; + signInTimeIndx = kqTimesArrayComInfo.getArrayindexByTimes(signInTime); + if(deduct_signintime.length() > 0){ + if(signTime.length() > 0){ + if(deduct_signintime.compareTo(signTime) < 0){ + flow_signInTime = deduct_signintime; + } + }else{ + flow_signInTime = deduct_signintime; + } + } + if(flow_signInTime.length() > 0){ + flowSignInTimeIndx = kqTimesArrayComInfo.getArrayindexByTimes(flow_signInTime); + } + if(kqDate.compareTo(signDate) < 0) { + signInTimeIndx += 1440; + flowSignInTimeIndx += 1440; + }else if(kqDate.compareTo(signDate) > 0){ + signInTimeIndx -= 1440; + signInTimeIndx = signInTimeIndx < 0 ? 0 : signInTimeIndx; + flowSignInTimeIndx -= 1440; + flowSignInTimeIndx = flowSignInTimeIndx < 0 ? 0 : flowSignInTimeIndx; + } + if(oneSign){ + if(workBeginIdx>signInTimeIndx) { + earlyInMins = workBeginIdx-signInTimeIndx; + } + } + } else if (checkInfo.get("signType").equals("2")) {//签退 + checkOut++; + //如果流程抵扣存在,打卡时长也存在,那么相互比较得到出勤时长和打卡时长 暂不这样处理,还是按照漏签的逻辑来处理 + if(signTime.length() > 0){ + signInTimeOutdx4Sign = kqTimesArrayComInfo.getArrayindexByTimes(signTime); + } + signOutId = signId; + signOutDate = signDate; + signOutTime = signTime; + signInTimeOutdx = kqTimesArrayComInfo.getArrayindexByTimes(signOutTime); + if(deduct_signofftime.length() > 0){ + if(signTime.length() > 0){ + if(deduct_signofftime.compareTo(signTime) > 0){ + flow_signOutTime = deduct_signofftime; + } + }else{ + flow_signOutTime = deduct_signofftime; + } + } + if(flow_signOutTime.length() > 0){ + signInTimeOutdx = kqTimesArrayComInfo.getArrayindexByTimes(flow_signOutTime); + } + if(kqDate.compareTo(signDate) < 0){ + signInTimeOutdx+=1440; + }else if(kqDate.compareTo(signDate) > 0){ + signInTimeOutdx -= 1440; + signInTimeOutdx = signInTimeOutdx < 0 ? 0 : signInTimeOutdx; + } + if(oneSign){ + if(signInTimeOutdx>workEndIdx) { + lateOutMins = signInTimeOutdx-workEndIdx; + } + } + } + if (checkInfo.get("signType").equals("1")) {//签到 + if(signTime.length() > 0){ + String signMinTime = signTime.substring(0,5)+":00"; + endIdx = kqTimesArrayComInfo.getArrayindexByTimes(signTime); + if(signTime.compareTo(signMinTime) > 0){ + //如果签到时间是带秒的且是迟到,那么签到时间多一秒和多一分钟是一样的 + endIdx += 1; + signInTimeIndx = signInTimeIndx + 1;//如果是带秒的打卡数据不应该影响流程抵扣的数据的下标 + } + if(kqDate.compareTo(signDate) < 0){ + endIdx+=1440; + }else if(kqDate.compareTo(signDate) > 0){ + endIdx -= 1440; + endIdx = endIdx < 0 ? 0 : endIdx; + } + if (endIdx > workBeginIdx) { + if(flow_signInTime.length() > 0){ + if(flowSignInTimeIndx > workBeginIdx){ + //增加一个判断,流程抵扣打卡如果开启了并且有抵扣上班打卡,那么也就不是迟到了 + Arrays.fill(dayMins, workBeginIdx, endIdx, 2);//迟到时段标识 2 + } + }else{ + Arrays.fill(dayMins, workBeginIdx, endIdx, 2);//迟到时段标识 2 + } + } + } + } else if (checkInfo.get("signType").equals("2")) {//签退 + if(signTime.length() > 0){ + beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(signTime); + if(StringUtils.isNotBlank(signDate) && signDate.compareTo(kqDate) > 0){ + beginIdx+=1440; + }else if(kqDate.compareTo(signDate) > 0){ + beginIdx -= 1440; + beginIdx = beginIdx < 0 ? 0 : beginIdx; + } + if (workEndIdx > beginIdx) { + if(flow_signOutTime.length() > 0){ + if (workEndIdx > signInTimeOutdx) { + //增加一个判断,流程抵扣打卡如果开启了并且有抵扣下班打卡,那么也就不是早退了 + Arrays.fill(dayMins, beginIdx, workEndIdx, 3);//早退时段标识 3 + } + }else{ + + Arrays.fill(dayMins, beginIdx, workEndIdx, 3);//早退时段标识 3 + } + } + } + } + } + + //打卡时长=签退时间-签到时间(有签到签退才计算) + if(checkIn==1&&checkOut==1){ + if(signInTimeIndx4Sign > -1 && signInTimeOutdx4Sign > -1){ + if(DateUtil.dayDiff(signInDate,signOutDate)==0){//同一天签到和签退 + signMins=signInTimeOutdx4Sign - signInTimeIndx4Sign; + }else if(DateUtil.dayDiff(signInDate,signOutDate)==1) {//第一天签到,第二天签退 + if(signInTimeOutdx4Sign workBeginIdx) { + Arrays.fill(dayMins, workBeginIdx, workEndIdx, 4);//旷工时段标识 4 + } + } + + if (checkOut == 0 && checkIn > 0) {//漏签(有签到无签退) + if(signInTimeIndx > -1){ + if (workEndIdx > signInTimeIndx) { + //漏签就是从本次时段内的打卡到下班点 + //上班漏签应该是从签到到签到结束时间,不过这里可以不用管,只是一个次数 + Arrays.fill(dayMins, signInTimeIndx, workEndIdx, 6);//上班漏签时段标识 6 + } else { + //签到晚于本次时段结束时间,也算漏签 + forgotCheckMins++; + } + }else if(flowSignInTimeIndx > -1){ + if (workEndIdx > flowSignInTimeIndx) { + //漏签就是从本次时段内的打卡到下班点 + //上班漏签应该是从签到到签到结束时间,不过这里可以不用管,只是一个次数 + Arrays.fill(dayMins, flowSignInTimeIndx, workEndIdx, 6);//上班漏签时段标识 6 + } else { + //签到晚于本次时段结束时间,也算漏签 + forgotCheckMins++; + } + } + } + + if (checkIn == 0 && checkOut > 0) {//漏签(有签退无签到) + if(signInTimeOutdx > 0){ + if(workBeginIdx < signInTimeOutdx) { + //下班漏签应该是从签退到签退开始时间,不过这里可以不用管,只是一个次数 + Arrays.fill(dayMins, workBeginIdx, signInTimeOutdx, 66);//下班漏签时段标识 66,66呼应前面的漏签的6 + }else{ + //这种数据理论上不会存在,也记下吧 + forgotBeginWorkCheckMins++; + } + } + } + + if (workFlowInfo.get(dateKey) != null) { + workFlow = (List) workFlowInfo.get(dateKey); + } + + for (int j = 0; workFlow != null && j < workFlow.size(); j++) { + Map data = (Map) workFlow.get(j); + String flowType = Util.null2String(data.get("flowtype")); + String newLeaveType = Util.null2String(data.get("newleavetype")); + String signtype = Util.null2String(data.get("signtype")); + String serial = Util.null2String(data.get("serial")); + String requestId = Util.null2String(data.get("requestId")); + beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(data.get("begintime"))); + endIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(data.get("endtime"))); + if (beginIdx >= endIdx) { + continue; + } + + if(flowType.equals(FlowReportTypeEnum.EVECTION.getFlowType())){ + Arrays.fill(dayMins, beginIdx, endIdx, 7);//出差抵扣时段标识 7 + }else if(flowType.equals(FlowReportTypeEnum.OUT.getFlowType())){ + Arrays.fill(dayMins, beginIdx, endIdx, 8);//公出抵扣时段标识 8 + }else if(flowType.equalsIgnoreCase(FlowReportTypeEnum.LEAVE.getFlowType())){ + if (endIdx > beginIdx) { + Arrays.fill(dayMins, beginIdx, endIdx, 5);//流程抵扣时段标识 5 + int tmpBeginIdx = beginIdx; + int tmpEndIdx = endIdx; + Integer val = 0; + + if(beginIdx>=workEndIdx){ + continue; + } + if(endIdx<=workBeginIdx){ + continue; + } + + if(leaveInfo.get(newLeaveType)==null){ + leaveInfo.put(newLeaveType,val); + }else{ + val = (Integer) leaveInfo.get(newLeaveType); + } + + if(beginIdxworkEndIdx)tmpEndIdx=endIdx; + if(tmpEndIdx>tmpBeginIdx){ + leaveInfo.put(newLeaveType,val+(tmpEndIdx-tmpBeginIdx)); + } + } + }else{ + if (endIdx > beginIdx) { + Arrays.fill(dayMins, beginIdx, endIdx, 99);//异常流程抵扣时段标识99 + } + } + } + + + if (workEndTimeAcross && false) {//跨天需要加入一天的流程 + workFlow = null; + if (workFlowInfo.get(nextDateKey) != null) { + workFlow = (List) workFlowInfo.get(nextDateKey); + } + + for (int j = 0; workFlow != null && j < workFlow.size(); j++) { + Map data = (Map) workFlow.get(j); + String flowType = Util.null2String(data.get("flowtype")); + beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(data.get("begintime")))+1440; + endIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(data.get("endtime")))+1440; + if(endIdx>=2880){ + endIdx = 2880; + } + if(flowType.equals(FlowReportTypeEnum.EVECTION.getFlowType())){ + Arrays.fill(dayMins, beginIdx, endIdx, 7);//出差抵扣时段标识 7 + }else if(flowType.equals(FlowReportTypeEnum.OUT.getFlowType())){ + Arrays.fill(dayMins, beginIdx, endIdx, 8);//公出抵扣时段标识 8 + }else if(flowType.equalsIgnoreCase(FlowReportTypeEnum.LEAVE.getFlowType())){ + if (endIdx > beginIdx) { + Arrays.fill(dayMins, beginIdx, endIdx, 5);//流程抵扣时段标识 5 + + } + }else{ + if (endIdx > beginIdx) { + Arrays.fill(dayMins, beginIdx, endIdx, 99);//异常流程抵扣时段标识99 + } + } + } + } + + if(lsRestTime != null && !lsRestTime.isEmpty()){ + for(int k = 0 ; k < lsRestTime.size(); k++){ + TimeScopeEntity restTimeScope = lsRestTime.get(k); + if (restTimeScope!=null) { + String restBeginTime = Util.null2String(restTimeScope.getBeginTime()); + String restEndTime = Util.null2String(restTimeScope.getEndTime()); + beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(restBeginTime); + endIdx = kqTimesArrayComInfo.getArrayindexByTimes(restEndTime); + if (endIdx > beginIdx) { + Arrays.fill(dayMins, beginIdx, endIdx, -11);//休息时间 + } + } + } + int all_rest_cnt = kqTimesArrayComInfo.getCnt(dayMins, workBeginIdx, workEndIdx, -11); + if(all_rest_cnt >= 0){ + workMins = workMins-(all_rest_cnt); + } + } + + for (int j = workBeginIdx; j < workEndIdx; j++) { + switch (dayMins[j]) { + case 1: + tmpAttendanceMins++; + break; + case 2: + beLateMins++; + break; + case 3: + leaveEarlyMins++; + break; + case 4: + absenteeismMins++; + break; + case 5: + leaveMins++; + break; + case 6: + forgotCheckMins++; + break; + case 7: + evectionMins++; + break; + case 8: + outMins++; + break; + case 66: + forgotBeginWorkCheckMins++; + break; + case 99: + otherMins++; + break; + default: + break; + } + } + + if(forgotCheckMins == 1 && beLateMins==0 && tmpAttendanceMins==0){//forgotCheckMins==1表示下班后漏签,不是迟到,流程已完全抵扣异常 + forgotCheckMins = 0; + } + + KQShiftRuleEntity kqShiftRuleEntity = new KQShiftRuleEntity(); + kqShiftRuleEntity.setUserId(userId); + kqShiftRuleEntity.setKqDate(kqDate); + kqShiftRuleEntity.setBelatemins(beLateMins); + kqShiftRuleEntity.setLeaveearlymins(leaveEarlyMins); + kqShiftRuleEntity.setAbsenteeismmins(absenteeismMins); + kqShiftRuleEntity.setForgotcheckmins(forgotCheckMins); + kqShiftRuleEntity.setForgotBeginWorkCheckMins(forgotBeginWorkCheckMins); + kqShiftRuleEntity.setEarlyInMins(earlyInMins); + kqShiftRuleEntity.setLateOutMins(lateOutMins); + kqLog.info("人性化规则处理前数据" + JSONObject.toJSONString(kqShiftRuleEntity)); + if(this.writeLog) { + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005301,weaver.general.ThreadVarLanguage.getLang())+"",kqShiftRuleEntity); + } + // 考勤二开 设置第二次打卡,不记录迟到 + if (CollectionUtils.isNotEmpty(lsWorkTime) && lsWorkTime.size() == 2 && lsWorkTime.get(1).getBeginTime().equals("24:00") && i == 1) { + WorkTimeEntity cusWorkTimeEntity = new WorkTimeEntity(); + BeanUtils.copyProperties(workTime,cusWorkTimeEntity); + Map shiftRuleInfo = cusWorkTimeEntity.getShiftRuleInfo(); + RecordSet rs = new RecordSet(); + rs.executeQuery("select mins_next from kq_ShiftOnOffWorkSections where record ='1' and onoffworktype = 'start' and serialid = ?", workTime.getSerialId()); + String mins_next = ""; + if (rs.next()) { + mins_next = rs.getString("mins_next"); + } + shiftRuleInfo.put("permitlatestatus", "1"); + shiftRuleInfo.put("permitlateminutes", StringUtils.isNotBlank(mins_next) ? mins_next : "239"); + //人性化规则 + kqShiftRuleEntity = kqFormatShiftRule.doShiftRule(cusWorkTimeEntity, kqShiftRuleEntity); + } else { + //人性化规则 + kqShiftRuleEntity = kqFormatShiftRule.doShiftRule(workTime, kqShiftRuleEntity); + } + //人性化规则 + //kqShiftRuleEntity = kqFormatShiftRule.doShiftRule(workTime,kqShiftRuleEntity); + kqLog.info("人性化规则处理后数据" + JSONObject.toJSONString(kqShiftRuleEntity)); + if(this.writeLog) { + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005302,weaver.general.ThreadVarLanguage.getLang())+"",kqShiftRuleEntity); + } + beLateMins = kqShiftRuleEntity.getBelatemins(); + graveBeLateMins = kqShiftRuleEntity.getGravebelatemins(); + leaveEarlyMins = kqShiftRuleEntity.getLeaveearlymins(); + graveLeaveEarlyMins = kqShiftRuleEntity.getGraveleaveearlymins(); + absenteeismMins = kqShiftRuleEntity.getAbsenteeismmins(); + forgotCheckMins = kqShiftRuleEntity.getForgotcheckmins(); + forgotBeginWorkCheckMins = kqShiftRuleEntity.getForgotBeginWorkCheckMins(); + + boolean isondutyfreecheck =false; + boolean isoffdutyfreecheck =false; + Map model_ShiftRule = kqFormatShiftRule.getModel_ShiftRule(i, workTime.getSerialId()); + Iterator iter = model_ShiftRule.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = (Map.Entry) iter.next(); + String key = Util.null2String(entry.getKey()); + String value = Util.null2String(entry.getValue()); + if(key.equals("start")&&value.equals("1")){ + isondutyfreecheck = true; + } + if(key.equals("end")&&value.equals("1")){ + isoffdutyfreecheck = true; + } + } + boolean beforeBegin = !new com.engine.kq.biz.KQFormatBiz().needCal(workBeginDate,workBeginTime); + if(beforeBegin) {//还未到上班时间,不用计算任何状态 + kqLog.writeLog("还未到上班时间,不用计算任何状态"); + beLateMins = 0; + graveBeLateMins = 0; + leaveEarlyMins = 0; + graveLeaveEarlyMins = 0; + absenteeismMins = 0; + forgotCheckMins = 0; + forgotBeginWorkCheckMins = 0; + }else if(!new com.engine.kq.biz.KQFormatBiz().needCal(workEndDate,workEndTime)) {//还未到下班时间 + kqLog.writeLog("还未到上班时间"); + leaveEarlyMins = 0; + graveLeaveEarlyMins = 0; + forgotCheckMins = 0; + } + + if (workTime.getIsExclude()) {//无需考勤人员没有异常状态 + beLateMins = 0; + graveBeLateMins = 0; + leaveEarlyMins = 0; + graveLeaveEarlyMins = 0; + absenteeismMins = 0; + forgotCheckMins = 0; + forgotBeginWorkCheckMins = 0; + } + //允许下班不打卡 ,如果上班也没有打卡,那么算上班旷工0.5天 + if (isoffdutyfreecheck) { + if (checkIn == 0) {//(无签到),就会有上班漏签,如果有下班卡,那么上班漏签 + if(forgotBeginWorkCheckMins==0&&absenteeismMins>0){ + forgotBeginWorkCheckMins= absenteeismMins ; + } + } + absenteeismMins = 0; + forgotCheckMins = 0; + } + //允许上班不打卡,如果下班也没有打卡,那么算漏签 + if(isondutyfreecheck){ + if (checkOut == 0) {//(无签退) + if(forgotCheckMins==0&&absenteeismMins>0){ + forgotCheckMins= absenteeismMins ; + } + } + absenteeismMins = 0; + forgotBeginWorkCheckMins = 0; + } + if(isondutyfreecheck&&isoffdutyfreecheck){ + absenteeismMins = 0; + forgotCheckMins = 0; + forgotBeginWorkCheckMins = 0; + } + //计算实际出勤时间(出差公出算出勤)=应出勤-旷工-请假-迟到-早退 + attendanceMins = workMins - absenteeismMins-leaveMins-beLateMins-graveBeLateMins-leaveEarlyMins-graveLeaveEarlyMins; + // 如果没有开启"漏签是否算实际出勤"开关,则漏签不算实际出勤时长 + if("0".equals(nosign_is_absent)) { + attendanceMins = attendanceMins-forgotCheckMins-forgotBeginWorkCheckMins; + } + if(beforeBegin || attendanceMins < 0) {//还未到上班时间,不用计算任何状体 + attendanceMins = 0; + } + kqLog.info("实际出勤计算公式" + "实际出勤=应出勤- 旷工-请假-迟到-早退 userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid); + kqLog.info("实际出勤计算结果" + attendanceMins + "=" + workMins + "- " + absenteeismMins + "-" + leaveMins + "-" + (beLateMins + graveBeLateMins) + "-" + (leaveEarlyMins - graveLeaveEarlyMins)+" userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid); + if(this.writeLog) { + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005303,weaver.general.ThreadVarLanguage.getLang())+"",""+weaver.systeminfo.SystemEnv.getHtmlLabelName(130566,weaver.general.ThreadVarLanguage.getLang())+"="+weaver.systeminfo.SystemEnv.getHtmlLabelName(132056,weaver.general.ThreadVarLanguage.getLang())+"- "+weaver.systeminfo.SystemEnv.getHtmlLabelName(20085,weaver.general.ThreadVarLanguage.getLang())+"-"+weaver.systeminfo.SystemEnv.getHtmlLabelName(670,weaver.general.ThreadVarLanguage.getLang())+"-"+weaver.systeminfo.SystemEnv.getHtmlLabelName(20081,weaver.general.ThreadVarLanguage.getLang())+"-"+weaver.systeminfo.SystemEnv.getHtmlLabelName(20082,weaver.general.ThreadVarLanguage.getLang())+""); + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005304,weaver.general.ThreadVarLanguage.getLang())+"",attendanceMins+"="+workMins+"- "+absenteeismMins+"-"+leaveMins+"-"+(beLateMins+graveBeLateMins)+"-"+(leaveEarlyMins-graveLeaveEarlyMins)); + } + //判断当天考勤状态 +// if (beLateMins > 0) { +// status = ButtonStatusEnum.BELATE.getStatusCode(); +// } else if (leaveEarlyMins > 0) { +// status = ButtonStatusEnum.LEAVEERALY.getStatusCode(); +// } else if (absenteeismMins > 0) { +// status = ButtonStatusEnum.ABSENT.getStatusCode(); +// } else if (forgotCheckMins > 0) { +// status = ButtonStatusEnum.NOSIGN.getStatusCode(); +// } else { +// status = ButtonStatusEnum.NORMAL.getStatusCode(); +// } + + String groupid = Util.null2String(workTime.getGroupId()); + String serialid = Util.null2String(workTime.getSerialId()); + + if (i == 0 ) {//第一段工作时段,考虑迟到,严重迟到,旷工,不考虑早退,严重早退 + //将早退,严重早退时长加到出勤时长中 + attendanceMins = attendanceMins + leaveEarlyMins + graveLeaveEarlyMins; + //再将早退,严重早退时长归零 + leaveEarlyMins = 0 ; + graveLeaveEarlyMins = 0 ; + } else if (i > 0 && i < lsWorkTime.size() -1 ) {//非第一段工作时段也非最后一个工作时段,不考虑迟到,严重迟到,旷工,早退,严重早退 + //将迟到,严重迟到,旷工,早退,严重早退时长加到出勤时长中 + attendanceMins = attendanceMins + beLateMins + graveBeLateMins + absenteeismMins + leaveEarlyMins + graveLeaveEarlyMins; + //再将迟到,严重迟到,旷工,早退,严重早退时长归零 + beLateMins = 0 ; + graveBeLateMins = 0 ; + absenteeismMins = 0 ; + leaveEarlyMins = 0 ; + graveLeaveEarlyMins = 0 ; + } else if (i == lsWorkTime.size() -1) {//最后一个工作时段,考虑早退,严重早退,旷工,不考虑迟到,严重迟到 + //将迟到,严重迟到时长加到出勤时长中 + attendanceMins = attendanceMins + beLateMins + graveBeLateMins; + //再将早退,严重早退时长归零 + beLateMins = 0 ; + graveBeLateMins = 0 ; + } + + params.add(userId); + params.add(kqDate); + params.add(groupid.length() == 0 ? null : groupid); + params.add(serialid.length() == 0 ? null : serialid); + params.add(i); + params.add(workBeginDate);//index:5 value:工作开始日期 + params.add(kqTimesArrayComInfo.turn48to24Time(ori_workBeginTime));//index:6 value:工作开始时间 + params.add(workEndDate);//index:7 value:工作结束日期 + params.add(kqTimesArrayComInfo.turn48to24Time(ori_workEndTime));//index:8 value:工作结束时间 + params.add(workMins);//index:9 value:工作时长 + params.add(signInDate);//index:10 value:签到日期 + params.add(signInTime); + params.add(signInId.length() == 0 ? null : signInId); + params.add(signOutDate); + params.add(signOutTime); + params.add(signOutId.length() == 0 ? null : signOutId); + kqLog.info("format in >>>>>userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid + +":signInDate:"+signInDate+":signInTime::"+signInTime+":signOutDate:"+signOutDate+":signOutTime::"+signOutTime); + params.add(signMins);//index:16 value:签到签退时长 + params.add(attendanceMins);//index:17 value:出勤时长 + params.add(beLateMins); + params.add(graveBeLateMins); + params.add(leaveEarlyMins); + params.add(graveLeaveEarlyMins); + params.add(absenteeismMins); + params.add(forgotCheckMins); + params.add(leaveMins); + params.add(JSONObject.toJSONString(leaveInfo)); + params.add(evectionMins); + params.add(outMins); + params.add(forgotBeginWorkCheckMins); + params.add(JSONObject.toJSONString(otherinfo)); + + Map definedFieldInfo = new com.engine.kq.biz.KQFormatBiz().getDefinedField(); + String[] definedFields = Util.splitString(Util.null2String(definedFieldInfo.get("definedField")),","); + com.engine.kq.biz.KQReportFieldComInfo kqReportFieldComInfo = new com.engine.kq.biz.KQReportFieldComInfo(); + for (int tmpIdx = 0; tmpIdx env = new HashMap<>(); + String keyname = ""; + while (matcher.find()) { + String key = matcher.group(0); + keyname = key.substring(2, key.length() - 1).trim(); + expression = matcher.replaceAll(keyname); + env.put(keyname, keyname.equals("beLateMins")?beLateMins:leaveEarlyMins); + } + Expression compiledExp = AviatorEvaluator.compile(expression,true); + String value = Util.null2String(compiledExp.execute(env)); + params.add(value); + if(value.equals("1")) { + params.add(keyname.equals("beLateMins") ? beLateMins : leaveEarlyMins); + }else{ + params.add("0"); + } + } + kqLog.info("format in >>>>>userId" + userId + "kqDate==" + kqDate+":hostIps:"+hostIps+":uuid::"+uuid + +":params:"+JSON.toJSONString(params)); + lsParam.add(params); + } + + } catch (Exception e) { + writeLog(e); + kqLog.info(e); + } + return lsParam; + } + + /** + * 24小时制班次二开 + * 计算两个时间之间相差的分钟数 + * 时间格式为:yyyy-MM-dd HH:mm + * @param oldTime + * @param newTime + * @return + * @throws ParseException + */ + public Integer getTime(String oldTime,String newTime) throws ParseException { + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + long NTime =df.parse(newTime).getTime(); + //从对象中拿到时间 + long OTime = df.parse(oldTime).getTime(); + long diff=(NTime-OTime)/1000/60; + Integer result= Integer.parseInt(String.valueOf(diff)); + return result; + } + + public void setWriteLog(boolean writeLog) { + this.writeLog = writeLog; + } + + public Map getLogInfo() { + return logInfo; + } + + public void formatDateByKQDate(String kqdate) { + com.engine.kq.biz.KQFormatBiz kqFormatBiz = new com.engine.kq.biz.KQFormatBiz(); + kqFormatBiz.formatDateByKQDate(kqdate); + } + + public void formatDateByGroupId(String groupid, String kqdate) { + com.engine.kq.biz.KQFormatBiz kqFormatBiz = new com.engine.kq.biz.KQFormatBiz(); + kqFormatBiz.formatDateByGroupId(groupid, kqdate); + } + + public void formatDate(String resourceid, String kqdate) { + com.engine.kq.biz.KQFormatBiz kqFormatBiz = new com.engine.kq.biz.KQFormatBiz(); + kqFormatBiz.formatDate(resourceid, kqdate); + } + + public void delFormatData(String resourceid, String kqdate) { + com.engine.kq.biz.KQFormatBiz kqFormatBiz = new KQFormatBiz(); + kqFormatBiz.delFormatData(resourceid, kqdate); + } + + /** + * 非工作日格式化考勤报表 + * @param userId + * @param kqDate + * @param nonlsParam + * @param workTime + * @param workFlowInfo + */ + public void formatNonWork(String userId, String kqDate, List nonlsParam, WorkTimeEntity workTime, Map workFlowInfo) { + String signInId = ""; + String signInDate = ""; + String signInTime = ""; + String signOutId = ""; + String signOutDate = ""; + String signOutTime = ""; + int beginIdx = 0; + int endIdx = 0; + int leaveMins = 0;//请假时长 + Map leaveInfo = new HashMap<>();//请假信息 + int evectionMins = 0;//出差时长 + int outMins = 0;//公出时长 + int otherMins = 0;//异常流程时长 + int[] dayMins = new int[2880];//一天所有分钟数 + List workFlow = null; + String dateKey = userId + "|" + kqDate; + com.engine.kq.biz.KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + + String preDate = DateUtil.addDate(kqDate, -1);//上一天日期 + String nextDate = DateUtil.addDate(kqDate, 1);//下一天日期 + WorkTimeEntity pre_workTime = new com.engine.kq.biz.KQWorkTime().getWorkTime(userId, preDate); + List pre_lsSignTime = new ArrayList<>(); + + if (pre_workTime != null) { + pre_lsSignTime = pre_workTime.getSignTime();//允许打卡时间 + pre_lsSignTime = pre_lsSignTime != null ? pre_lsSignTime : new ArrayList<>(); + } + WorkTimeEntity next_workTime = new KQWorkTime().getWorkTime(userId, nextDate); + List next_lsSignTime = new ArrayList<>(); + + if (next_workTime != null) { + next_lsSignTime = next_workTime.getSignTime();//允许打卡时间 + next_lsSignTime = next_lsSignTime != null ? next_lsSignTime : new ArrayList<>(); + } + + List lsCheckInfo = new KQFormatSignData().getNonWorkSignInfo(userId,preDate,kqDate,pre_lsSignTime,next_lsSignTime); + + for (int j = 0; lsCheckInfo != null && j < lsCheckInfo.size(); j++) { + Map checkInfo = (Map) lsCheckInfo.get(j); + String signStatus = Util.null2String(checkInfo.get("signStatus")); + String signId = Util.null2String(checkInfo.get("signId")); + String signDate = Util.null2String(checkInfo.get("signDate")); + String signTime = Util.null2String(checkInfo.get("signTime")); + if (checkInfo.get("signType").equals("1")) {//签到 + signInId = signId; + signInDate = signDate; + signInTime = signTime; + } else if (checkInfo.get("signType").equals("2")) {//签退 + signOutId = signId; + signOutDate = signDate; + signOutTime = signTime; + } + } + + if (workFlowInfo.get(dateKey) != null) { + workFlow = (List) workFlowInfo.get(dateKey); + } + + for (int j = 0; workFlow != null && j < workFlow.size(); j++) { + Map data = (Map) workFlow.get(j); + String flowType = Util.null2String(data.get("flowtype")); + String newLeaveType = Util.null2String(data.get("newleavetype")); + beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(data.get("begintime"))); + endIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(data.get("endtime"))); + if(flowType.equals(FlowReportTypeEnum.EVECTION.getFlowType())){ + Arrays.fill(dayMins, beginIdx, endIdx, 7);//出差抵扣时段标识 7 + }else if(flowType.equals(FlowReportTypeEnum.OUT.getFlowType())){ + Arrays.fill(dayMins, beginIdx, endIdx, 8);//公出抵扣时段标识 8 + }else if(flowType.equalsIgnoreCase(FlowReportTypeEnum.LEAVE.getFlowType())){ + if (endIdx > beginIdx) { + Arrays.fill(dayMins, beginIdx, endIdx, 5);//流程抵扣时段标识 5 + int tmpBeginIdx = beginIdx; + int tmpEndIdx = endIdx; + Integer val = 0; + if(leaveInfo.get(newLeaveType)==null){ + leaveInfo.put(newLeaveType,val); + }else{ + val = (Integer) leaveInfo.get(newLeaveType); + } + if(tmpEndIdx>tmpBeginIdx){ + leaveInfo.put(newLeaveType,val+(tmpEndIdx-tmpBeginIdx)); + } + } + }else{ + if (endIdx > beginIdx) { + Arrays.fill(dayMins, beginIdx, endIdx, 99);//异常流程抵扣时段标识99 + } + } + } + + for (int j = 0; j < 2880; j++) { + switch (dayMins[j]) { + case 5: + leaveMins++; + break; + case 7: + evectionMins++; + break; + case 8: + outMins++; + break; + case 99: + otherMins++; + break; + default: + break; + } + } + + nonlsParam.add(userId); + nonlsParam.add(kqDate); + nonlsParam.add(workTime.getGroupId()); + nonlsParam.add(0); + nonlsParam.add(signInDate); + nonlsParam.add(signInTime); + nonlsParam.add(signInId.length() == 0 ? null : signInId); + nonlsParam.add(signOutDate); + nonlsParam.add(signOutTime); + nonlsParam.add(signOutId.length() == 0 ? null : signOutId); + nonlsParam.add(leaveMins); + nonlsParam.add(JSONObject.toJSONString(leaveInfo)); + nonlsParam.add(evectionMins); + nonlsParam.add(outMins); + } +}