diff --git a/src/com/engine/kq/bean/KqLockAttenda.java b/src/com/engine/kq/bean/KqLockAttenda.java new file mode 100644 index 0000000..2eb52c6 --- /dev/null +++ b/src/com/engine/kq/bean/KqLockAttenda.java @@ -0,0 +1,74 @@ +package com.engine.kq.bean; + +/** + * 排班制考勤组----排班设置权限(数据存储在建模表中) + */ +public class KqLockAttenda { + private String LOCK_COM; + + private String LOCK_SUBCOM; + + private String LOCK_DEPT; + + private String LOCK_RESOURCE; + + private String LOCK_FROMDATE; + private String LOCK_TODATE; + private String LOCK_LOCK; + + public String getLOCK_COM() { + return LOCK_COM; + } + + public void setLOCK_COM(String LOCK_COM) { + this.LOCK_COM = LOCK_COM; + } + + public String getLOCK_SUBCOM() { + return LOCK_SUBCOM; + } + + public void setLOCK_SUBCOM(String LOCK_SUBCOM) { + this.LOCK_SUBCOM = LOCK_SUBCOM; + } + + public String getLOCK_DEPT() { + return LOCK_DEPT; + } + + public void setLOCK_DEPT(String LOCK_DEPT) { + this.LOCK_DEPT = LOCK_DEPT; + } + + public String getLOCK_RESOURCE() { + return LOCK_RESOURCE; + } + + public void setLOCK_RESOURCE(String LOCK_RESOURCE) { + this.LOCK_RESOURCE = LOCK_RESOURCE; + } + + public String getLOCK_FROMDATE() { + return LOCK_FROMDATE; + } + + public void setLOCK_FROMDATE(String LOCK_FROMDATE) { + this.LOCK_FROMDATE = LOCK_FROMDATE; + } + + public String getLOCK_TODATE() { + return LOCK_TODATE; + } + + public void setLOCK_TODATE(String LOCK_TODATE) { + this.LOCK_TODATE = LOCK_TODATE; + } + + public String getLOCK_LOCK() { + return LOCK_LOCK; + } + + public void setLOCK_LOCK(String LOCK_LOCK) { + this.LOCK_LOCK = LOCK_LOCK; + } +} diff --git a/src/com/engine/kq/biz/KQFormatData.java b/src/com/engine/kq/biz/KQFormatData.java new file mode 100644 index 0000000..4123c64 --- /dev/null +++ b/src/com/engine/kq/biz/KQFormatData.java @@ -0,0 +1,1705 @@ +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.jucailin.genid.IdGenerator; +import com.engine.kq.log.KQLog; +import com.engine.kq.util.KQLockAttendaUtil; +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.lang3.StringUtils; +import weaver.common.DateUtil; +import weaver.conn.BatchRecordSet; +import weaver.conn.RecordSet; +import weaver.file.Prop; +import weaver.formmode.setup.ModeRightInfo; +import weaver.general.BaseBean; +import weaver.general.InitServer; +import weaver.general.Util; +import weaver.hrm.company.DepartmentComInfo; +import weaver.hrm.resource.ResourceComInfo; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +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<>(); + + private static final String LOCK_DEGREE = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_DEGREE")); + + public Map formatKqDateByLock(String userId, String kqDate, int formatType) { + Map resultMap = new HashMap<>(); + + //-1: 其他; 11:右键重新计算考勤数据; 12: 考勤自动和手动同步;13:钉钉同步或者导入; 14:云桥考勤同步 15: 考勤导入;16:排班更新 + //17:考勤流程;18testkq.jsp直接触发的;19:考勤设置升级;20:计划任务执行。 + //①在途的考勤流程可以正常提交归档报表能统计,管理员干预归档的流程报表能统计。 + //②关账不影响考勤导入打卡数据,正常的打卡数据进入报表,导入、同步。 + //③其他操作报表更新控制不生效,比如重新计算考勤,自动计算考勤。 + +// if (LOCK_DEGREE.equals("0")&&new KQLockAttendaUtil().checkLockStatus(userId, kqDate)) { +// kqLog.info("锁定程度强控:人员考勤数据已被锁定,"+"userId:"+userId+":kqDate:"+kqDate+";formatType="+formatType); +// if(formatType==12||formatType==13||formatType==14||formatType==15||formatType==17){ +// return formatKqDate(userId, kqDate); +// } +// return resultMap; +// } + //最新确认逻辑:弱控只控制流程在锁定范围内不能提交,其他都可以重新计算考勤报表。 + return formatKqDate(userId, kqDate); + } + + /*** + * 该方法不允许直接调用 + * @param userId + * @param kqDate + * @return + */ + public Map formatKqDate(String userId, String kqDate) { + //考勤报表增加锁定功能:弱控 + //1、考勤流程控制,请假、出差、公出、补卡、加班、销假、考勤变更新建的流程不能提交,在途的流程可以正常提交归档报表能统计,管理员干预归档的流程报表能统计。 + //2、关账不影响考勤导入打卡数据,正常的打卡数据进入报表。 + //3、强控就是前2点锁定日期后也不能进入报表了 + List> lsParam = new ArrayList<>(); + boolean isKqReportHalfOpen = "1".equals(new KQSettingsComInfo().getMain_val("kq_report_half")); + //非工作日处理 + List nonlsParam = null; + Map resultMap = new HashMap<>(); + BatchRecordSet bRs = new BatchRecordSet(); + 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; + } + // 强控 + if (LOCK_DEGREE.equals("1")&&new KQLockAttendaUtil().checkLockStatus(userId, kqDate)) { + kqLog.info("锁定程度强控:人员考勤数据已被锁定,"+"userId:"+userId+":kqDate:"+kqDate); + return resultMap; + } + String uuid = UUID.randomUUID().toString(); + KQFormatFreeData kqFormatFreeData = new KQFormatFreeData(); + KQWorkTime kqWorkTime = new KQWorkTime(); + kqWorkTime.setIsFormat(true); + String kqDateNext = DateUtil.addDate(kqDate, 1); + + 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 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 != null && workTime.getWorkMins() == 0 && workTime.getNonWorkShift() != 1)) { + 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,day_type,create_time,update_time,id,flowinfo)values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + rs.executeUpdate(sql, nonlsParam); + + Long id = IdGenerator.generate(); + String baseField = ""; + if ("mysql".equalsIgnoreCase(rs.getDBType())){ + baseField = "sysdate(),sysdate(),"+id; + }else if ("oracle".equalsIgnoreCase(rs.getDBType())){ + baseField = "SYSDATE,SYSDATE,"+id; + }else if ("postgresql".equalsIgnoreCase(rs.getDBType())){ + baseField = "now(),now(),"+id; + }else{ + baseField = "GETDATE(),GETDATE(),"+id; + } + 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,create_time,update_time,id)" + + " 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,"; +// if(isKqReportHalfOpen) { +// sql+=" sum((on_absenteeismmins+off_absenteeismmins)) as absenteeism,sum(absenteeismmins) as absenteeismmins,"; +// } else { + sql+=" sum(case when absenteeismmins> 0 then 1 else 0 end) as absenteeism,sum(absenteeismmins) as absenteeismmins,"; +// } + sql+=" 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," +baseField+ + " 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 KQFormatBiz().getDefinedField(); + String definedField = ""; + String definedParam = ""; + String definedParamSum = ""; + String convertAttendDay = workTime != null ? Util.null2s(workTime.getConvertAttendDay(),"1.0") : "1.0"; + 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) { + if (rs.getDBType().equals("postgresql")) { + 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+"":"")+",day_type,create_time,update_time,id,flowinfo,on_absenteeismmins,off_absenteeismmins) " + + " values(?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?"+(definedField.length()>0?","+definedParam+"":"")+",?,?::timestamp,?::timestamp,?,?,?,?)"; + + }else{ + 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+"":"")+",day_type,create_time,update_time,id,flowinfo,on_absenteeismmins,off_absenteeismmins) " + + " values(?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?"+(definedField.length()>0?","+definedParam+"":"")+",?,?,?,?,?,?,?)"; + } + for (int i = 0; i < lsParam.size(); i++) { + List param = lsParam.get(i); + boolean isok = rs.executeUpdate(sql, param); + kqLog.info("插入记录:userId:"+userId+":kqDate:"+kqDate+":param:"+JSON.toJSONString(param)+":isok:"+isok+"::uuid::"+uuid); + } + String attendancedaysF = " (cast(sum(attendanceMins)AS decimal(10, 2))*"+Util.getDoubleValue(convertAttendDay)+")/sum(workmins) as attendancedays, sum(attendanceMins) as attendanceMins, "; + String workF = " case when sum(workmins)>0 then "+convertAttendDay+" end as workdays, sum(workmins) as workmins,"; + String belateminsF = " sum(case when belatemins> 0 then 1 else 0 end) as belate,sum(belatemins) as belatemins,"; + String graveBeLateMinsF = " sum(case when graveBeLateMins> 0 then 1 else 0 end) as graveBeLate,sum(graveBeLateMins) as graveBeLateMins,"; + String leaveearlyminsF = " sum(case when leaveearlymins> 0 then 1 else 0 end) as leaveearly,sum(leaveearlymins) as leaveearlymins,"; + String graveLeaveEarlyMinsF = " sum(case when graveLeaveEarlyMins> 0 then 1 else 0 end) as graveLeaveEarly,sum(graveLeaveEarlyMins) as graveLeaveEarlyMins, "; + String absenteeismminsF = " sum(case when absenteeismmins> 0 then 1 else 0 end) as absenteeism,sum(absenteeismmins) as absenteeismmins, "; + String forgotcheckminsF = " sum(case when forgotcheckmins> 0 then 1 else 0 end) as forgotcheck,sum(forgotcheckmins) as forgotcheckmins,"; + String forgotbeginworkcheckminsF = " sum(case when forgotbeginworkcheckmins> 0 then 1 else 0 end) as forgotbeginworkcheck,sum(forgotbeginworkcheckmins) as forgotbeginworkcheckmins "; + String signF = " cast(sum(signmins)AS decimal(10, 2))/sum(workmins) as signdays, sum(signmins) as signmins,"; + String onoffAbsenteeismminsF= " sum(case when on_absenteeismmins> 0 then 1 else 0 end) as on_absenteeismmins,sum(case when off_absenteeismmins> 0 then 1 else 0 end) as off_absenteeismmins "; + if(1 == workTime.getNonWorkShift()){ + attendancedaysF = " 0 as attendancedays, 0 as attendanceMins, "; + workF = " 0 as workdays, 0 as workmins,"; + belateminsF = " 0 as belate,0 as belatemins,"; + graveBeLateMinsF = " 0 as graveBeLate,0 as graveBeLateMins,"; + leaveearlyminsF = " 0 as leaveearly,0 as leaveearlymins,"; + graveLeaveEarlyMinsF = " 0 as graveLeaveEarly,0 as graveLeaveEarlyMins, "; + absenteeismminsF = " 0 as absenteeism,0 as absenteeismmins,"; + forgotcheckminsF = " 0 as forgotcheck,0 as forgotcheckmins,"; + forgotbeginworkcheckminsF = " 0 as forgotbeginworkcheck,0 as forgotbeginworkcheckmins "; + signF = " 0 as signdays, 0 as signmins,"; + onoffAbsenteeismminsF = " 0 as on_absenteeismmins, 0 as off_absenteeismmins "; + } + + Long id = IdGenerator.generate(); + String baseField = ""; + if ("mysql".equalsIgnoreCase(rs.getDBType())){ + baseField = " now(),now(),"+id; + }else if ("oracle".equalsIgnoreCase(rs.getDBType())){ + baseField = " sysdate,sysdate,"+id; + }else if ("postgresql".equalsIgnoreCase(rs.getDBType())){ + baseField = " now(),now(),"+id; + }else{ + baseField = " getdate(),getdate(),"+id; + } + + 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+"":"")+",create_time,update_time,id,on_absenteeismmins,off_absenteeismmins) " + + " select a.resourceid,kqdate,b.subcompanyid1,b.departmentid,b.jobtitle,groupid,serialid," + + workF + + attendancedaysF + + signF + + belateminsF + + graveBeLateMinsF + + leaveearlyminsF + + graveLeaveEarlyMinsF + + absenteeismminsF + + forgotcheckminsF+ + " sum(leaveMins) as leaveMins," + + " sum(evectionMins) as evectionMins,sum(outMins) as outMins, " + + forgotbeginworkcheckminsF + + (definedField.length()>0?","+definedParamSum+"":"")+","+baseField+","+onoffAbsenteeismminsF+ + " 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); + } + } + + BaseBean bb = new BaseBean(); + String serialid = Util.null2String(workTime.getSerialId()); + //节假日天数 + String jjrts = "0"; + //正常工作天数 + String zcgzts = "0"; + KQHolidaySetComInfo holidaySetComInfo = new KQHolidaySetComInfo(); + String changeTypeNew = holidaySetComInfo.getChangeType("1", kqDate); + if("1".equals(changeTypeNew)){ + jjrts = "1"; + } + + if(DateUtil.getWeek(kqDate) != 6 && DateUtil.getWeek(kqDate) != 7){ + //不为周六周日 + if(!"1".equals(changeTypeNew) && !"3".equals(changeTypeNew)){ + //不为节假日和休息日 + zcgzts = "1"; + } + } + + + //夜班次数 + String ybcs = "0"; + if(checkYb(serialid)){ + //是夜班 + String sjcqsc = geSjcqsc(userId,kqDate,rs); + if(Double.parseDouble(sjcqsc)<240){ + ybcs = "0"; + }else if(Double.parseDouble(sjcqsc)>=240 && Double.parseDouble(sjcqsc)<480){ + ybcs = "0.5"; + }else { + ybcs = "1"; + } + } + //成本中心 + String cbzx = getCbzx(userId,kqDate,rs); + + if(StringUtils.isBlank(cbzx)){ + //没找到成本中心,取当前部门 + ResourceComInfo resourceComInfo = new ResourceComInfo(); + DepartmentComInfo departmentComInfo = new DepartmentComInfo(); + String deptId = resourceComInfo.getDepartmentID(userId); + cbzx = departmentComInfo.getDepartmentname(deptId); + } + + bb.writeLog("usr:"+userId+"KqD"+kqDate+"ybcs:"+ybcs+"zcgzts:"+zcgzts+"jjrts:"+jjrts+"cbzx:"+cbzx); + Integer checkM = checkKqModeInfo(userId,kqDate,rs); + if(checkM>0){ + bb.writeLog("已存在更新"); + //更新台账数据 + updateKqModeInfo(rs,userId,kqDate,ybcs,zcgzts,jjrts,cbzx); + }else{ + //格式化数据台账生成-二开 + createKqModeInfo(rs,userId,kqDate,ybcs,zcgzts,jjrts,cbzx); + } + }catch (Exception e) { + kqLog.info("考勤重算报错:KQFormatData.Exception:"); + StringWriter errorsWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(errorsWriter)); + kqLog.info(errorsWriter.toString()); + } + return resultMap; + } + + public List> format(String userId, String kqDate, WorkTimeEntity workTime, + Map workFlowInfo, String uuid) { + List> lsParam = new ArrayList<>(); + List params = null; + HashMap middleMap = new HashMap<>(); + try { + Timestamp date = new Timestamp(System.currentTimeMillis()); + KQSettingsComInfo kqSettingsComInfo = new KQSettingsComInfo(); + String nosign_is_absent = Util.null2String(kqSettingsComInfo.getMain_val("nosign_is_absent"),"1"); + //默认不开启半天的特殊规则,如果开启,那么只要是半天的单位,并且申请考勤流程半天,那么实际出勤就是0.5天,不考虑迟到和早退。当天旷工的情况需要考虑,即如果另外半天是旷工,那么实际出勤自然也是0 + String is_half = Util.null2String(kqSettingsComInfo.getMain_val("is_half"),"0"); + String early_one_mins = Util.null2String(kqSettingsComInfo.getMain_val("early_one_mins"),"0"); + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + 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(); + boolean oneSign = false; + List lsSignTime = new ArrayList<>(); + List lsWorkTime = new ArrayList<>(); + List lsRestTime = new ArrayList<>(); + List workFlow = null; + int restShift = 0; + int signoutOnlyoff = 0; + if (workTime != null) { + lsSignTime = workTime.getSignTime();//允许打卡时间 + lsWorkTime = workTime.getWorkTime();//工作时间 + lsRestTime = workTime.getRestTime();//休息时段时间 + oneSign = lsWorkTime!=null&&lsWorkTime.size()==1; + restShift = workTime.getNonWorkShift(); + signoutOnlyoff = workTime.getSignoutOnlyoff(); + } + kqLog.info("format in >>>>>userId" + userId + "kqDate==" + kqDate+":restShift:"+restShift+":signoutOnlyoff:"+signoutOnlyoff+":hostIps:"+hostIps+":uuid::"+uuid); + + if(this.writeLog) { + logInfo.put("signoutOnlyoff",signoutOnlyoff); + } + + + int[] dayMins = new int[2880];//一天所有分钟数 + Arrays.fill(dayMins, -1); + + //处理半天班次冲销问题 + int[] dayMinsNew = new int[2880];//一天所有分钟数 + Arrays.fill(dayMinsNew, -1); + int workMins4leave = 0; + int middleMins = 0;//班次的半天时长 + int middleMins_final = 0;//班次的半天时长 + int shiftNums = lsWorkTime == null ? 0 : lsWorkTime.size(); + + // 一天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; + } + + 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(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()); + int beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(restBeginTime); + int endIdx = kqTimesArrayComInfo.getArrayindexByTimes(restEndTime); + if (endIdx > beginIdx) { + Arrays.fill(dayMinsNew, beginIdx, endIdx, -11);//休息时间 + } + } + } + int all_rest_cnt = kqTimesArrayComInfo.getCnt(dayMinsNew, workBeginIdx, workEndIdx, -11); + if(all_rest_cnt >= 0){ + workMins = workMins-(all_rest_cnt); + } + } + workMins4leave += workMins; + } + middleMins = workMins4leave>0?workMins4leave/2:0; + middleMins_final = middleMins; + int split_time_index = middleMins_final; // 半天时间index,用于考勤汇总报表区分上下午 + if(oneSign) { + List halfWorkIndex = workTime.getHalfWorkIndex(); + if(halfWorkIndex != null && !halfWorkIndex.isEmpty()) { + int[] halfWorkIndexs = halfWorkIndex.get(0); + split_time_index = halfWorkIndexs[1];//半天的时间 + } + } + + String signOutTimeNew = ""; + 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; + + Arrays.fill(dayMins, workBeginIdx, workEndIdx, 1);//工作时段标识 1 + + int beginIdx = 0; + int endIdx = 0; + int checkIn = 0; + int checkOut = 0; + String signInId = ""; + String signInDate = ""; + String signInTime = ""; + String signOutId = ""; + String signOutDate = ""; + 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 on_absenteeismMins = 0; + int off_absenteeismMins = 0; + int leaveMins = 0;//请假时长 + Map leaveInfo = new HashMap<>();//请假信息 + Map otherinfo = new HashMap<>();//存一些用得到的信息 + Map flowinfo = 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 (1 != restShift) { + if(oneSign){ + //个性化设置只支持一天一次上下班 + ShiftInfoBean shiftInfoBean = new ShiftInfoBean(); + shiftInfoBean.setSplitDate(kqDate); + shiftInfoBean.setShiftRuleMap(workTime.getShiftRuleInfo()); + shiftInfoBean.setSignTime(lsSignTime); + shiftInfoBean.setWorkTime(lsWorkTime); + shiftInfoBean.setSignoutOnlyoff(signoutOnlyoff); + 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(this.writeLog) { + logInfo.put("before.workEndIdx",workEndIdx); + } + 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); + } + } + if(this.writeLog) { + logInfo.put("after.workEndIdx",workEndIdx); + } + + List lsCheckInfo = new KQFormatSignData().getSignInfo(userId,signTimeScope,workTimeScope,kqDate,preDate,nextDate,kqTimesArrayComInfo,hostIps,uuid,shiftCount,shiftI,signoutOnlyoff); + 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")) {//签到 + boolean checkCf = true; + if(i== 1 && lsWorkTime.size() == 2){ + //二段班次的,第二笔卡签到判断是否和第一笔卡签退一样,一样的话不计签到 + if(signOutTimeNew.equals(signTime)){ + //不计签到 + checkCf = false; + } + } + + if(checkCf){ + checkIn++; + //如果流程抵扣存在,打卡时长也存在,那么相互比较得到出勤时长和打卡时长 暂不这样处理,还是按照漏签的逻辑来处理 + if(signTime.length() > 0){ + signInTimeIndx4Sign = kqTimesArrayComInfo.getArrayindexByTimes(signTime); + } + signInId = signId; + signInDate = signDate; + signInTime = signTime; + signInTimeIndx = kqTimesArrayComInfo.getArrayindexByTimes(signInTime); + if(this.writeLog) { + logInfo.put(j+">>>signInTime",signInTime); + logInfo.put(j+">>>signInTimeIndx",signInTimeIndx); + logInfo.put(j+">>>kqDate",kqDate+"|"+signDate); + } + 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; + } + } + } 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(this.writeLog) { + logInfo.put(j+".signTime",signDate+"|"+signTime); + logInfo.put(j+".beginIdx",beginIdx); + logInfo.put(j+".workEndIdx",workEndIdx); + } + 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); + } + + boolean isHandle1 = false; + boolean isHandle2 = false; + List flowList = Lists.newArrayList(); + 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 durationrule = Util.null2String(data.get("durationrule")); + String ishalf = Util.null2String(data.get("ishalf")); + double duration = Util.getDoubleValue(Util.null2String(data.get("duration"))); + if(flowType.equalsIgnoreCase(FlowReportTypeEnum.LEAVE.getFlowType())){ + duration = Util.getDoubleValue(Util.null2String(data.get(newLeaveType))); + } + String serial = Util.null2String(data.get("serial")); + String requestId = Util.null2String(data.get("requestId")); + String begintime = Util.null2String(data.get("begintime")); + String endtime = Util.null2String(data.get("endtime")); + beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(begintime); + endIdx = kqTimesArrayComInfo.getArrayindexByTimes(endtime); + if (beginIdx >= endIdx) { + continue; + } + Map flowMap = Maps.newHashMap(); + flowMap.put("newLeaveType", newLeaveType); + flowMap.put("begintime", begintime); + flowMap.put("endtime", endtime); + List> flowMapList = Lists.newArrayList(); + if(flowinfo.containsKey(flowType)){ + List> tmpFlowMapList = (List>) flowinfo.get(flowType); + tmpFlowMapList.add(flowMap); + }else{ + flowMapList.add(flowMap); + flowinfo.put(flowType, flowMapList); + } + int middleIdx = (workBeginIdx+workEndIdx)/2;//工作时段标识 1 + + if(flowType.equals(FlowReportTypeEnum.EVECTION.getFlowType())){ + if("2".equals(durationrule) && "true".equals(ishalf)){ + isHandle2 = true; + } + Arrays.fill(dayMins, beginIdx, endIdx, 7);//出差抵扣时段标识 7 + }else if(flowType.equals(FlowReportTypeEnum.OUT.getFlowType())){ + if("2".equals(durationrule) && "true".equals(ishalf)){ + isHandle2 = true; + } + Arrays.fill(dayMins, beginIdx, endIdx, 8);//公出抵扣时段标识 8 + }else if(flowType.equalsIgnoreCase(FlowReportTypeEnum.LEAVE.getFlowType())){ + if("2".equals(durationrule) && "true".equals(ishalf)){ + isHandle1 = true; + } + 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: + if(j 0){ + //如果没有个性化的旷工,那就是全天旷工 + isAmAbsent = true; + } + if(off_absenteeismMins > 0) { + isPmAbsent = true; + } + + 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); + kqShiftRuleEntity.setAMAbsent(isAmAbsent); + kqShiftRuleEntity.setPMAbsent(isPmAbsent); + kqShiftRuleEntity.setNosign_is_absent(nosign_is_absent); + kqShiftRuleEntity.setSignInTime(signInTime); + kqShiftRuleEntity.setSignOutTime(signOutTime); + kqShiftRuleEntity.setEarly_one_mins(early_one_mins); + kqLog.info("人性化规则处理前数据" + JSONObject.toJSONString(kqShiftRuleEntity)); + if(this.writeLog) { + logInfo.put(""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005301,weaver.general.ThreadVarLanguage.getLang())+"",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); + } + + if(i==0 && lsWorkTime.size() == 2){ + //两个班段的第一个班段不用走人性化规则 + new BaseBean().writeLog("二开不走人性化规则"); + signOutTimeNew = signOutTime; + }else{ + beLateMins = kqShiftRuleEntity.getBelatemins(); + graveBeLateMins = kqShiftRuleEntity.getGravebelatemins(); + leaveEarlyMins = kqShiftRuleEntity.getLeaveearlymins(); + graveLeaveEarlyMins = kqShiftRuleEntity.getGraveleaveearlymins(); + absenteeismMins = kqShiftRuleEntity.getAbsenteeismmins(); + forgotCheckMins = kqShiftRuleEntity.getForgotcheckmins(); + forgotBeginWorkCheckMins = kqShiftRuleEntity.getForgotBeginWorkCheckMins(); + int shiftOn_absenteeismMins = Util.getIntValue(kqShiftRuleEntity.getOn_absenteeismMins()); + if(shiftOn_absenteeismMins > 0) { + on_absenteeismMins = shiftOn_absenteeismMins; + } + int shiftOff_absenteeismMins = Util.getIntValue(kqShiftRuleEntity.getOff_absenteeismMins()); + if(shiftOff_absenteeismMins > 0) { + off_absenteeismMins = shiftOff_absenteeismMins; + } + } + + + + 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 KQFormatBiz().needCal(workBeginDate,workBeginTime); + if(beforeBegin) {//还未到上班时间,不用计算任何状态 + kqLog.writeLog("还未到上班时间,不用计算任何状态"); + beLateMins = 0; + graveBeLateMins = 0; + leaveEarlyMins = 0; + graveLeaveEarlyMins = 0; + absenteeismMins = 0; + forgotCheckMins = 0; + forgotBeginWorkCheckMins = 0; + isAmAbsent = false; + isPmAbsent = false; + on_absenteeismMins = 0; + off_absenteeismMins = 0; + }else if(!new KQFormatBiz().needCal(workEndDate,workEndTime)) {//还未到下班时间 + kqLog.writeLog("还未到上班时间"); + leaveEarlyMins = 0; + graveLeaveEarlyMins = 0; + forgotCheckMins = 0; + isPmAbsent = false; + off_absenteeismMins = 0; + } + + if (1 == restShift || workTime.getIsExclude()) {//休息日班次或者无需考勤人员没有异常状态 + beLateMins = 0; + graveBeLateMins = 0; + leaveEarlyMins = 0; + graveLeaveEarlyMins = 0; + absenteeismMins = 0; + forgotCheckMins = 0; + forgotBeginWorkCheckMins = 0; + isAmAbsent = false; + isPmAbsent = false; + on_absenteeismMins = 0; + off_absenteeismMins = 0; + } + if (1 == restShift) {//非工作日班次連打卡時長和出勤时长也不給了 + workMins = 0; + signMins = 0; + isAmAbsent = false; + isPmAbsent = false; + on_absenteeismMins = 0; + off_absenteeismMins = 0; + } + //允许下班不打卡 ,如果上班也没有打卡,那么算上班旷工0.5天 + if (isoffdutyfreecheck) { + if (checkIn == 0) {//(无签到),就会有上班漏签,如果有下班卡,那么上班漏签 + if(forgotBeginWorkCheckMins==0&&absenteeismMins>0){ + forgotBeginWorkCheckMins= absenteeismMins ; + } + } + absenteeismMins = 0; + forgotCheckMins = 0; + off_absenteeismMins = 0; + } + //允许上班不打卡,如果下班也没有打卡,那么算漏签 + if(isondutyfreecheck){ + if (checkOut == 0) {//(无签退) + if(forgotCheckMins==0&&absenteeismMins>0){ + forgotCheckMins= absenteeismMins ; + } + } + absenteeismMins = 0; + forgotBeginWorkCheckMins = 0; + on_absenteeismMins = 0; + } + if(isondutyfreecheck&&isoffdutyfreecheck){ + absenteeismMins = 0; + forgotCheckMins = 0; + forgotBeginWorkCheckMins = 0; + on_absenteeismMins = 0; + off_absenteeismMins = 0; + } + //计算实际出勤时间(出差公出算出勤)=应出勤-旷工-请假-迟到-早退 + attendanceMins = workMins - absenteeismMins-leaveMins-beLateMins-graveBeLateMins-leaveEarlyMins-graveLeaveEarlyMins; + + if(this.writeLog) { + logInfo.put("is_half",is_half); + logInfo.put("shiftNums",shiftNums); + logInfo.put("isHandle2",isHandle2); + logInfo.put("isHandle1",isHandle1); + logInfo.put("workMins"+i,workMins); + logInfo.put("absenteeismMins"+i,absenteeismMins); + logInfo.put("middleMins"+i,middleMins); + } + //如果开启半天特殊处理的,请假是需要扣除0.5天 + //说明没有打卡的情况,因为有打卡肯定是有迟到、早退、漏签这些异常的,不考虑迟到算旷工,早退算旷工的情况 + //只处理1天1次,和1天2次的情况,因为1天3次的中间点可能在第二段,需要考虑有没有打卡,以及有打卡第三次是否需要处理等情况,和上下午半天的概念不太适用 + if("1".equals(is_half)){ + boolean absentFlag_1 = false;//请假, + boolean absentFlag_2 = false;//公出或出差 + if(isHandle1 || isHandle2){ + if(absenteeismMins>0 && !(beLateMins >0||graveBeLateMins > 0||leaveEarlyMins > 0||graveLeaveEarlyMins > 0||forgotCheckMins > 0||forgotBeginWorkCheckMins >0)){ + if(isHandle1){ + absentFlag_1 = true;//可以理解为是1天3次和1天1次的情况,因为1天2次的情况,如果有旷工,那么另外半天才是有请假, + } + if(isHandle2){ + absentFlag_2 = true;//可以理解为是1天3次和1天1次的情况,因为1天2次的情况,如果有旷工,那么另外半天才是有公出或者出差 + } + } + } + if(this.writeLog) { + logInfo.put("tmp_absenteeismMins"+i,absenteeismMins); + logInfo.put("absentFlag_1"+i,absentFlag_1); + logInfo.put("absentFlag_2"+i,absentFlag_2); + } + /*1次---上午3小时,下午5小时 + 上午公出,下午旷工 + 上午公出,下午打卡 + 上午旷工,下午公出 + 上午打卡,下午公出 + + 2次---上午3小时,下午5小时 + 上午公出,下午旷工--需处理实际出勤、旷工时长 + 上午公出,下午打卡--需处理实际出勤 + 上午旷工,下午公出--需处理实际出勤、旷工时长 + 上午打卡,下午公出--需处理实际出勤 + */ + if(isHandle2){ + if(shiftNums ==1){ + absenteeismMins = absentFlag_2?middleMins_final:0; + attendanceMins = workMins - absenteeismMins; + }else if(shiftNums == 2){ + if(workMins>middleMins_final && middleMins_final>0){ + absenteeismMins = (absenteeismMins > middleMins_final)?middleMins_final:((absentFlag_2||outMins>0||evectionMins>0)?Math.abs(workMins - middleMins_final):0); + absenteeismMins = (i==1 && middleMap.get("attendanceMins0")>0)?(absentFlag_2?absenteeismMins:0):absenteeismMins;//上午打卡3小时,下午公出5小时,下午的就不要显示旷工1小时了 + } + attendanceMins = workMins - absenteeismMins; + } + } + if(this.writeLog) { + logInfo.put("absenteeismMins_1"+i,absenteeismMins); + logInfo.put("attendanceMins_1"+i,attendanceMins); + } + + /*1次---上午3小时,下午5小时 + 上午请假,下午旷工 + 上午请假,下午打卡 + 上午旷工,下午请假 + 上午打卡,下午请假 + + 2次---上午3小时,下午5小时 + 上午请假,下午旷工--需处理实际出勤、旷工时长 + 上午请假,下午打卡--需处理实际出勤 + 上午旷工,下午请假--需处理实际出勤、旷工时长 + 上午打卡,下午请假--需处理实际出勤 + */ + + if(isHandle1){ + if(shiftNums == 1){ + absenteeismMins = absentFlag_1?middleMins_final:0; + attendanceMins = workMins - absenteeismMins - (leaveMins>0?middleMins_final:(absentFlag_1?(workMins - middleMins_final):0)); + }else if(shiftNums == 2){ + if(workMins>middleMins_final && middleMins_final>0){ + absenteeismMins = (absenteeismMins > middleMins_final)?middleMins_final:((absentFlag_1||leaveMins>0)?Math.abs(workMins - middleMins_final):0); + absenteeismMins = (i==1 && middleMap.get("attendanceMins0")>0)?0:absenteeismMins;//上午打卡3小时,下午请假5小时,下午的就不要显示旷工1小时了 + } + attendanceMins = workMins - absenteeismMins - (leaveMins>0?middleMins_final:(absentFlag_1?Math.abs(workMins - middleMins_final):0)); + attendanceMins = attendanceMins>middleMins_final?middleMins_final:attendanceMins;//上午请假3小时,下午打卡5小时 + }else if(shiftNums == 3){//比如一天三次上下班,那么中间点在第二次上下班区间 +// if(workMins>middleMins && middleMins>0){ +// absenteeismMins = (absenteeismMins > middleMins_final)?middleMins_final:((absentFlag_1||leaveMins>0)?(workMins - middleMins):0); +// absenteeismMins = (i>=1 && middleMap.get("attendanceMins"+(i-1))>0)?0:absenteeismMins; +// } +// attendanceMins = workMins - absenteeismMins - (leaveMins>0?middleMins_final:(absentFlag_1?Math.abs(workMins - middleMins_final):0)); +// attendanceMins = attendanceMins>middleMins_final?middleMins_final:attendanceMins;//上午请假3小时,下午打卡5小时 +// if(workMins < middleMins){//客户可能是一天2次,或者3次,那么workmins有可能是小于半天的请假时间 +// middleMins = middleMins-workMins; +// }else { +// middleMins = 0; +// } + } + if(absenteeismMins > middleMins_final){//客户可能是一天2次,或者3次 + absenteeismMins = middleMins_final; + } + } + middleMap.put("attendanceMins"+i,attendanceMins); + middleMap.put("absenteeismMins"+i,absenteeismMins); + middleMap.put("workMins"+i,workMins); + middleMap.put("leaveMins"+i,leaveMins); + middleMap.put("outMins"+i,outMins); + middleMap.put("evectionMins"+i,evectionMins); + middleMap.put("isHandle1"+i,isHandle1?1:0); + middleMap.put("isHandle2"+i,isHandle2?1:0); + middleMap.put("absentFlag_1"+i,absentFlag_1?1:0);//1表示有旷工 + middleMap.put("absentFlag_2"+i,absentFlag_2?1:0);//1表示有旷工 + } + + // 如果没有开启"漏签是否算实际出勤"开关,则漏签不算实际出勤时长 + if("0".equals(nosign_is_absent)) { + attendanceMins = attendanceMins-forgotCheckMins-forgotBeginWorkCheckMins; + } + if(beforeBegin || attendanceMins < 0) {//还未到上班时间,不用计算任何状体 + attendanceMins = 0; + } + + /** + * 汇总报表的日历显示是有旷工就不显示漏签了,如果这里还统计漏签,张总表示日历也需要修改,改不动了 + * 在处理完实际出勤之后,将漏签还原 + */ + String nosign_ishandle = Util.null2String(kqShiftRuleEntity.getNosign_ishandle()); + if("1".equals(nosign_ishandle)){ + forgotCheckMins = 0; + }else if("2".equals(nosign_ishandle)){ + forgotCheckMins = 0; + forgotBeginWorkCheckMins = 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()); + + 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); + params.add(kqTimesArrayComInfo.turn48to24Time(ori_workBeginTime)); + params.add(workEndDate); + params.add(kqTimesArrayComInfo.turn48to24Time(ori_workEndTime)); + params.add(workMins); + params.add(signInDate); + 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); + params.add(attendanceMins); + 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 KQFormatBiz().getDefinedField(); + String[] definedFields = Util.splitString(Util.null2String(definedFieldInfo.get("definedField")),","); + KQReportFieldComInfo kqReportFieldComInfo = new 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)); + Long id = IdGenerator.generate(); + params.add(workTime.getDayType()); + params.add(date); + params.add(date); + params.add(id); + params.add(JSONObject.toJSONString(flowinfo)); +// if(isAmAbsent){ +// params.add(1); +// }else { +// params.add(0); +// } +// if(isPmAbsent){ +// params.add(1); +// }else { +// params.add(0); +// } + params.add(on_absenteeismMins); + params.add(off_absenteeismMins); + lsParam.add(params); + } + } catch (Exception e) { + kqLog.info("考勤格式化生成数据报错:KQFormatData:"); + StringWriter errorsWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(errorsWriter)); + kqLog.info(errorsWriter.toString()); + } + return lsParam; + } + + public void setWriteLog(boolean writeLog) { + this.writeLog = writeLog; + } + + public Map getLogInfo() { + return logInfo; + } + + public void formatDateByKQDate(String kqdate) { + KQFormatBiz kqFormatBiz = new KQFormatBiz(); + kqFormatBiz.formatDateByKQDate(kqdate); + } + + public void formatDateByGroupId(String groupid, String kqdate) { + KQFormatBiz kqFormatBiz = new KQFormatBiz(); + kqFormatBiz.formatDateByGroupId(groupid, kqdate); + } + + public void formatDate(String resourceid, String kqdate) { + KQFormatBiz kqFormatBiz = new KQFormatBiz(); + kqFormatBiz.formatDate(resourceid, kqdate); + } + + public void delFormatData(String resourceid, String kqdate) { + 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 flowinfo = new HashMap<>();//流程信息 + 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; + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + + String preDate = DateUtil.addDate(kqDate, -1);//上一天日期 + String nextDate = DateUtil.addDate(kqDate, 1);//下一天日期 + WorkTimeEntity pre_workTime = new 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")); + String begintime = Util.null2String(data.get("begintime")); + String endtime = Util.null2String(data.get("endtime")); + beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(begintime); + endIdx = kqTimesArrayComInfo.getArrayindexByTimes(endtime); + + if (beginIdx > endIdx) { + continue; + } + Map flowMap = Maps.newHashMap(); + flowMap.put("newLeaveType", newLeaveType); + flowMap.put("begintime", begintime); + flowMap.put("endtime", endtime); + List> flowMapList = Lists.newArrayList(); + if(flowinfo.containsKey(flowType)){ + List> tmpFlowMapList = (List>) flowinfo.get(flowType); + tmpFlowMapList.add(flowMap); + }else{ + flowMapList.add(flowMap); + flowinfo.put(flowType, flowMapList); + } + 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); + nonlsParam.add(workTime.getDayType()); + Timestamp date = new Timestamp(System.currentTimeMillis()); + Long id = IdGenerator.generate(); + nonlsParam.add(date); + nonlsParam.add(date); + nonlsParam.add(id); + nonlsParam.add(JSONObject.toJSONString(flowinfo)); + } + + /** + * 获取实际出勤时长 + * @param userId + * @param date + * @return + */ + public static String geSjcqsc(String userId,String date,RecordSet rs){ + String sjtsMins = ""; + String sql = " select attendancemins from kq_format_total where resourceid ="+userId+" and kqdate = '"+date+"'"; + rs.executeQuery(sql); + if(rs.next()){ + sjtsMins = Util.null2String(rs.getString("attendancemins")); + Integer mins = Integer.valueOf(sjtsMins); + if(mins>480){ + sjtsMins = "480"; + } + } + return sjtsMins; + } + + /** + * 判断当天是否有考勤数据 + * @param userId + * @param date + * @return + */ + private static Integer checkKqModeInfo(String userId,String date,RecordSet rs){ + String sql = "select count(*) as cont from uf_gshsj where xm = "+userId+" and rq = '"+date+"'"; + rs.execute(sql); + Integer check = 0; + if(rs.next()){ + check = Util.getIntValue(rs.getString("cont")); + } + return check; + } + + /** + * 获取成本中心 + * @param userId + * @param date + * @return + */ + public static String getCbzx(String userId,String date,RecordSet rs){ + String cbzx = ""; + String sql = "select (select departmentmark from hrmdepartment where id = szcbzx) as cbzx from uf_kqcbzxgs where xm = "+userId+" and szrq = '"+date+"'"; + rs.executeQuery(sql); + if(rs.next()){ + cbzx = Util.null2String(rs.getString("cbzx")); + } + return cbzx; + } + + /** + * 更新台账数据 + */ + public static void updateKqModeInfo(RecordSet rs,String userId,String date,String ybgs,String zcgztian,String fdjjrts,String cbzx){ + String sql = "update uf_gshsj set ybgs=?,zcgztian=?,fdjjrts=?,cbzx=? where xm=? and rq=?"; + boolean isdelete2 = rs.executeUpdate(sql,ybgs,zcgztian,fdjjrts,cbzx,userId,date); + } + + + + /** + * 格式化生成台账数据 + * @param userId + * @param date + */ + public static void createKqModeInfo(RecordSet rs,String userId,String date,String ybgs,String zcgztian,String fdjjrts,String cbzx){ + BaseBean bb = new BaseBean(); + bb.writeLog("createKqModeInfo == >userId:"+userId+" date:"+date); + //插入 + String idNew = ""; + int modeid = getFormModeIdByCubeName("uf_gshsj"); + SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss"); + String modedatacreatedate = sdfDate.format(new Date()); + String modedatacreatetime = sdfTime.format(new Date()); + String sqlMode = "insert into uf_gshsj (xm,rq,ybgs,zcgztian,fdjjrts,cbzx,FORMMODEID,MODEDATACREATER,MODEDATACREATERTYPE,MODEDATACREATEDATE,MODEDATACREATETIME) \n" + + "values (?,?,?,?,?,?,?,?,?,?,?)"; + rs.executeUpdate(sqlMode, userId,date,ybgs,zcgztian,fdjjrts,cbzx,modeid, userId, "0", modedatacreatedate, modedatacreatetime); + + RecordSet findNew = new RecordSet(); + String sqlFindnew ="select Id from uf_gshsj where xm = "+userId+" and rq = '"+date+"' order by" + + " modedatacreatedate desc,modedatacreatetime desc"; + findNew.execute(sqlFindnew); + bb.writeLog("findSqlNew:"+sqlFindnew); + if (findNew.next()){ + idNew = Util.null2String(findNew.getString("id")); + } + bb.writeLog("idNew:"+idNew); + // 权限重构 + int dataId = 0; + if(StringUtils.isNotBlank(idNew)){ + dataId = Integer.valueOf(idNew); + } + + ModeRightInfo modeRightInfo = new ModeRightInfo(); + modeRightInfo.editModeDataShare(Integer.valueOf(userId), modeid, dataId); + } + + + /** + * 根据建模表名获取formModeId + * + * @param cubeName 建模表明 + * @return int formModeId + */ + private static int getFormModeIdByCubeName(String cubeName) { + RecordSet rs = new RecordSet(); + rs.executeQuery("select t1.id from modeinfo t1\n" + + " left join workflow_bill t2\n" + + " on t1.formid=t2.id\n" + + " where t2.tablename='" + cubeName + "'"); + rs.next(); + return rs.getInt("id"); + } + + /** + * 判断是否是夜班 + * @param serialid + * @return + */ + private static Boolean checkYb(String serialid){ + RecordSet rs = new RecordSet(); + String sql = "select * from kq_ShiftManagement where id = "+serialid+" and serial like '%夜班%'"; + rs.execute(sql); + Boolean check = false; + if (rs.getCounts()>0){ + check = true; + } + return check; + } +} diff --git a/src/com/engine/kq/biz/KQFormatSignData.java b/src/com/engine/kq/biz/KQFormatSignData.java new file mode 100644 index 0000000..9f8627a --- /dev/null +++ b/src/com/engine/kq/biz/KQFormatSignData.java @@ -0,0 +1,860 @@ +package com.engine.kq.biz; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.engine.kq.cmd.attendanceButton.ButtonStatusEnum; +import com.engine.kq.entity.TimeScopeEntity; +import com.engine.kq.entity.TimeSignScopeEntity; +import com.engine.kq.entity.WorkTimeEntity; +import com.engine.kq.log.KQLog; +import com.engine.kq.util.UtilKQ; +import com.engine.kq.wfset.util.KQSignUtil; +import com.google.common.collect.Lists; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import weaver.common.DateUtil; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.general.Util; + +import java.util.*; + +/** + * 获取班次打卡数据 + */ +public class KQFormatSignData extends BaseBean { + private KQLog kqLog = new KQLog(); + + public List getSignInfo(String userId, TimeScopeEntity signTimeScope, + TimeScopeEntity workTimeScope, String kqDate, String preDate, + String nextDate, KQTimesArrayComInfo kqTimesArrayComInfo) { + return getSignInfo(userId, signTimeScope, workTimeScope, kqDate, preDate, nextDate, kqTimesArrayComInfo, + Lists.newArrayList(), ""); + } + + public List getSignInfo(String userId, TimeScopeEntity signTimeScope, + TimeScopeEntity workTimeScope, String kqDate, String preDate, + String nextDate, KQTimesArrayComInfo kqTimesArrayComInfo, ArrayList hostIps, String uuid) { + return getSignInfo(userId, signTimeScope, workTimeScope, kqDate, preDate, nextDate, kqTimesArrayComInfo, hostIps, uuid, 0, 0); + } + + public List getSignInfo(String userId, TimeScopeEntity signTimeScope, + TimeScopeEntity workTimeScope, String kqDate, String preDate, + String nextDate, KQTimesArrayComInfo kqTimesArrayComInfo, ArrayList hostIps, String uuid, int shiftCount, int shiftI) { + return getSignInfo(userId, signTimeScope, workTimeScope, kqDate, preDate, nextDate, kqTimesArrayComInfo, hostIps, uuid, shiftCount, shiftI, 0); + } + + /*** + * 获取班次打卡数据 + * @param userId + * @param signTimeScope + * @param workTimeScope + * @param kqDate + * @param preDate + * @param nextDate + * @param kqTimesArrayComInfo + * @return + */ + public List getSignInfo(String userId, TimeScopeEntity signTimeScope, + TimeScopeEntity workTimeScope, String kqDate, String preDate, + String nextDate, KQTimesArrayComInfo kqTimesArrayComInfo, ArrayList hostIps, String uuid, int shiftCount, int shiftI, int signoutOnlyoff) { + kqLog.info("in getSignInfo ::userId" + userId + "kqDate==" + kqDate + ":hostIps:" + hostIps + ":uuid::" + uuid + " in "); + List lsCheckInfo = new ArrayList<>(); + String count4NoonStartDateTime = ""; + String count4NoonEndDateTime = ""; + try { + Map checkInfo = null; + String base_sql = ""; + RecordSet rs = new RecordSet(); + String dbtype = rs.getDBType(); + + //获取工作上下班时间 + String workBeginDateTime = workTimeScope.getBeginTimeAcross() ? nextDate : kqDate; + workBeginDateTime += " " + kqTimesArrayComInfo.turn48to24Time(workTimeScope.getBeginTime()) + ":00"; + kqLog.info("in getSignInfo ::userId" + userId + "kqDate==" + kqDate + ":hostIps:" + hostIps + ":uuid::" + uuid + "::workBeginDateTime::" + workBeginDateTime); + + //获取工作上下班时间 + String workEndDateTime = workTimeScope.getEndTimeAcross() ? nextDate : kqDate; + workEndDateTime += " " + kqTimesArrayComInfo.turn48to24Time(workTimeScope.getEndTime()) + ":00"; + kqLog.info("in getSignInfo ::userId" + userId + "kqDate==" + kqDate + ":hostIps:" + hostIps + ":uuid::" + uuid + "::workEndDateTime::" + workEndDateTime); + + Map flow_deduct_card_map = getflowDeductCardSql(userId, kqDate, workTimeScope.getBeginTime(), workTimeScope.getEndTime()); + + kqLog.info("in getSignInfo ::userId" + userId + "kqDate==" + kqDate + ":hostIps:" + hostIps + ":uuid::" + uuid + "::flow_deduct_card_map::" + flow_deduct_card_map); + kqLog.info("in getSignInfo ::userId" + userId + "kqDate==" + kqDate + ":hostIps:" + hostIps + ":uuid::" + uuid + "::signTimeScope::" + JSON.toJSONString(signTimeScope)); + + List> sqlConditions = getCanSignInfo(signTimeScope, kqDate, preDate, nextDate, kqTimesArrayComInfo, workTimeScope, shiftCount, shiftI, signoutOnlyoff); + base_sql = signSignSql(rs); + new KQLog().info("sqlConditions:(userId:" + userId + ":base_sql" + base_sql + ":::userId" + userId + "kqDate==" + kqDate + ":hostIps:" + hostIps + ":uuid::" + uuid + "::flow_deduct_card_map::" + flow_deduct_card_map + "::sqlConditions::" + JSONObject.toJSONString(sqlConditions)); + if (sqlConditions != null && !sqlConditions.isEmpty()) { + kqLog.info("userId="+userId + ",kqDate="+kqDate+":sqlConditions:"+ JSONObject.toJSONString(sqlConditions)); + if(shiftCount == 2) { + String fieldName = ""; + if(shiftI == 0) { + fieldName = "signEndDateTime"; + /* + 1、设置了上班结束打卡或者下班开始打卡,那么sqlConditions的如下 + sqlConditions:[ + {"signEndDateTime":"2024-08-28 10:00:59","signBeginDateTime":"2024-08-28 06:00:00","type":"signin"}, + {"signEndDateTime":"2024-08-28 12:40:59","signBeginDateTime":"2024-08-28 11:40:00","type":"signoff"} + ] + 2、没有设置上班结束或者下班开始,那么sqlConditions的如下 + sqlConditions:[ + {"signEndDateTime":"2024-08-28 12:40:59","signBeginDateTime":"2024-08-28 06:00:00"} + ] + */ + Map sqlMap = sqlConditions.get((null!=sqlConditions && sqlConditions.size()>0)?(sqlConditions.size()-1):0); + String type = Util.null2String(sqlMap.get("type")); + if(type.length() > 0){ + if("signoff".equalsIgnoreCase(type)){ + count4NoonEndDateTime = Util.null2String(sqlMap.get(fieldName)); + if (sqlConditions.size() >= 2) { + sqlMap = sqlConditions.get(1); + count4NoonStartDateTime = workEndDateTime; + count4NoonEndDateTime = Util.null2String(sqlMap.get("signEndDateTime")); + } + }else if("signin".equalsIgnoreCase(type)){ + //暂不处理 + } + }else{ + count4NoonStartDateTime = workEndDateTime; + count4NoonEndDateTime = Util.null2String(sqlMap.get(fieldName)); + } + } else if(shiftI == 1) { + fieldName = "signBeginDateTime"; + Map sqlMap = sqlConditions.get(0); + String type = Util.null2String(sqlMap.get("type")); + if(type.length() > 0){ + if("signoff".equalsIgnoreCase(type)){ + //暂不处理 + }else if("signin".equalsIgnoreCase(type)){ + count4NoonStartDateTime = Util.null2String(sqlMap.get("signBeginDateTime")); + if (count4NoonStartDateTime.length() == 19) { + count4NoonStartDateTime = count4NoonStartDateTime.substring(0, 17) + "00"; + } + count4NoonEndDateTime = workBeginDateTime; + } + }else{ + count4NoonStartDateTime = Util.null2String(sqlMap.get(fieldName)); + if (count4NoonStartDateTime.length() == 19) { + count4NoonStartDateTime = count4NoonStartDateTime.substring(0, 17) + "00"; + } + count4NoonEndDateTime = workBeginDateTime; + } + } +// Map sqlMap = sqlConditions.get(0); +// count4NoonStartDateTime = Util.null2String(sqlMap.get(fieldName)); +// if (count4NoonStartDateTime.length() == 19) { +// count4NoonStartDateTime = count4NoonStartDateTime.substring(0, 17) + "00"; +// } +// sqlMap = sqlConditions.get(0); +// count4NoonEndDateTime = Util.null2String(sqlMap.get(fieldName)); +// if (sqlConditions.size() >= 2) { +// sqlMap = sqlConditions.get(1); +// count4NoonEndDateTime = Util.null2String(sqlMap.get(fieldName)); +// } + } + + boolean hasSignIn = false; + for (Map sqlMap : sqlConditions) { + String sql = ""; + String orderSql = ""; + int idx = 0; + String signBeginDateTime = Util.null2String(sqlMap.get("signBeginDateTime")); + String signEndDateTime = Util.null2String(sqlMap.get("signEndDateTime")); + String type = Util.null2String(sqlMap.get("type")); + String signoutOnlyoff_flag = Util.null2String(sqlMap.get("signoutOnlyoff")); + if (type.length() > 0) { + if ("signoff".equalsIgnoreCase(type)) { + orderSql = " order by signdate desc, signtime desc "; + } else if ("signin".equalsIgnoreCase(type)) { + orderSql = " order by signdate asc, signtime asc "; + } + if ("oracle".equalsIgnoreCase(dbtype)) { + sql = "select * from (" + base_sql + " " + orderSql + ") a where rownum=1"; + } else if ("mysql".equalsIgnoreCase(dbtype)) { + sql = "select * from (" + base_sql + " " + orderSql + ") a limit 0,1"; + } else if ("postgresql".equalsIgnoreCase(dbtype)) { + sql = "select * from (" + base_sql + " " + orderSql + ") a limit 1 offset 0"; + } else if ("sqlserver".equalsIgnoreCase(dbtype)) { + sql = "select top 1 * from (" + base_sql + ") a " + " " + orderSql; + } else { + sql = "select * from (" + base_sql + " " + orderSql + ") a where rownum=1"; + } + } else { + orderSql = " order by signdate asc, signtime asc "; + sql = base_sql + " " + orderSql; + } + rs.executeQuery(sql, userId, signBeginDateTime, signEndDateTime); + new KQLog().info("getSignInfo:(userId:" + userId + ":signBeginDateTime:" + + signBeginDateTime + ":signEndDateTime:" + signEndDateTime + "):sql" + sql + ":counts:" + rs.getCounts() + ":::userId" + userId + "kqDate==" + kqDate + ":hostIps:" + hostIps + ":uuid::" + uuid + "::flow_deduct_card_map::" + flow_deduct_card_map); + while (rs.next()) { + String signId = Util.null2String(rs.getString("id")); + String signdate = Util.null2String(rs.getString("signdate")); + String signtime = Util.null2String(rs.getString("signtime")); + + checkInfo = new HashMap<>(); + checkInfo.put("signId", signId);//签到签退标识 + checkInfo.put("signDate", signdate);//签到签退日期 + checkInfo.put("signTime", signtime);//签到签退时间 + String signDateTime = signdate + " " + signtime; + idx++; + if (type.length() > 0) { + if ("signin".equalsIgnoreCase(type)) { + checkInfo.put("signType", "1"); + if (workBeginDateTime.length() > 0) { + checkInfo.put("signStatus", UtilKQ.getSignStatus("1", signDateTime, workBeginDateTime)); + } + if (!Util.null2String(checkInfo.get("signStatus")).equalsIgnoreCase(ButtonStatusEnum.NORMAL.getStatusCode())) { + if (flow_deduct_card_map.containsKey("signin")) { + String deduct_signintime = Util.null2String(flow_deduct_card_map.get("signin")); + if (deduct_signintime.length() > 0) { + signDateTime = signdate + " " + deduct_signintime; + checkInfo.put("deduct_signintime", deduct_signintime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", UtilKQ.getSignStatus("1", signDateTime, workBeginDateTime)); + } + } + } + lsCheckInfo.add(checkInfo); + } else { + checkInfo.put("signType", "2"); + if (workEndDateTime.length() > 0) { + checkInfo.put("signStatus", UtilKQ.getSignStatus("2", signDateTime, workEndDateTime)); + } + if (!Util.null2String(checkInfo.get("signStatus")).equalsIgnoreCase(ButtonStatusEnum.NORMAL.getStatusCode())) { + if (flow_deduct_card_map.containsKey("signoff")) { + String deduct_signofftime = Util.null2String(flow_deduct_card_map.get("signoff")); + if (deduct_signofftime.length() > 0) { + signDateTime = signdate + " " + deduct_signofftime; + checkInfo.put("deduct_signofftime", deduct_signofftime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", UtilKQ.getSignStatus("2", signDateTime, workEndDateTime)); + } + } + } + lsCheckInfo.add(checkInfo); + } + } else { + if (signoutOnlyoff_flag.length()>0) { + if("signin".equals(signoutOnlyoff_flag) && idx == 1){ + checkInfo.put("signType", "1"); + if (workBeginDateTime.length() > 0) { + checkInfo.put("signStatus", UtilKQ.getSignStatus("1", signDateTime, workBeginDateTime)); + } + if (!Util.null2String(checkInfo.get("signStatus")).equalsIgnoreCase(ButtonStatusEnum.NORMAL.getStatusCode())) { + if (flow_deduct_card_map.containsKey("signin")) { + String deduct_signintime = Util.null2String(flow_deduct_card_map.get("signin")); + if (deduct_signintime.length() > 0) { + signDateTime = signdate + " " + deduct_signintime; + checkInfo.put("deduct_signintime", deduct_signintime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", UtilKQ.getSignStatus("1", signDateTime, workBeginDateTime)); + } + } + } + lsCheckInfo.add(checkInfo); + hasSignIn = true; + } + if("signoff".equals(signoutOnlyoff_flag)){ + if ((hasSignIn && idx == rs.getCounts() && idx > 1) || (!hasSignIn && idx == rs.getCounts())) {//第一条可能是签到卡需要处理下,否则可能会导致一条上班卡同时识别为上班卡和下班卡 + checkInfo.put("signType", "2"); + if (workEndDateTime.length() > 0) { + checkInfo.put("signStatus", UtilKQ.getSignStatus("2", signDateTime, workEndDateTime)); + } + if (!Util.null2String(checkInfo.get("signStatus")).equalsIgnoreCase(ButtonStatusEnum.NORMAL.getStatusCode())) { + if (flow_deduct_card_map.containsKey("signoff")) { + String deduct_signofftime = Util.null2String(flow_deduct_card_map.get("signoff")); + if (deduct_signofftime.length() > 0) { + signDateTime = signdate + " " + deduct_signofftime; + checkInfo.put("deduct_signofftime", deduct_signofftime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", UtilKQ.getSignStatus("2", signDateTime, workEndDateTime)); + } + } + } + lsCheckInfo.add(checkInfo); + } + } + } else { + if (idx == 1) {//第一条算签到 + checkInfo.put("signType", "1"); + if (workBeginDateTime.length() > 0) { + checkInfo.put("signStatus", UtilKQ.getSignStatus("1", signDateTime, workBeginDateTime)); + } + if (!Util.null2String(checkInfo.get("signStatus")).equalsIgnoreCase(ButtonStatusEnum.NORMAL.getStatusCode())) { + if (flow_deduct_card_map.containsKey("signin")) { + String deduct_signintime = Util.null2String(flow_deduct_card_map.get("signin")); + if (deduct_signintime.length() > 0) { + signDateTime = signdate + " " + deduct_signintime; + checkInfo.put("deduct_signintime", deduct_signintime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", UtilKQ.getSignStatus("1", signDateTime, workBeginDateTime)); + } + } + } + lsCheckInfo.add(checkInfo); + hasSignIn = true; + } else if (idx == rs.getCounts()) {//最后一条算签退 + checkInfo.put("signType", "2"); + if (workEndDateTime.length() > 0) { + checkInfo.put("signStatus", UtilKQ.getSignStatus("2", signDateTime, workEndDateTime)); + } + if (!Util.null2String(checkInfo.get("signStatus")).equalsIgnoreCase(ButtonStatusEnum.NORMAL.getStatusCode())) { + if (flow_deduct_card_map.containsKey("signoff")) { + String deduct_signofftime = Util.null2String(flow_deduct_card_map.get("signoff")); + if (deduct_signofftime.length() > 0) { + signDateTime = signdate + " " + deduct_signofftime; + checkInfo.put("deduct_signofftime", deduct_signofftime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", UtilKQ.getSignStatus("2", signDateTime, workEndDateTime)); + } + } + } + lsCheckInfo.add(checkInfo); + } + } + } + } + } + } + //如果签到,签退不成对,流程抵扣异常存在,那么需要判断下是不是可以补足 + if (lsCheckInfo.size() < 2 && !flow_deduct_card_map.isEmpty()) { + if (lsCheckInfo.isEmpty()) { + if (flow_deduct_card_map.containsKey("signin")) { + String deduct_signintime = Util.null2String(flow_deduct_card_map.get("signin")); + if (deduct_signintime.length() > 0) { + checkInfo = new HashMap<>(); + String[] workBeginDateTimes = workBeginDateTime.split(" "); + String tmp_workBeginDate = workBeginDateTimes[0]; + String tmp_workBeginTime = workBeginDateTimes[1]; + checkInfo.put("signType", "1"); + checkInfo.put("signDate", tmp_workBeginDate);//签到签退日期 + checkInfo.put("signTime", "");//签到签退时间 + checkInfo.put("deduct_signintime", tmp_workBeginTime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", ButtonStatusEnum.NORMAL.getStatusCode()); + lsCheckInfo.add(checkInfo); + } + } + if (flow_deduct_card_map.containsKey("signoff")) { + String deduct_signofftime = Util.null2String(flow_deduct_card_map.get("signoff")); + if (deduct_signofftime.length() > 0) { + checkInfo = new HashMap<>(); + String[] workEndDateTimes = workEndDateTime.split(" "); + String tmp_workEndDate = workEndDateTimes[0]; + String tmp_workEndTime = workEndDateTimes[1]; + checkInfo.put("signType", "2"); + checkInfo.put("signDate", tmp_workEndDate);//签到签退日期 + checkInfo.put("signTime", "");//签到签退时间 + checkInfo.put("deduct_signofftime", tmp_workEndTime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", ButtonStatusEnum.NORMAL.getStatusCode()); + lsCheckInfo.add(checkInfo); + } + } + } else { + Map checkCardMap = (Map) lsCheckInfo.get(0); + if (!checkCardMap.isEmpty()) { + String signType = Util.null2String(checkCardMap.get("signType")); + if ("1".equalsIgnoreCase(signType)) { + //如果签到数据有了,检测下是不是有签退的流程抵扣打卡 + if (flow_deduct_card_map.containsKey("signoff")) { + String deduct_signofftime = Util.null2String(flow_deduct_card_map.get("signoff")); + if (deduct_signofftime.length() > 0) { + checkInfo = new HashMap<>(); + String[] workEndDateTimes = workEndDateTime.split(" "); + String tmp_workEndDate = workEndDateTimes[0]; + String tmp_workEndTime = workEndDateTimes[1]; + checkInfo.put("signType", "2"); + checkInfo.put("signDate", tmp_workEndDate);//签到签退日期 + checkInfo.put("signTime", "");//签到签退时间 + checkInfo.put("deduct_signofftime", tmp_workEndTime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", ButtonStatusEnum.NORMAL.getStatusCode()); + lsCheckInfo.add(checkInfo); + } + } + } else { + if (flow_deduct_card_map.containsKey("signin")) { + String deduct_signintime = Util.null2String(flow_deduct_card_map.get("signin")); + if (deduct_signintime.length() > 0) { + checkInfo = new HashMap<>(); + String[] workBeginDateTimes = workBeginDateTime.split(" "); + String tmp_workBeginDate = workBeginDateTimes[0]; + String tmp_workBeginTime = workBeginDateTimes[1]; + checkInfo.put("signType", "1"); + checkInfo.put("signDate", tmp_workBeginDate);//签到签退日期 + checkInfo.put("signTime", "");//签到签退时间 + checkInfo.put("deduct_signintime", tmp_workBeginTime);//流程抵扣作为打卡时间 + checkInfo.put("signStatus", ButtonStatusEnum.NORMAL.getStatusCode()); + lsCheckInfo.add(checkInfo); + } + } + } + } + } + } + // 上午的签退取中间时段的第一次打卡 + if (shiftCount == 2 && shiftI == 0) { + String noonSignTimeSql = KQSignUtil.buildSignSql(count4NoonStartDateTime, count4NoonEndDateTime); + String baseSql = "select * from hrmschedulesign where 1=1 and isInCom='1' and userid=" + userId + " "; + String sql = baseSql; + sql += " and " + noonSignTimeSql + " order by signdate, signtime"; + rs.executeQuery(sql); + if (rs.next()) { + String signId = Util.null2String(rs.getString("id")); + String signDate = Util.null2String(rs.getString("signdate")); + String signTime = Util.null2String(rs.getString("signtime")); + String signDateTime = signDate + " " + signTime; + for (int j = 0; lsCheckInfo != null && j < lsCheckInfo.size(); j++) { + Map checkInfoInner = (Map) lsCheckInfo.get(j); + if (checkInfoInner.get("signType").equals("2")) {//签退 + String signDateInner = Util.null2String(checkInfoInner.get("signDate")); + String signTimeInner = Util.null2String(checkInfoInner.get("signTime")); + String deduct_signofftime = Util.null2String(checkInfoInner.get("deduct_signofftime")); + if (!"".equals(signTimeInner)) { + String signDateTimeInner = signDateInner + " " + signTimeInner; + if (signDateTime.compareTo(signDateTimeInner) < 0) { + checkInfoInner.put("signId", signId);//签到签退标识 + checkInfoInner.put("signType", "2"); + checkInfoInner.put("signDate", signDateInner);//签到签退日期 + checkInfoInner.put("signTime", signTime);//签到签退时间 + checkInfoInner.put("deduct_signofftime", deduct_signofftime);//流程抵扣作为打卡时间 + checkInfoInner.put("signStatus", ButtonStatusEnum.NORMAL.getStatusCode()); + } + } + } + } + } + } else if (shiftCount == 2 && shiftI == 1) { // 下午的签到取中间时段的第二次打卡 + String noonSignTimeSql = KQSignUtil.buildSignSql(count4NoonStartDateTime, count4NoonEndDateTime); + String baseSql = "select * from hrmschedulesign where 1=1 and isInCom='1' and userid=" + userId + " "; + String sql = baseSql; + sql += " and " + noonSignTimeSql + " order by signdate, signtime"; + rs.executeQuery(sql); + int count = 0; + int counts = rs.getCounts(); + if (counts == 1) { + // lsCheckInfo.clear(); + } + while (rs.next()) { + if (count == 0) { + count++; + continue; + } + String signId = Util.null2String(rs.getString("id")); + String signTime = Util.null2String(rs.getString("signtime")); + for (int j = 0; lsCheckInfo != null && j < lsCheckInfo.size(); j++) { + Map checkInfoInner = (Map) lsCheckInfo.get(j); + if (checkInfoInner.get("signType").equals("1")) {//签退 + String signDateInner = Util.null2String(checkInfoInner.get("signDate")); + String signTimeInner = Util.null2String(checkInfoInner.get("signTime")); + String deduct_signofftime = Util.null2String(checkInfoInner.get("deduct_signofftime")); + checkInfoInner.put("signId", signId);//签到签退标识 + checkInfoInner.put("signType", "1"); + checkInfoInner.put("signDate", signDateInner);//签到签退日期 + checkInfoInner.put("signTime", signTime);//签到签退时间 + checkInfoInner.put("deduct_signofftime", deduct_signofftime);//流程抵扣作为打卡时间 + checkInfoInner.put("signStatus", ButtonStatusEnum.NORMAL.getStatusCode()); + } + } + break; + } + } + } catch (Exception e) { + + kqLog.info("报表错:getSignInfo:"); + StringWriter errorsWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(errorsWriter)); + kqLog.info(errorsWriter.toString()); + } + + //writeLog(sql,userId +"=="+ signBeginDateTime+"=="+signEndDateTime); + return lsCheckInfo; + } + + /** + * 根据上下班时间获取到是否有流程抵扣打卡的数据 + * + * @param userId + * @param kqDate + * @param workBeginDateTime + * @param workEndDateTime + */ + public Map getflowDeductCardSql(String userId, String kqDate, String workBeginDateTime, String workEndDateTime) { + Map flow_deduct_card_map = new HashMap<>(); + RecordSet rs = new RecordSet(); + String flow_deduct_card_sql = "select * from kq_flow_deduct_card where 1=1 and (isclear is null or isclear<>1) "; + if (userId.length() > 0) { + flow_deduct_card_sql += " and resourceid=" + userId; + } + if (kqDate.length() > 0) { + flow_deduct_card_sql += " and belongDate='" + kqDate + "'"; + } + if (workBeginDateTime.length() > 0) { + flow_deduct_card_sql += " and workBeginTime='" + workBeginDateTime + "'"; + } + if (workEndDateTime.length() > 0) { + flow_deduct_card_sql += " and workEndTime='" + workEndDateTime + "'"; + } + rs.executeQuery(flow_deduct_card_sql); + while (rs.next()) { + String signtype = rs.getString("signtype"); + if ("1".equalsIgnoreCase(signtype)) { + flow_deduct_card_map.put("signin", workBeginDateTime); + } + if ("2".equalsIgnoreCase(signtype)) { + flow_deduct_card_map.put("signoff", workEndDateTime); + } + } + return flow_deduct_card_map; + } + + /** + * 根据打卡的范围生成上班,下班数据获取的sql + * + * @param signTimeScope + * @param kqDate + * @param preDate + * @param nextDate + * @param kqTimesArrayComInfo + * @return + */ + public List> getCanSignInfo(TimeScopeEntity signTimeScope, String kqDate, String preDate, String nextDate, KQTimesArrayComInfo kqTimesArrayComInfo) { + return getCanSignInfo(signTimeScope, kqDate, preDate, nextDate, kqTimesArrayComInfo, null); + } + + public List> getCanSignInfo(TimeScopeEntity signTimeScope, String kqDate, String preDate, String nextDate, KQTimesArrayComInfo kqTimesArrayComInfo,TimeScopeEntity workTimeScope,int signoutOnlyoff) { + return getCanSignInfo(signTimeScope, kqDate, preDate, nextDate, kqTimesArrayComInfo, workTimeScope, 0, 0, signoutOnlyoff); + } + + public List> getCanSignInfo(TimeScopeEntity signTimeScope, String kqDate, String preDate, String nextDate, KQTimesArrayComInfo kqTimesArrayComInfo, TimeScopeEntity workTimeScope) { + return getCanSignInfo(signTimeScope, kqDate, preDate, nextDate, kqTimesArrayComInfo, workTimeScope, 0, 0); + } + + public List> getCanSignInfo(TimeScopeEntity signTimeScope, String kqDate, String preDate, String nextDate, KQTimesArrayComInfo kqTimesArrayComInfo, TimeScopeEntity workTimeScope, int shiftCount, int shiftI) { + return getCanSignInfo(signTimeScope, kqDate, preDate, nextDate, kqTimesArrayComInfo, workTimeScope, shiftCount, shiftI, 0); + } + + public List> getCanSignInfo(TimeScopeEntity signTimeScope, String kqDate, String preDate, String nextDate, KQTimesArrayComInfo kqTimesArrayComInfo, TimeScopeEntity workTimeScope, int shiftCount, int shiftI, int signoutOnlyoff) { + + List> sqlConditions = new ArrayList<>(); + Map conditionMap = new HashMap<>(); + + TimeSignScopeEntity timeSignScopeEntity = signTimeScope.getTimeSignScopeEntity(); + + String signBeginDateTime = ""; + String signEndDateTime = ""; + signBeginDateTime = signTimeScope.getBeginTimeAcross() ? nextDate : kqDate; + if (signTimeScope.isBeginTimePreAcross()) { + signBeginDateTime = preDate; + } + signBeginDateTime += " " + kqTimesArrayComInfo.turn48to24Time(signTimeScope.getBeginTime()) + ":00"; + + signEndDateTime = signTimeScope.getEndTimeAcross() ? nextDate : kqDate; + +// if (workTimeScope != null && workTimeScope.getEndTimeAcross() && signTimeScope.getEndTimeAcross() ) { +// if(workTimeScope.getEndTime().compareTo(signTimeScope.getEndTime())>=0){ +// signEndDateTime = DateUtil.addDate(kqDate, 2);//下下一天日期; +// } +// } + signEndDateTime += " " + kqTimesArrayComInfo.turn48to24Time(signTimeScope.getEndTime()) + ":59"; + + + if (timeSignScopeEntity == null) { + //没有设置 签到最晚时间和签退最早时间,比如是09:00-18:00,打卡范围是【08:00---19:00】 + if (signoutOnlyoff == 1 && workTimeScope != null) {//开启了下班后只能签退的按钮,那么考勤格式化的打卡数据查询范围也搞一下 + String signBeginDateEndTime = ""; + String signEndDateStartTime = ""; + String workEndTime = workTimeScope.getEndTime(); + boolean workEndTimeAcross = workTimeScope.getEndTimeAcross(); + + String workEndTimeNew = kqTimesArrayComInfo.getTimesByArrayindex(kqTimesArrayComInfo.getArrayindexByTimes(workEndTime) - 1);//17:59 + signBeginDateEndTime = workEndTimeAcross ? nextDate : kqDate; + signBeginDateEndTime += " " + kqTimesArrayComInfo.turn48to24Time(workEndTimeNew) + ":59";//17:59:59 + + conditionMap = new HashMap<>(); + conditionMap.put("signBeginDateTime", signBeginDateTime);//08:00:00 + conditionMap.put("signEndDateTime", signBeginDateEndTime);//17:59:59 +// conditionMap.put("type", "signin"); + conditionMap.put("signoutOnlyoff", "signin"); + sqlConditions.add(conditionMap); + + conditionMap = new HashMap<>(); + conditionMap.put("signBeginDateTime", signBeginDateTime);//08:00:00,这里为什么从上班开始打卡时间起算,因为存在上班有打卡,连续打卡的情况,那么需要将除上班卡之后的打卡都识别为下班卡 + conditionMap.put("signEndDateTime", signEndDateTime);//19:00:59 + //这里不能传type=signoff,否则上班打卡可能会同时识别为上班卡和下班卡 + conditionMap.put("signoutOnlyoff", "signoff"); + sqlConditions.add(conditionMap); + + } else {//走标准原逻辑 + conditionMap = new HashMap<>(); + conditionMap.put("signBeginDateTime", signBeginDateTime); + conditionMap.put("signEndDateTime", signEndDateTime); + sqlConditions.add(conditionMap); + } + + } else { + String beginTimeEnd = timeSignScopeEntity.getBeginTimeEnd(); + boolean beginTimeEndAcross = timeSignScopeEntity.isBeginTimeEndAcross(); + + String endTimeStart = timeSignScopeEntity.getEndTimeStart(); + boolean endTimeStartAcross = timeSignScopeEntity.isEndTimeStartAcross(); + + if (beginTimeEnd.length() > 0) { + //如果设置了 上班结束时间 + if (endTimeStart.length() > 0) { + //设置了下班开始时间 + String signBeginDateEndTime = ""; + String signEndDateStartTime = ""; + signBeginDateEndTime = beginTimeEndAcross ? nextDate : kqDate; + signBeginDateEndTime += " " + kqTimesArrayComInfo.turn48to24Time(beginTimeEnd) + ":59"; + + //张总表示设了打卡归属,以设置的为准,这个开关相当于不起作用,代码含泪注释 +// if(signoutOnlyoff == 1 && workTimeScope != null){//开启了下班后只能签退的按钮,那么考勤格式化的打卡数据查询范围也搞一下 +// String workEndTime = workTimeScope.getEndTime(); +// boolean workEndTimeAcross = workTimeScope.getEndTimeAcross(); +// signBeginDateEndTime = workEndTimeAcross ? nextDate : kqDate; +// signBeginDateEndTime+=" "+kqTimesArrayComInfo.turn48to24Time(workEndTime)+":59"; +// conditionMap = new HashMap<>(); +// conditionMap.put("signBeginDateTime", signBeginDateTime); +// conditionMap.put("signEndDateTime", signBeginDateEndTime); +// conditionMap.put("type", "signin"); +// sqlConditions.add(conditionMap); +// +// conditionMap = new HashMap<>(); +// conditionMap.put("signBeginDateTime", signBeginDateEndTime); +// conditionMap.put("signEndDateTime", signEndDateTime); +// conditionMap.put("type", "signoff"); +// sqlConditions.add(conditionMap); +// +// }else{ + conditionMap = new HashMap<>(); + conditionMap.put("signBeginDateTime", signBeginDateTime); + conditionMap.put("signEndDateTime", signBeginDateEndTime); + conditionMap.put("type", "signin"); + sqlConditions.add(conditionMap); + + signEndDateStartTime = endTimeStartAcross ? nextDate : kqDate; + signEndDateStartTime += " " + kqTimesArrayComInfo.turn48to24Time(endTimeStart) + ":00"; + + conditionMap = new HashMap<>(); + conditionMap.put("signBeginDateTime", signEndDateStartTime); + conditionMap.put("signEndDateTime", signEndDateTime); + conditionMap.put("type", "signoff"); + sqlConditions.add(conditionMap); +// } + } else { + //没有设置下班开始时间 + String signBeginDateEndTime = ""; + String signEndDateStartTime = ""; + signBeginDateEndTime = beginTimeEndAcross ? nextDate : kqDate; + signBeginDateEndTime += " " + kqTimesArrayComInfo.turn48to24Time(beginTimeEnd) + ":59"; + + conditionMap = new HashMap<>(); + conditionMap.put("signBeginDateTime", signBeginDateTime); + conditionMap.put("signEndDateTime", signBeginDateEndTime); + conditionMap.put("type", "signin"); + sqlConditions.add(conditionMap); + + //如果设置了上班结束时间,相当于下班开始时间也被限定了 + String endTimeByBeginTime = kqTimesArrayComInfo.getTimesByArrayindex(kqTimesArrayComInfo.getArrayindexByTimes(beginTimeEnd) + 1); + signEndDateStartTime = beginTimeEndAcross ? nextDate : kqDate; + signEndDateStartTime += " " + kqTimesArrayComInfo.turn48to24Time(endTimeByBeginTime) + ":00"; + + conditionMap = new HashMap<>(); + conditionMap.put("signBeginDateTime", signEndDateStartTime); + conditionMap.put("signEndDateTime", signEndDateTime); + conditionMap.put("type", "signoff"); + sqlConditions.add(conditionMap); + } + } else if (endTimeStart.length() > 0) { + //如果没有设置上班结束时间,设置了下班开始时间 + String signBeginDateEndTime = ""; + String signEndDateStartTime = ""; + + //如果设置了下班开始时间,相当于上班结束时间也被限定了 + String BeginTimeByendTime = kqTimesArrayComInfo.getTimesByArrayindex(kqTimesArrayComInfo.getArrayindexByTimes(endTimeStart) - 1); + signBeginDateEndTime = endTimeStartAcross ? nextDate : kqDate; + signBeginDateEndTime += " " + kqTimesArrayComInfo.turn48to24Time(BeginTimeByendTime) + ":59"; + + conditionMap = new HashMap<>(); + conditionMap.put("signBeginDateTime", signBeginDateTime); + conditionMap.put("signEndDateTime", signBeginDateEndTime); + conditionMap.put("type", "signin"); + sqlConditions.add(conditionMap); + + signEndDateStartTime = endTimeStartAcross ? nextDate : kqDate; + signEndDateStartTime += " " + kqTimesArrayComInfo.turn48to24Time(endTimeStart) + ":00"; + + conditionMap = new HashMap<>(); + conditionMap.put("signBeginDateTime", signEndDateStartTime); + conditionMap.put("signEndDateTime", signEndDateTime); + conditionMap.put("type", "signoff"); + sqlConditions.add(conditionMap); + } + } + return sqlConditions; + } + + public String signSignSql(RecordSet rs) { + String sql = ""; + if (rs.getDBType().equals("oracle")) { + sql = " select id,signdate,signtime from hrmschedulesign where isincom=1 and userid = ? and signdate||' '||signtime >= ? and signdate||' '||signtime <= ? " + + " "; + } else if ("sqlserver".equals(rs.getDBType())) { + sql = " select id,signdate,signtime from hrmschedulesign where isincom=1 and userid = ? and signdate + ' ' + signtime >= ? and signdate + ' ' + signtime <= ? " + + " "; + } else { + sql = " select id,signdate,signtime from hrmschedulesign where isincom=1 and userid = ? and concat(signdate,' ',signtime) >= ? and concat(signdate,' ',signtime) <= ? " + + " "; + } + return sql; + } + + public List getSignInfoForAll(String userId, String signBeginDateTime, String signEndDateTime, String workBeginDateTime, String workEndDateTime) { + List lsCheckInfo = new ArrayList<>(); + Map checkInfo = null; + String sql = ""; + RecordSet rs = new RecordSet(); + + int idx = 0; + if (rs.getDBType().equals("oracle")) { + sql = " select id,signdate,signtime from hrmschedulesign where isincom=1 and userid = ? and signdate||' '||signtime >= ? and signdate||' '||signtime <= ? " + + " order by signdate asc, signtime asc "; + } else if ("sqlserver".equals(rs.getDBType())) { + sql = " select id,signdate,signtime from hrmschedulesign where isincom=1 and userid = ? and signdate + ' ' + signtime >= ? and signdate + ' ' + signtime <= ? " + + " order by signdate asc, signtime asc "; + } else { + sql = " select id,signdate,signtime from hrmschedulesign where isincom=1 and userid = ? and concat(signdate,' ',signtime) >= ? and concat(signdate,' ',signtime) <= ? " + + " order by signdate asc, signtime asc "; + } + rs.executeQuery(sql, userId, signBeginDateTime, signEndDateTime); + //writeLog(sql,userId +"=="+ signBeginDateTime+"=="+signEndDateTime); + while (rs.next()) { + String signId = Util.null2String(rs.getString("id")); + String signdate = Util.null2String(rs.getString("signdate")); + String signtime = Util.null2String(rs.getString("signtime")); + + checkInfo = new HashMap<>(); + checkInfo.put("signId", signId);//签到签退标识 + checkInfo.put("signDate", signdate);//签到签退日期 + checkInfo.put("signTime", signtime);//签到签退时间 + String signDateTime = signdate + " " + signtime; + + idx++; + if (idx % 2 == 1) { + checkInfo.put("signType", "1"); + } else { + checkInfo.put("signType", "2"); + } + lsCheckInfo.add(checkInfo); + } + return lsCheckInfo; + } + + public List getNonWorkSignInfo(String userId, String preDate, String kqDate, + List pre_lsSignTime, + List next_lsSignTime) { + List lsCheckInfo = new ArrayList<>(); + Map checkInfo = null; + RecordSet rs = new RecordSet(); + String pre_Worktime4Today = ""; + if (!pre_lsSignTime.isEmpty()) { + TimeScopeEntity pre_signTimeScope = pre_lsSignTime.get(pre_lsSignTime.size() - 1); + if (pre_signTimeScope.getEndTimeAcross()) { + pre_Worktime4Today = pre_signTimeScope.getEndTime(); + } + } + String next_Worktime4Today = ""; + if (!next_lsSignTime.isEmpty()) { + TimeScopeEntity next_signTimeScope = next_lsSignTime.get(next_lsSignTime.size() - 1); + if (next_signTimeScope.isBeginTimePreAcross()) { + next_Worktime4Today = next_signTimeScope.getBeginTime(); + } + } + String sql = "select * from hrmschedulesign where userid=" + userId + " and signdate = '" + kqDate + "' "; + if (pre_Worktime4Today.length() > 0) { + if (pre_Worktime4Today.length() == 5) { + pre_Worktime4Today += ":59"; + } + sql += " and signtime > '" + pre_Worktime4Today + "'"; + } + if (next_Worktime4Today.length() > 0) { + if (next_Worktime4Today.length() == 5) { + next_Worktime4Today += ":00"; + } + sql += " and signtime < '" + next_Worktime4Today + "'"; + } + sql += " order by signdate asc,signtime asc "; + rs.executeQuery(sql); + int idx = 0; + while (rs.next()) { + String signId = Util.null2String(rs.getString("id")); + String signdate = Util.null2String(rs.getString("signdate")); + String signtime = Util.null2String(rs.getString("signtime")); + + checkInfo = new HashMap<>(); + checkInfo.put("signId", signId);//签到签退标识 + checkInfo.put("signDate", signdate);//签到签退日期 + checkInfo.put("signTime", signtime);//签到签退时间 + idx++; + if (idx == 1) {//第一条算签到 + checkInfo.put("signType", "1"); + lsCheckInfo.add(checkInfo); + } else if (idx == rs.getCounts()) {//最后一条算签退 + checkInfo.put("signType", "2"); + lsCheckInfo.add(checkInfo); + } + } + return lsCheckInfo; + } + + /** + * 获取班次上班时段 + * @param serial + * @param status + * @param record + * @return + */ + private static String getBcTimes(String serial,String status,String record){ + RecordSet rs = new RecordSet(); + String sql = "select times from kq_ShiftOnOffWorkSections where serialid = "+serial+" and (isdelete is null or isdelete <> '1') and onoffworktype = '"+status+"' and record = "+record; + rs.execute(sql); + String times = ""; + if (rs.next()){ + times = Util.null2String(rs.getString("times")); + } + return times; + } + + /** + * 获取打卡数量 + * @param userId + * @param date + * @param end + * @return + */ + private static Integer checkDkCount(String userId,String date,String end){ + RecordSet rs = new RecordSet(); + String sql = "select count(*) as num from HrmScheduleSign where userid = "+userId+" and signdate = '"+date+"' and signtime < '"+end+"'"; + rs.execute(sql); + Integer dkCount = 0; + if (rs.next()){ + dkCount = Util.getIntValue(rs.getString("num")); + } + return dkCount; + } + + /** + * 获取上午最后一笔卡 + * @param userId + * @param date + * @param end + * @return + */ + private static String getSignTimeNew(String userId,String date,String end){ + RecordSet rs = new RecordSet(); + String sql = "select signtime from HrmScheduleSign where userid = "+userId+" and signdate = '"+date+"' and signtime < '"+end+"' order by signtime desc limit 1"; + rs.execute(sql); + String signTimeB = ""; + if (rs.next()){ + signTimeB = Util.null2String(rs.getString("signtime")); + } + return signTimeB; + } +} \ No newline at end of file diff --git a/src/com/engine/kq/biz/KQYesterdayAbnormalRemindJob.java b/src/com/engine/kq/biz/KQYesterdayAbnormalRemindJob.java new file mode 100644 index 0000000..b792afc --- /dev/null +++ b/src/com/engine/kq/biz/KQYesterdayAbnormalRemindJob.java @@ -0,0 +1,220 @@ +package com.engine.kq.biz; + +import com.alibaba.fastjson.JSON; +import com.cloudstore.dev.api.bean.MessageBean; +import com.cloudstore.dev.api.bean.MessageType; +import com.cloudstore.dev.api.util.Util_Message; +import com.engine.kq.entity.KQGroupEntity; +import com.engine.kq.log.KQLog; +import com.engine.msgcenter.biz.ConfigManager; +import com.engine.msgcenter.biz.WeaMessageTypeConfig; +import com.google.common.collect.Sets; +import com.weaver.general.Util; +import weaver.common.DateUtil; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.hrm.common.Tools; +import weaver.hrm.resource.ResourceComInfo; +import weaver.interfaces.schedule.BaseCronJob; +import weaver.systeminfo.SystemEnv; + +import java.util.*; + +public class KQYesterdayAbnormalRemindJob extends BaseCronJob { + + private BaseBean log = new BaseBean(); + + private KQLog kqLog = new KQLog(); + + public void execute() { + String currentDate = Tools.getCurrentDate(); + String yesterDay = DateUtil.addDate(currentDate, -1); + kqLog.info(">>>>>>>>>>>>>>>>KQYesterdayAbnormalRemindJob>>>>>>>>>>>>>>begin>>>>>>>>>>>>>>>>"); + handleKqRemind(yesterDay); + kqLog.info(">>>>>>>>>>>>>>>>KQYesterdayAbnormalRemindJob>>>>>>>>>>>>>>end>>>>>>>>>>>>>>>>"); + } + + private void handleKqRemind(String date) { + try { + ResourceComInfo resourceComInfo = new ResourceComInfo(); + KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo(); + Map managerMessages = new HashMap<>(); + Map managerMessagesUUID = new HashMap<>(); + Map> yesterdayAbnormalData = new KqYesterdayAbnormalRemindBiz().getYesterdayAbnormalData(date, date); + String curDateTime = DateUtil.getDateTime(); + RecordSet recordSet = new RecordSet(); + for(Map.Entry> entry : yesterdayAbnormalData.entrySet()) { + String resourceId = entry.getKey(); + Map value = entry.getValue(); + + KQGroupEntity kQGroupEntity = kqGroupMemberComInfo.getUserKQGroupInfo(resourceId, date); + String abnormalremind = Util.null2String(kQGroupEntity.getAbnormalremind()); + if(!"1".equals(abnormalremind)){ + kqLog.info(">>>>>>>>>>>>>>>>KQYesterdayAbnormalRemindJob>>>>>>>>>>>>>>abnormalremind is closed>>>>>>>>>>>>>>>>"+resourceId); + continue; + } + + kqLog.info(">>>>>>>>>>>>>>>>KQYesterdayAbnormalRemindJob>>>>>>>>>>>>>>value>>>>>>>>>>>>>>>>"+value); + double late = value.get("late") == null ? 0.0 : value.get("late"); + double leaveearly = value.get("leaveearly") == null ? 0.0 : value.get("leaveearly"); + double absent = value.get("absent") == null ? 0.0 : value.get("absent"); + double forgot = value.get("forgot") == null ? 0.0 : value.get("forgot"); + double gravelate = value.get("gravelate") == null ? 0.0 : value.get("gravelate"); + double graveleaveearly = value.get("graveleaveearly") == null ? 0.0 : value.get("graveleaveearly"); + String content = getLabelName(97) +":"+date+" " + getLabelName(1867)+":"+resourceComInfo.getLastname(resourceId) +" "+ getLabelName(24770)+":"; + StringBuffer remindContentStr = new StringBuffer(); + StringBuffer sb = new StringBuffer(); + + if(late > 0) { + sb.append(getLabelName(20081)) ;//迟到 + remindContentStr.append(getLabelName(390055)).append(":").append(late).append(getLabelName(518516)); + } + + if(gravelate > 0){ + if(sb.length() > 0) { + sb.append( ","); + } + sb.append(getLabelName(500546)) ;//严重迟到 + if(remindContentStr.length() >0) { + remindContentStr.append(","); + } + remindContentStr.append(getLabelName(390056)).append(":").append(gravelate).append(getLabelName(518516)); + } + + if(leaveearly > 0){ + if(sb.length() > 0) { + sb.append( ","); + } + sb.append(getLabelName(20082)) ;//早退 + if(remindContentStr.length() >0) { + remindContentStr.append(","); + } + remindContentStr.append(getLabelName(390057)).append(":").append(leaveearly).append(getLabelName(518516)); + } + + if(graveleaveearly > 0){ + if(sb.length() > 0) { + sb.append( ","); + } + sb.append(getLabelName(500547)) ;//严重早退 + if(remindContentStr.length() >0) { + remindContentStr.append(","); + } + remindContentStr.append(getLabelName(390058)).append(":").append(graveleaveearly).append(getLabelName(518516)); + } + + if(absent > 0) { + if(sb.length() > 0) { + sb.append( ","); + } + sb.append( getLabelName(20085));//旷工 + + if(remindContentStr.length() >0) { + remindContentStr.append(","); + } + remindContentStr.append(getLabelName(390059)).append(":").append(absent).append(getLabelName(518516)); + } + if(forgot > 0) { + if(sb.length() > 0) { + sb.append( ","); + } + sb.append(getLabelName(20086));//漏签 + + if(remindContentStr.length() >0) { + remindContentStr.append(","); + } + remindContentStr.append(getLabelName(20086)).append(getLabelName(21551)).append(":").append(forgot).append(getLabelName(518516)); + } + if(sb.length() > 0) { + content += sb.toString(); + content += "
"+remindContentStr.toString(); + } else { + continue; + } + kqLog.info(">>>>>>>>>>>>>>>>KQYesterdayAbnormalRemindJob>>>>>>>>>>>>>>content>>>>>>>>>>>>>>>>"+content); + String uuid = UUID.randomUUID().toString().replace("-", ""); + + appNotification(resourceId, content, uuid); + insertMessageLog(resourceId, content, resourceId, curDateTime, uuid, recordSet); + + + String managerID = resourceComInfo.getManagerID(resourceId); + if (managerID != null && !"".equals(managerID) && Util.getIntValue(managerID, 0) > 0) { + String managerUUID = ""; + if(managerMessagesUUID.containsKey(managerID)) { + managerUUID = managerMessagesUUID.get(managerID).toString(); + } else { + managerUUID = UUID.randomUUID().toString().replace("-", ""); + managerMessagesUUID.put(managerID, new StringBuilder(managerUUID)); + } + insertMessageLog(resourceId, content, managerID, curDateTime, managerUUID, recordSet); + managerMessages.putIfAbsent(managerID, new StringBuilder()); + managerMessages.get(managerID).append(content).append("

"); + + } + } + // 统一发送给上级 + for (Map.Entry entry : managerMessages.entrySet()) { + String managerID = entry.getKey(); + String content = entry.getValue().toString(); + String managerUUID = managerMessagesUUID.get(managerID).toString(); + appNotification(managerID, content, managerUUID); + } + } catch (Exception e) { + log.writeLog(e); + } + } + + private static String getLabelName(int labelId) { + return SystemEnv.getHtmlLabelName(labelId, weaver.general.ThreadVarLanguage.getLang()); + } + + private void insertMessageLog(String resourceId, String content, String receiverId, String sendTime, String uuid, RecordSet rs) { + + String sql = "INSERT INTO abnormalremindmsg_log (resourceId, content, sendTime, receiverId,uuid) VALUES (?, ?, ?, ?, ?)"; + try { + rs.executeUpdate(sql, resourceId, content, sendTime, receiverId, uuid); + } catch (Exception e) { + log.writeLog(e); + kqLog.info("KQYesterdayAbnormalRemindJob::insertMessageLog: error inserting log for resourceId=" + resourceId + ", receiverId=" + receiverId, e); + } +} + + + public void appNotification(String resourceId,String content, String uuid) { + try { + String detailTitle = "539214"; + String title = content; + int createrId = 1; + String pcUrl = "/spa/hrm/static4attendance/index.html#/attendance/abnormalremindMsg?uuid="+uuid; + String mobileUrl = "/spa/hrm/static4mobile/index.html#/abnormalremindMsg?uuid="+uuid; + ConfigManager configManager = new ConfigManager(); + // 2、默认规则检查用户配置,返回后台自定义消息类型和对应通过配置的用户 + // @param singPath 与需求变更之前的path参数含义一致,代表该消息类型详细配置中唯一标志值,各模块参考自己的值(有疑问请联系云商店-田泽法) + // @param userid 按默认规则检查的用户配置信息(检查多人参考重载方法) + Map> accessConfig = configManager.defaultRuleCheckConfig(MessageType.HRM_KQ_REMIND, resourceId, null); + + // 3、遍历自定义消息类型集合 + for (Map.Entry> entry : accessConfig.entrySet()) { + // 4、构造消息实体 + MessageBean bean = Util_Message.createMessage(MessageType.HRM_KQ_REMIND, 0, title, detailTitle, content, pcUrl, mobileUrl, createrId); + + // 5、获取新的自定义消息类型 + WeaMessageTypeConfig config = entry.getKey(); + + // 6、新的自定义消息类型相关信息通知到消息实体bean上 + bean.setMessageConfig(config); + + // 7、设置检查配置通过需要发送消息的用户 + bean.setUserList(Sets.newHashSet(entry.getValue())); + + // 8、发送消息 + Util_Message.sendAndpublishMessage(bean); + kqLog.info("in>>>>KQYesterdayAbnormalRemindJob>>>>>>appNotification=bean::"+ JSON.toJSONString(bean)); + } + } catch (Exception e) { + log.writeLog(e); + } + } + +} diff --git a/src/com/engine/kq/biz/KqYesterdayAbnormalRemindBiz.java b/src/com/engine/kq/biz/KqYesterdayAbnormalRemindBiz.java new file mode 100644 index 0000000..d67a7b2 --- /dev/null +++ b/src/com/engine/kq/biz/KqYesterdayAbnormalRemindBiz.java @@ -0,0 +1,90 @@ +package com.engine.kq.biz; + +import com.engine.kq.log.KQLog; +import weaver.conn.RecordSet; +import weaver.general.Util; + +import java.util.HashMap; +import java.util.Map; + +/** + * 考勤异常提醒公共接口 + */ +public class KqYesterdayAbnormalRemindBiz { + + private KQLog kqLog = new KQLog(); + /** + * 获取昨天考勤异常相关数据 + * @return + */ + public Map> getYesterdayAbnormalData(String fromDate, String toDate) { + return getYesterdayAbnormalData(fromDate, toDate, null); + } + + public Map> getYesterdayAbnormalData(String fromDate, String toDate, String resourceId) { + kqLog.info("KqAbnormalRemindBiz::getYesterdayAbnormalData:fromDate"+fromDate+":toDate:"+toDate+":resourceId:"+resourceId); + RecordSet rs = new RecordSet(); + Map> yesterdayAbnormalMap = new HashMap<>(); + String forgotBeginWorkCheck_field = " sum(b.forgotBeginWorkCheck) "; + + if(rs.getDBType().equalsIgnoreCase("oracle") || rs.getDBType().equalsIgnoreCase("gs")) { + forgotBeginWorkCheck_field = " sum(nvl(b.forgotbeginworkcheckmins,0)) "; + }else if((rs.getDBType()).equalsIgnoreCase("mysql")){ + forgotBeginWorkCheck_field = " sum(ifnull(b.forgotbeginworkcheckmins,0)) "; + }else { + forgotBeginWorkCheck_field = " sum(isnull(b.forgotbeginworkcheckmins,0)) "; + } + String backFields = " a.id,a.lastname,a.workcode,a.dsporder,b.resourceid,a.subcompanyid1 as subcompanyid,a.departmentid,a.jobtitle," + + " sum(b.beLateMins) as beLateMins, " + + " sum(b.graveBeLateMins) as graveBeLateMins," + + " sum(b.leaveEarlyMins) as leaveEarlyMins, " + + " sum(b.graveLeaveEarlyMins) as graveLeaveEarlyMins, " + + " sum(b.absenteeismMins) as absenteeismMins, sum(b.forgotcheckmins)+"+forgotBeginWorkCheck_field+" as forgotCheckMins "; + + if(rs.getDBType().equals("oracle")){ + backFields = "/*+ index(kq_format_total IDX_KQ_FORMAT_TOTAL_KQDATE) */ "+backFields; + } + String sqlFrom = " from hrmresource a, kq_format_detail b where a.id= b.resourceid and b.kqdate >='"+fromDate+"' and b.kqdate <='"+toDate+"'"; + if(resourceId != null) { + sqlFrom += " and (a.accounttype = 0 or a.accounttype is null) and a.id="+resourceId; + } + String groupBy = " group by a.id,a.lastname,a.workcode,a.dsporder,b.resourceid,a.subcompanyid1,a.departmentid,a.jobtitle "; + String sql = backFields + sqlFrom + groupBy; + sql = " select " + sql; + kqLog.info("KqAbnormalRemindBiz::sql:"+sql); + rs.executeQuery(sql); + while (rs.next()) { + Map abnormalDataMap = new HashMap<>(); + String userId = rs.getString("id"); + double beLateMins = Util.getDoubleValue(rs.getString("beLateMins"), 0.0);//迟到 + double graveBeLateMins = Util.getDoubleValue(rs.getString("graveBeLateMins"), 0.0);//严重迟到 + double leaveEarlyMins = Util.getDoubleValue(rs.getString("leaveEarlyMins"), 0.0);//早退 + double graveLeaveEarlyMins = Util.getDoubleValue(rs.getString("graveLeaveEarlyMins"), 0.0);//严重早退 + double absenteeismMins = Util.getDoubleValue(rs.getString("absenteeismMins"), 0.0);//旷工 + double forgotCheck = Util.getDoubleValue(rs.getString("forgotCheckMins"), 0.0);//漏签 + if(beLateMins> 0) { + abnormalDataMap.put("late", beLateMins); + } + if(graveBeLateMins> 0) { + abnormalDataMap.put("gravelate", graveBeLateMins); + } + if(leaveEarlyMins> 0) { + abnormalDataMap.put("leaveearly", leaveEarlyMins); + } + if(graveLeaveEarlyMins> 0) { + abnormalDataMap.put("graveleaveearly", graveLeaveEarlyMins); + } + if(absenteeismMins> 0) { + abnormalDataMap.put("absent", absenteeismMins); + } + if(forgotCheck> 0) { + abnormalDataMap.put("forgot", forgotCheck); + } + if(!abnormalDataMap.isEmpty()) { + yesterdayAbnormalMap.put(userId, abnormalDataMap); + } + } + kqLog.info("KqAbnormalRemindBiz::getYesterdayAbnormalData:yesterdayAbnormalMap"+yesterdayAbnormalMap); + return yesterdayAbnormalMap; + } +} diff --git a/src/com/engine/kq/biz/chain/shiftinfo/ShiftInfoBean.java b/src/com/engine/kq/biz/chain/shiftinfo/ShiftInfoBean.java new file mode 100644 index 0000000..7233a07 --- /dev/null +++ b/src/com/engine/kq/biz/chain/shiftinfo/ShiftInfoBean.java @@ -0,0 +1,805 @@ +package com.engine.kq.biz.chain.shiftinfo; + +import com.engine.kq.entity.TimeScopeEntity; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 1、首先有个KQTimesArrayComInfo缓存类,这个类把00:00-23:59的时间点都转换成了0-1439的数值 + * 我把这个数值视作下标index + * + * 2、假如班次设置的工作时段是 + * 8:00-12:00 + * 13:00-18:00 + * 22:00-次日4:00 + * + * 3、... + * + * 4、那么restTimes表示的就是休息时段15:00-16:00对应的数组下标{[100,200]},举个栗子而已 + * + * 5、那么workIndex表示的就是休息时段8:00-12:00...对应的数组下标{[50,80],[90,180],[250,280]},workIndexTime存的就是时间点举个栗子而已 + * + * 6、那么halfWorkIndex表示的就是半天规则情况下需要用到的数组下标 + * 上面的例子里的工作时长的15个小时,所以半天的话,需要从8:00-16:30,只要是满足小于这个范围段内的都是半天,大于的就是1天了 + * halfWorkIndex对应的数组下标就是{[50,70]},halfWorkIndexTime存的就是时间点举个栗子而已 + * + * 7、那么wholeWorkIndex表示的就是整天规则情况下需要用到的数组下标,我只需要知道workIndex就可以了。wholeWorkIndexTime存的就是时间点 + * + */ +public class ShiftInfoBean { + /** + * 指定开始时间 + */ + private String splitFromTime; + /** + * 指定结束时间 + */ + private String splitToTime; + + /** + * 指定日期 因为流程时段区间已经被拆分成一天一条了 + */ + private String splitDate; + /** + * 要返回当天的工作时间区间对应的数组下标 这个是不包含跨天的 + */ + private List workIndex; + + /** + * 要返回当天的工作时间区间对应的数组下标 这个是包含跨天的 + */ + private List workAcrossIndex; + + /** + * 要返回当天的工作时间区间对应的时间 这个是包含跨天的 + */ + private List workAcrossTime; + + /** + * 当天打卡时段时间:多少分钟可以开始签到签退的 + */ + private List workMinsAcrossIndex; + /** + * 要返回的休息时间区间对应的数组下标 不包含跨天 + */ + private List restIndex; + /** + * 要返回的休息时间区间对应的数组下标 包含跨天的 + */ + private List restAcrossIndex; + /** + * 要返回的半天规则时间区间对应的数组下标 + * 这里有值的话是三个,最早的开始时间 中间时间 最晚的下班时间 + */ + private List halfWorkIndex; + + /** + * 工作时长 + */ + private int workmins; + + private int signoutOnlyoff; + + /** + * 加班用的前日期是何种类型 + */ + private int changeType; + + /** + * 当前日期的班次 + */ + private String serialid; + + /** + * 指定日期的前一天,因为存在跨天,昨天数据可能也需要在今天统计 + */ + private String preSplitDate; + + /** + * 这个返回的是前一天的班次存在跨天,跨到今天的工作时段区间 + */ + private List preWorkIndex; + + /** + * 要返回前一天天的工作时间区间对应的数组下标 这个是包含跨天的 + */ + private List preWorkAcrossIndex; + + /** + * 要返回前一天打卡时段信息:多少分钟可以开始签到签退的 + */ + private List preWorkMinsAcrossIndex; + + /** + * 映射前一天的跨天和时间区间下标 + */ + private Map preWorktimeAcrossMap; + /** + * 要返回前一天的休息时间区间对应的数组下标 + */ + private List preRestIndex; + /** + * 要返回的前一天的半天规则时间区间对应的数组下标 + * 这里有值的话是三个,开始时间 中间时间 下班时间 + */ + private List preHalfWorkIndex; + + /** + * 前一天的工作时长 + */ + private int preWorkmins; + + /** + * 前一个日期的班次 + */ + private String preSerialid; + + /** + * 得到实际时长分钟数 + */ + private double D_Mins; + + /** + * 流程判断的各种规则 + * 半天小时的 + */ + private String minimumUnit; + + /** + * 流程用的时候存的值 + */ + private String duration; + + /** + * 针对时段跨天 流程跨天的情况,23:59-24:00差一分钟的处理 + */ + private String oneMoreMinute; + + /** + * 当前时间段 + */ + private int[] curMins; + + /** + * 当前时间段 + */ + private int[] preMins; + + /** + * 存储所有的工作时间 + */ + private List allWorkTime; + + /** + * 存储所有的跨天时间 + */ + private List allAcrossWorkTime; + /** + * 存储所有的休息时间 + */ + private List allRestTime; + + /** + * 存储所有的休息时间 + */ + private List allAcrossRestTime; + + + + /** + * 存储所有的工作时间 + */ + private List preAllWorkTime; + + /** + * 存储所有的跨天时间 + */ + private List preAllAcrossWorkTime; + /** + * 存储所有的休息时间 + */ + private List preAllRestTime; + + /** + * 存储所有的休息时间 + */ + private List preAllAcrossRestTime; + + /** + * 是否是自由班製 + */ + private boolean isfree; + /** + * 自由班制签到开始时间 + */ + private String freeSignStart; + /** + * 自由班制工作时长 + */ + private String freeWorkMins; + /** + * 自由班制应该签退时间 + */ + private String freeSignEnd; + /** + * 自由班制 半天中间点 + */ + private String freeSignMiddle; + + + /** + * 当前班次作为当前班次存在,在0-48小时内的工作时段下标 + */ + private List workLongTimeIndex; + + /** + * 当前班次作为当前班次存在,在0-48小时内的工作时段下标 + */ + private List restLongTimeIndex; + + /** + * 存储所有的工作时间 48小时制休息时段 + */ + private List allLongWorkTime; + + /** + * 判断当前班次是否存在跨天 + */ + private String isAcross; + + /** + * 判断前一天班次是否存在跨天 + */ + private String isPreAcross; + + private Map shiftRuleMap; + + /** + * 和kqformdate里的workTimeEntity用到的保持一致 + */ + private List signTime;//允许打卡时间 + /** + * 和kqformdate里的workTimeEntity用到的保持一致 + */ + private List workTime;//工作时间 + + /** + * 半天计算规则 + */ + private String halfcalrule; + + /** + * 自定义 半天计算规则 时间点 + */ + private String halfcalpoint; + + private String halfcalpoint2cross; + + /** + * 存储每一段工作时段内的工作时长 + */ + private List eachWorkMins; + /** + * 是否是非工作日 1表示是非工作日班次 + */ + private int restShift; + + /** + * 昨天应出勤折算天数 + */ + private String preConvertAttendDay = ""; + + /** + * 应出勤折算天数 + */ + private String convertAttendDay = ""; + + public ShiftInfoBean() { + this.splitFromTime = ""; + this.splitToTime = ""; + this.splitDate = ""; + this.workIndex = new ArrayList<>(); + this.workAcrossIndex = new ArrayList<>(); + this.restIndex = new ArrayList<>(); + this.restAcrossIndex = new ArrayList<>(); + this.halfWorkIndex = new ArrayList<>(); + this.workmins = 0; + this.signoutOnlyoff = 0; + this.preSplitDate = ""; + this.preWorkIndex = new ArrayList<>(); + this.preWorkAcrossIndex = new ArrayList<>(); + this.preWorktimeAcrossMap = new HashMap<>(); + this.preRestIndex = new ArrayList<>(); + this.preHalfWorkIndex = new ArrayList<>(); + this.preWorkmins = 0; + this.D_Mins = 0.0; + this.minimumUnit = ""; + this.duration = ""; + this.oneMoreMinute = ""; + this.preWorkMinsAcrossIndex = new ArrayList<>(); + this.workMinsAcrossIndex = new ArrayList<>(); + this.preSerialid = ""; + this.serialid = ""; + this.workAcrossTime = new ArrayList<>(); + this.isfree = false; + this.freeSignStart = ""; + this.freeWorkMins = ""; + this.freeSignEnd = ""; + this.freeSignMiddle = ""; + + this.workLongTimeIndex = new ArrayList<>(); + this.restLongTimeIndex = new ArrayList<>(); + this.allLongWorkTime = new ArrayList<>(); + this.isAcross = ""; + this.isPreAcross = ""; + this.shiftRuleMap = Maps.newHashMap(); + this.workTime = Lists.newArrayList(); + this.signTime = Lists.newArrayList(); + this.halfcalrule = ""; + this.halfcalpoint = ""; + this.halfcalpoint2cross = ""; + this.eachWorkMins = new ArrayList<>(); + } + + public String getSplitDate() { + return splitDate; + } + + public void setSplitDate(String splitDate) { + this.splitDate = splitDate; + } + + public String getSplitFromTime() { + return splitFromTime; + } + + public void setSplitFromTime(String splitFromTime) { + this.splitFromTime = splitFromTime; + } + + public String getSplitToTime() { + return splitToTime; + } + + public void setSplitToTime(String splitToTime) { + this.splitToTime = splitToTime; + } + + public List getWorkIndex() { + return workIndex; + } + + public void setWorkIndex(List workIndex) { + this.workIndex = workIndex; + } + + public List getRestIndex() { + return restIndex; + } + + public void setRestIndex(List restIndex) { + this.restIndex = restIndex; + } + + public List getHalfWorkIndex() { + return halfWorkIndex; + } + + public void setHalfWorkIndex(List halfWorkIndex) { + this.halfWorkIndex = halfWorkIndex; + } + + public double getD_Mins() { + return D_Mins; + } + + public void setD_Mins(double d_Mins) { + D_Mins = d_Mins; + } + + public String getPreSplitDate() { + return preSplitDate; + } + + public void setPreSplitDate(String preSplitDate) { + this.preSplitDate = preSplitDate; + } + + public List getPreWorkIndex() { + return preWorkIndex; + } + + public void setPreWorkIndex(List preWorkIndex) { + this.preWorkIndex = preWorkIndex; + } + + public List getWorkAcrossIndex() { + return workAcrossIndex; + } + + public void setWorkAcrossIndex(List workAcrossIndex) { + this.workAcrossIndex = workAcrossIndex; + } + + public int getWorkmins() { + return workmins; + } + + public void setWorkmins(int workmins) { + this.workmins = workmins; + } + + public int getSignoutOnlyoff() { + return signoutOnlyoff; + } + + public void setSignoutOnlyoff(int signoutOnlyoff) { + this.signoutOnlyoff = signoutOnlyoff; + } + + public String getMinimumUnit() { + return minimumUnit; + } + + public void setMinimumUnit(String minimumUnit) { + this.minimumUnit = minimumUnit; + } + + public List getPreHalfWorkIndex() { + return preHalfWorkIndex; + } + + public void setPreHalfWorkIndex(List preHalfWorkIndex) { + this.preHalfWorkIndex = preHalfWorkIndex; + } + + public List getPreWorkAcrossIndex() { + return preWorkAcrossIndex; + } + + public void setPreWorkAcrossIndex(List preWorkAcrossIndex) { + this.preWorkAcrossIndex = preWorkAcrossIndex; + } + + public Map getPreWorktimeAcrossMap() { + return preWorktimeAcrossMap; + } + + public void setPreWorktimeAcrossMap( + Map preWorktimeAcrossMap) { + this.preWorktimeAcrossMap = preWorktimeAcrossMap; + } + + public List getPreRestIndex() { + return preRestIndex; + } + + public void setPreRestIndex(List preRestIndex) { + this.preRestIndex = preRestIndex; + } + + public int getPreWorkmins() { + return preWorkmins; + } + + public void setPreWorkmins(int preWorkmins) { + this.preWorkmins = preWorkmins; + } + + public List getRestAcrossIndex() { + return restAcrossIndex; + } + + public void setRestAcrossIndex(List restAcrossIndex) { + this.restAcrossIndex = restAcrossIndex; + } + + public String getDuration() { + return duration; + } + + public void setDuration(String duration) { + this.duration = duration; + } + + public String getOneMoreMinute() { + return oneMoreMinute; + } + + public void setOneMoreMinute(String oneMoreMinute) { + this.oneMoreMinute = oneMoreMinute; + } + + public List getWorkMinsAcrossIndex() { + return workMinsAcrossIndex; + } + + public void setWorkMinsAcrossIndex(List workMinsAcrossIndex) { + this.workMinsAcrossIndex = workMinsAcrossIndex; + } + + public List getPreWorkMinsAcrossIndex() { + return preWorkMinsAcrossIndex; + } + + public void setPreWorkMinsAcrossIndex(List preWorkMinsAcrossIndex) { + this.preWorkMinsAcrossIndex = preWorkMinsAcrossIndex; + } + + public String getSerialid() { + return serialid; + } + + public void setSerialid(String serialid) { + this.serialid = serialid; + } + + public String getPreSerialid() { + return preSerialid; + } + + public void setPreSerialid(String preSerialid) { + this.preSerialid = preSerialid; + } + + public int[] getCurMins() { + return curMins; + } + + public void setCurMins(int[] curMins) { + this.curMins = curMins; + } + + public int[] getPreMins() { + return preMins; + } + + public void setPreMins(int[] preMins) { + this.preMins = preMins; + } + + public List getWorkAcrossTime() { + return workAcrossTime; + } + + public void setWorkAcrossTime(List workAcrossTime) { + this.workAcrossTime = workAcrossTime; + } + + public int getChangeType() { + return changeType; + } + + public void setChangeType(int changeType) { + this.changeType = changeType; + } + + public List getAllWorkTime() { + return allWorkTime; + } + + public void setAllWorkTime(List allWorkTime) { + this.allWorkTime = allWorkTime; + } + + public List getAllAcrossWorkTime() { + return allAcrossWorkTime; + } + + public void setAllAcrossWorkTime(List allAcrossWorkTime) { + this.allAcrossWorkTime = allAcrossWorkTime; + } + + public List getAllRestTime() { + return allRestTime; + } + + public void setAllRestTime(List allRestTime) { + this.allRestTime = allRestTime; + } + + public List getAllAcrossRestTime() { + return allAcrossRestTime; + } + + public void setAllAcrossRestTime(List allAcrossRestTime) { + this.allAcrossRestTime = allAcrossRestTime; + } + + public List getPreAllWorkTime() { + return preAllWorkTime; + } + + public void setPreAllWorkTime(List preAllWorkTime) { + this.preAllWorkTime = preAllWorkTime; + } + + public List getPreAllAcrossWorkTime() { + return preAllAcrossWorkTime; + } + + public void setPreAllAcrossWorkTime(List preAllAcrossWorkTime) { + this.preAllAcrossWorkTime = preAllAcrossWorkTime; + } + + public List getPreAllRestTime() { + return preAllRestTime; + } + + public void setPreAllRestTime(List preAllRestTime) { + this.preAllRestTime = preAllRestTime; + } + + public List getPreAllAcrossRestTime() { + return preAllAcrossRestTime; + } + + public void setPreAllAcrossRestTime(List preAllAcrossRestTime) { + this.preAllAcrossRestTime = preAllAcrossRestTime; + } + + public boolean isIsfree() { + return isfree; + } + + public void setIsfree(boolean isfree) { + this.isfree = isfree; + } + + public String getFreeSignStart() { + return freeSignStart; + } + + public void setFreeSignStart(String freeSignStart) { + this.freeSignStart = freeSignStart; + } + + public String getFreeWorkMins() { + return freeWorkMins; + } + + public void setFreeWorkMins(String freeWorkMins) { + this.freeWorkMins = freeWorkMins; + } + + public String getFreeSignEnd() { + return freeSignEnd; + } + + public void setFreeSignEnd(String freeSignEnd) { + this.freeSignEnd = freeSignEnd; + } + + public String getFreeSignMiddle() { + return freeSignMiddle; + } + + public void setFreeSignMiddle(String freeSignMiddle) { + this.freeSignMiddle = freeSignMiddle; + } + + public List getWorkLongTimeIndex() { + return workLongTimeIndex; + } + + public void setWorkLongTimeIndex(List workLongTimeIndex) { + this.workLongTimeIndex = workLongTimeIndex; + } + + public List getRestLongTimeIndex() { + return restLongTimeIndex; + } + + public void setRestLongTimeIndex(List restLongTimeIndex) { + this.restLongTimeIndex = restLongTimeIndex; + } + + public List getAllLongWorkTime() { + return allLongWorkTime; + } + + public void setAllLongWorkTime(List allLongWorkTime) { + this.allLongWorkTime = allLongWorkTime; + } + + public String getIsAcross() { + return isAcross; + } + + public void setIsAcross(String isAcross) { + this.isAcross = isAcross; + } + + public String getIsPreAcross() { + return isPreAcross; + } + + public void setIsPreAcross(String isPreAcross) { + this.isPreAcross = isPreAcross; + } + + public Map getShiftRuleMap() { + return shiftRuleMap; + } + + public void setShiftRuleMap(Map shiftRuleMap) { + this.shiftRuleMap = shiftRuleMap; + } + + public List getSignTime() { + return signTime; + } + + public void setSignTime(List signTime) { + this.signTime = signTime; + } + + public List getWorkTime() { + return workTime; + } + + public void setWorkTime(List workTime) { + this.workTime = workTime; + } + + public String getHalfcalrule() { + return halfcalrule; + } + + public void setHalfcalrule(String halfcalrule) { + this.halfcalrule = halfcalrule; + } + + public List getEachWorkMins() { + return eachWorkMins; + } + + public void setEachWorkMins(List eachWorkMins) { + this.eachWorkMins = eachWorkMins; + } + + public String getHalfcalpoint() { + return halfcalpoint; + } + + public void setHalfcalpoint(String halfcalpoint) { + this.halfcalpoint = halfcalpoint; + } + + public String getHalfcalpoint2cross() { + return halfcalpoint2cross; + } + + public void setHalfcalpoint2cross(String halfcalpoint2cross) { + this.halfcalpoint2cross = halfcalpoint2cross; + } + + public int getRestShift() { + return restShift; + } + + public void setRestShift(int restShift) { + this.restShift = restShift; + } + + public String getConvertAttendDay() { + return convertAttendDay; + } + + public void setConvertAttendDay(String convertAttendDay) { + this.convertAttendDay = convertAttendDay; + } + + public String getPreConvertAttendDay() { + return preConvertAttendDay; + } + + public void setPreConvertAttendDay(String preConvertAttendDay) { + this.preConvertAttendDay = preConvertAttendDay; + } +} diff --git a/src/com/engine/kq/entity/KQGroupEntity.java b/src/com/engine/kq/entity/KQGroupEntity.java new file mode 100644 index 0000000..605255e --- /dev/null +++ b/src/com/engine/kq/entity/KQGroupEntity.java @@ -0,0 +1,235 @@ +package com.engine.kq.entity; + +public class KQGroupEntity { + private String id; + private String groupname; + private String excludeid; + private String excludecount; + private String subcompanyid; + private String kqtype; + private String serialids; + private String weekday; + private String signstart; + private String workhour; + private String isdelete; + private String signintype; + private String ipscope; + private String locationcheck; + private String locationcheckscope; + private String wificheck; + private String outsidesign; + + private String outsignapprove; + private String validity; + private String validityfromdate; + private String validityenddate; + private String locationfacecheck; + private String locationshowaddress; + private String wififacecheck; + private String calmethod; + private String abnormalremind; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getGroupname() { + return groupname; + } + + public void setGroupname(String groupname) { + this.groupname = groupname; + } + + public String getExcludeid() { + return excludeid; + } + + public void setExcludeid(String excludeid) { + this.excludeid = excludeid; + } + + public String getExcludecount() { + return excludecount; + } + + public void setExcludecount(String excludecount) { + this.excludecount = excludecount; + } + + public String getSubcompanyid() { + return subcompanyid; + } + + public void setSubcompanyid(String subcompanyid) { + this.subcompanyid = subcompanyid; + } + + public String getKqtype() { + return kqtype; + } + + public void setKqtype(String kqtype) { + this.kqtype = kqtype; + } + + public String getSerialids() { + return serialids; + } + + public void setSerialids(String serialids) { + this.serialids = serialids; + } + + public String getWeekday() { + return weekday; + } + + public void setWeekday(String weekday) { + this.weekday = weekday; + } + + public String getSignstart() { + return signstart; + } + + public void setSignstart(String signstart) { + this.signstart = signstart; + } + + public String getWorkhour() { + return workhour; + } + + public void setWorkhour(String workhour) { + this.workhour = workhour; + } + + public String getIsdelete() { + return isdelete; + } + + public void setIsdelete(String isdelete) { + this.isdelete = isdelete; + } + + public String getSignintype() { + return signintype; + } + + public void setSignintype(String signintype) { + this.signintype = signintype; + } + + public String getIpscope() { + return ipscope; + } + + public void setIpscope(String ipscope) { + this.ipscope = ipscope; + } + + public String getLocationcheck() { + return locationcheck; + } + + public void setLocationcheck(String locationcheck) { + this.locationcheck = locationcheck; + } + + public String getLocationcheckscope() { + return locationcheckscope; + } + + public void setLocationcheckscope(String locationcheckscope) { + this.locationcheckscope = locationcheckscope; + } + + public String getOutsidesign() { + return outsidesign; + } + + public String getOutsignapprove() {return outsignapprove;} + + public String getValidity() { + return validity; + } + + public void setValidity(String validity) { + this.validity = validity; + } + + public String getValidityfromdate() { + return validityfromdate; + } + + public void setValidityfromdate(String validityfromdate) { + this.validityfromdate = validityfromdate; + } + + public String getValidityenddate() { + return validityenddate; + } + + public void setValidityenddate(String validityenddate) { + this.validityenddate = validityenddate; + } + + public void setOutsidesign(String outsidesign) {this.outsidesign = outsidesign;} + public void setOutsignapprove(String outsignapprove) { + this.outsignapprove = outsignapprove; + } + + public String getWificheck() { + return wificheck; + } + + public void setWificheck(String wificheck) { + this.wificheck = wificheck; + } + + public String getLocationfacecheck() { + return locationfacecheck; + } + + public void setLocationfacecheck(String locationfacecheck) { + this.locationfacecheck = locationfacecheck; + } + + public String getLocationshowaddress() { + return locationshowaddress; + } + + public void setLocationshowaddress(String locationshowaddress) { + this.locationshowaddress = locationshowaddress; + } + + public String getWififacecheck() { + return wififacecheck; + } + + public void setWififacecheck(String wififacecheck) { + this.wififacecheck = wififacecheck; + } + + public String getCalmethod() { + return calmethod; + } + + public void setCalmethod(String calmethod) { + this.calmethod = calmethod; + } + + public String getAbnormalremind() { + return this.abnormalremind; + } + + public void setAbnormalremind( String abnormalremind) { + this.abnormalremind = abnormalremind; + } + +} diff --git a/src/com/engine/kq/entity/KQShiftRuleEntity.java b/src/com/engine/kq/entity/KQShiftRuleEntity.java new file mode 100644 index 0000000..6efc3a4 --- /dev/null +++ b/src/com/engine/kq/entity/KQShiftRuleEntity.java @@ -0,0 +1,189 @@ +package com.engine.kq.entity; + +/** + * 考勤报表明细实体类 + */ +public class KQShiftRuleEntity { + private String userId = ""; + private String kqDate = ""; + private int belatemins = 0; + private int gravebelatemins = 0; + private int leaveearlymins = 0; + private int graveleaveearlymins = 0; + private int absenteeismmins = 0; + private int forgotcheckmins = 0; + private int forgotBeginWorkCheckMins = 0;//上班漏签 + private int earlyInMins = 0;//早到分钟数 + private int lateOutMins = 0;//晚走分钟数 + private String nosign_is_absent = "1"; + private String nosign_ishandle = "0"; + private String signInTime; + private String signOutTime; + private String early_one_mins; + //上午旷工 + private boolean isAMAbsent = false; + //下午旷工 + private boolean isPMAbsent = false; + private int on_absenteeismMins; + private int off_absenteeismMins; + + public int getForgotBeginWorkCheckMins() { + return forgotBeginWorkCheckMins; + } + + public void setForgotBeginWorkCheckMins(int forgotBeginWorkCheckMins) { + this.forgotBeginWorkCheckMins = forgotBeginWorkCheckMins; + } + + public int getBelatemins() { + return belatemins; + } + + public void setBelatemins(int belatemins) { + this.belatemins = belatemins; + } + + public int getGravebelatemins() { + return gravebelatemins; + } + + public void setGravebelatemins(int gravebelatemins) { + this.gravebelatemins = gravebelatemins; + } + + public int getLeaveearlymins() { + return leaveearlymins; + } + + public void setLeaveearlymins(int leaveearlymins) { + this.leaveearlymins = leaveearlymins; + } + + public int getGraveleaveearlymins() { + return graveleaveearlymins; + } + + public void setGraveleaveearlymins(int graveleaveearlymins) { + this.graveleaveearlymins = graveleaveearlymins; + } + + public int getAbsenteeismmins() { + return absenteeismmins; + } + + public void setAbsenteeismmins(int absenteeismmins) { + this.absenteeismmins = absenteeismmins; + } + + public int getForgotcheckmins() { + return forgotcheckmins; + } + + public void setForgotcheckmins(int forgotcheckmins) { + this.forgotcheckmins = forgotcheckmins; + } + + public int getEarlyInMins() { + return earlyInMins; + } + + public void setEarlyInMins(int earlyInMins) { + this.earlyInMins = earlyInMins; + } + + public int getLateOutMins() { + return lateOutMins; + } + + public void setLateOutMins(int lateOutMins) { + this.lateOutMins = lateOutMins; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getKqDate() { + return kqDate; + } + + public void setKqDate(String kqDate) { + this.kqDate = kqDate; + } + + public String getNosign_is_absent() { + return nosign_is_absent; + } + + public void setNosign_is_absent(String nosign_is_absent) { + this.nosign_is_absent = nosign_is_absent; + } + + public String getNosign_ishandle() { + return nosign_ishandle; + } + + public void setNosign_ishandle(String nosign_ishandle) { + this.nosign_ishandle = nosign_ishandle; + } + + public String getSignInTime() { + return signInTime; + } + + public void setSignInTime(String signInTime) { + this.signInTime = signInTime; + } + + public String getSignOutTime() { + return signOutTime; + } + + public void setSignOutTime(String signOutTime) { + this.signOutTime = signOutTime; + } + + public String getEarly_one_mins() { + return early_one_mins; + } + + public void setEarly_one_mins(String early_one_mins) { + this.early_one_mins = early_one_mins; + } + + public boolean isAMAbsent() { + return isAMAbsent; + } + + public void setAMAbsent(boolean AMAbsent) { + isAMAbsent = AMAbsent; + } + + public boolean isPMAbsent() { + return isPMAbsent; + } + + public void setPMAbsent(boolean PMAbsent) { + isPMAbsent = PMAbsent; + } + + public int getOn_absenteeismMins() { + return on_absenteeismMins; + } + + public void setOn_absenteeismMins(int on_absenteeismMins) { + this.on_absenteeismMins = on_absenteeismMins; + } + + public int getOff_absenteeismMins() { + return off_absenteeismMins; + } + + public void setOff_absenteeismMins(int off_absenteeismMins) { + this.off_absenteeismMins = off_absenteeismMins; + } +} diff --git a/src/com/engine/kq/entity/WorkTimeEntity.java b/src/com/engine/kq/entity/WorkTimeEntity.java new file mode 100644 index 0000000..dfaae29 --- /dev/null +++ b/src/com/engine/kq/entity/WorkTimeEntity.java @@ -0,0 +1,220 @@ +package com.engine.kq.entity; + +import java.util.List; +import java.util.Map; + +/*** + * 工作时间 + */ +public class WorkTimeEntity { + private String groupId;//所属考勤组 + private String groupName;//所属考勤组 + private String kqType;//考勤类型 + private String serialId;//班次 + private Map shiftRuleInfo;//班次人性化规则 + private List signTime;//允许打卡时间 + private List workTime;//工作时间 + private List restTime;//休息时间 + private int workMins;//工作时长 + private String isAcross;//是否跨天 + private String signstart;//自由工时开始打卡时间 + private boolean isExclude;//无需考勤人员 + private String calmethod;//自由班制计算方式 + private int signoutOnlyoff; + + private List halfWorkTime;//半天 + + private List halfWorkIndex; + + /** + * 是否是非工作日 1表示是非工作日班次 + */ + private int nonWorkShift; + /** + * 当前日期类型 + * playday 休息日 + * work 工作日 + * holiday 节假日 + */ + private String dayType; + + /** + * 应出勤折算天数 + */ + private String convertAttendDay = ""; + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getKQType() { + return kqType; + } + + public void setKQType(String kqType) { + this.kqType = kqType; + } + + public String getSerialId() { + return serialId; + } + + public void setSerialId(String serialId) { + this.serialId = serialId; + } + + public Map getShiftRuleInfo() { + return shiftRuleInfo; + } + + public void setShiftRuleInfo(Map shiftRuleInfo) { + this.shiftRuleInfo = shiftRuleInfo; + } + + public List getWorkTime() { + return workTime; + } + + public void setWorkTime(List workTime) { + this.workTime = workTime; + } + + public List getRestTime() { + return restTime; + } + + public void setRestTime(List restTime) { + this.restTime = restTime; + } + + public int getWorkMins() { + return workMins; + } + + public void setWorkMins(int workMins) { + this.workMins = workMins; + } + + public String getIsAcross() { + return isAcross; + } + + public void setIsAcross(String isAcross) { + this.isAcross = isAcross; + } + + public String getSignStart() { + return signstart; + } + + public void setSignStart(String signstart) { + this.signstart = signstart; + } + + public List getSignTime() { + return signTime; + } + + public void setSignTime(List signTime) { + this.signTime = signTime; + } + + public boolean getIsExclude() { + return isExclude; + } + + public void setIsExclude(boolean isExclude) { + this.isExclude = isExclude; + } + + public String getCalmethod() { + return calmethod; + } + + public void setCalmethod(String calmethod) { + this.calmethod = calmethod; + } + + public int getNonWorkShift() { + return nonWorkShift; + } + + public void setNonWorkShift(int restShift) { + this.nonWorkShift = restShift; + } + + public String getDayType() { + return dayType; + } + + public void setDayType(String dayType) { + this.dayType = dayType; + } + + public String getConvertAttendDay() { + return convertAttendDay; + } + + public void setConvertAttendDay(String convertAttendDay) { + this.convertAttendDay = convertAttendDay; + } + + public int getSignoutOnlyoff() { + return signoutOnlyoff; + } + + public void setSignoutOnlyoff(int signoutOnlyoff) { + this.signoutOnlyoff = signoutOnlyoff; + } + + public List getHalfWorkTime() { + return halfWorkTime; + } + + public void setHalfWorkTime(List halfWorkTime) { + this.halfWorkTime = halfWorkTime; + } + + public List getHalfWorkIndex() { + return halfWorkIndex; + } + + public void setHalfWorkIndex(List halfWorkIndex) { + this.halfWorkIndex = halfWorkIndex; + } + + @Override + public String toString() { + return "WorkTimeEntity{" + + "groupId='" + groupId + '\'' + + ", groupName='" + groupName + '\'' + + ", kqType='" + kqType + '\'' + + ", serialId='" + serialId + '\'' + + ", shiftRuleInfo=" + shiftRuleInfo + + ", signTime=" + signTime + + ", workTime=" + workTime + + ", restTime=" + restTime + + ", workMins=" + workMins + + ", isAcross='" + isAcross + '\'' + + ", signstart='" + signstart + '\'' + + ", isExclude=" + isExclude + + ", calmethod='" + calmethod + '\'' + + ", signoutOnlyoff=" + signoutOnlyoff + + ", nonWorkShift=" + nonWorkShift + + ", dayType='" + dayType + '\'' + + ", convertAttendDay='" + convertAttendDay + '\'' + + '}'; + } +} diff --git a/src/com/engine/kq/util/KQLockAttendaUtil.java b/src/com/engine/kq/util/KQLockAttendaUtil.java new file mode 100644 index 0000000..b21b6ee --- /dev/null +++ b/src/com/engine/kq/util/KQLockAttendaUtil.java @@ -0,0 +1,1382 @@ +package com.engine.kq.util; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.engine.kq.bean.ImportSetting; +import com.engine.kq.bean.KqLockAttenda; +import com.engine.kq.biz.*; +import com.engine.kq.cmd.shiftmanagement.toolkit.ShiftManagementToolKit; +import com.engine.kq.entity.KQScheduleSignEntity; +import com.engine.kq.entity.WorkTimeEntity; +import com.engine.kq.enums.KqSplitFlowTypeEnum; +import com.engine.kq.log.KQLog; +import com.engine.kq.timer.KQQueue; +import com.engine.kq.timer.KQTaskBean; +import com.engine.kq.wfset.bean.ProcessChangeSplitBean; +import com.engine.kq.wfset.bean.SplitBean; +import com.engine.kq.wfset.util.*; +import com.engine.workflow.biz.freeNode.FreeNodeBiz; +import com.engine.workflow.biz.publicApi.RequestOperateBiz; +import com.engine.workflow.biz.workflowOvertime.OvertimeBiz; +import com.engine.workflow.constant.PAResponseCode; +import com.engine.workflow.entity.core.RequestInfoEntity; +import com.engine.workflow.entity.publicApi.PAResponseEntity; +import com.engine.workflow.entity.publicApi.ReqOperateRequestEntity; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.wbi.util.StringUtil; +import weaver.conn.BatchRecordSet; +import weaver.conn.RecordSet; +import weaver.conn.RecordSetDataSource; +import weaver.file.Prop; +import weaver.general.BaseBean; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.hrm.User; +import weaver.hrm.common.Tools; +import weaver.hrm.resource.ResourceComInfo; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.RequestInfo; +import weaver.systeminfo.SystemEnv; +import weaver.wechat.util.DateUtil; +import weaver.workflow.agent.AgentManager; +import weaver.workflow.monitor.Monitor; +import weaver.workflow.monitor.MonitorDTO; +import weaver.workflow.workflow.WfForceOver; +import weaver.workflow.workflow.WfFunctionManageUtil; +import weaver.workflow.workflow.WorkflowComInfo; + +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + + +@SuppressWarnings("unchecked") +public class KQLockAttendaUtil { + + private static final String LOCK_TABLE = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_TABLE")); + private static final String LOCK_COM = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_COM")); + private static final String LOCK_SUBCOM = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_SUBCOM")); + private static final String LOCK_DEPT = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_DEPT")); + private static final String LOCK_RESOURCE = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_RESOURCE")); + private static final String LOCK_FROMDATE = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_FROMDATE")); + private static final String LOCK_TODATE = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_TODATE")); + private static final String LOCK_LOCK = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_LOCK")); + + private static final String LOCK_DEGREE = Util.null2String(Prop.getPropValue("kqLockAttenda", "LOCK_DEGREE")); + private static KQLog kqLog = new KQLog(); + + public List sdkqbb_map; + + public static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(100)); + + public KQLockAttendaUtil() { + this.sdkqbb_map = this.initModuleData(); + } + + + public List initModuleData() { + List list = new ArrayList<>(); + if ("".equals(LOCK_TABLE)) { + return list; + } + RecordSet rs = new RecordSet(); + StringBuilder sql = new StringBuilder(); + sql.append("select * from " + LOCK_TABLE + " where "); + sql.append(" " + LOCK_LOCK + "=1 "); + kqLog.info("sql>>>>>>>>>>>>>>>" + sql.toString()); + + KqLockAttenda bean = null; + rs.execute(sql.toString()); + while (rs.next()) { + bean = new KqLockAttenda(); + String iscompany = Util.null2String(rs.getString(LOCK_COM)); + bean.setLOCK_COM(iscompany); + String subcompanyIds = Util.null2String(rs.getString(LOCK_SUBCOM)); + bean.setLOCK_SUBCOM(subcompanyIds); + String departmentIds = Util.null2String(rs.getString(LOCK_DEPT)); + bean.setLOCK_DEPT(departmentIds); + String resouceIds = Util.null2String(rs.getString(LOCK_RESOURCE)); + bean.setLOCK_RESOURCE(resouceIds); + String fromdate = Util.null2String(rs.getString(LOCK_FROMDATE)); + bean.setLOCK_FROMDATE(fromdate); + String todate = Util.null2String(rs.getString(LOCK_TODATE)); + bean.setLOCK_TODATE(todate); + list.add(bean); + } + + return list; + } + + public boolean checkLockStatus(String resourceId, String kqdate) { + if (!LOCK_DEGREE.equals("0")&&!LOCK_DEGREE.equals("1")) { + return false; + } + try { + RecordSet rs = new RecordSet(); + ResourceComInfo resourceComInfo = new ResourceComInfo(); + String subcompanyId = resourceComInfo.getSubCompanyID(resourceId); + String departmentId = resourceComInfo.getDepartmentID(resourceId); + String sql = "select * from " + LOCK_TABLE + " where (" + LOCK_FROMDATE + "<='" + kqdate + "' and " + LOCK_TODATE + " >= '" + kqdate + "' ) "; + String sqlWhere = ""; + if (!"".equals(resourceId)) { + if (rs.getDBType().equals("oracle")||rs.getDBType().equals("postgresql")) { + sqlWhere=" and (','||CAST(" + LOCK_RESOURCE + " AS VARCHAR(2000))||',') like '%," + resourceId + ",%'"; + } else if (rs.getDBType().equals("mysql")) { + sqlWhere=" and concat(','," + LOCK_RESOURCE + ",',') like '%," + resourceId + ",%'" ; + } else { + sqlWhere=" and (','+CAST(" + LOCK_RESOURCE + " AS VARCHAR(2000))+',') like '%," + resourceId + ",%'" ; + } + rs.executeQuery(sql + sqlWhere); + rs.writeLog("KQLockAttendaUtil>sql="+sql + sqlWhere); + if (rs.next()) { + String lockValue = rs.getString(LOCK_LOCK); + if(lockValue.equals("1")){ + return true; + }else{ + return false; + } + } + } + if (!"".equals(departmentId)) { + if (rs.getDBType().equals("oracle")||rs.getDBType().equals("postgresql")) { + sqlWhere=" and (','||CAST(" + LOCK_DEPT + " AS VARCHAR(2000))||',') like '%," + departmentId + ",%'"; + } else if (rs.getDBType().equals("mysql")) { + sqlWhere=" and concat(','," + LOCK_DEPT + ",',') like '%," + departmentId + ",%'"; + } else { + sqlWhere=" and (','+CAST(" + LOCK_DEPT + " AS VARCHAR(2000))+',') like '%," + departmentId + ",%'"; + } + rs.writeLog("KQLockAttendaUtil>sql="+sql + sqlWhere); + rs.executeQuery(sql + sqlWhere); + if (rs.next()) { + String lockValue = rs.getString(LOCK_LOCK); + if(lockValue.equals("1")){ + return true; + }else{ + return false; + } + } + } + if (!"".equals(subcompanyId)) { + if (rs.getDBType().equals("oracle")||rs.getDBType().equals("postgresql")) { + sqlWhere=" and (','||CAST(" + LOCK_SUBCOM + " AS VARCHAR(2000))||',') like '%," + subcompanyId + ",%'"; + } else if (rs.getDBType().equals("mysql")) { + sqlWhere=" and concat(','," + LOCK_SUBCOM + ",',') like '%," + subcompanyId + ",%'"; + } else { + sqlWhere=" and (','+CAST(" + LOCK_SUBCOM + " AS VARCHAR(2000))+',') like '%," + subcompanyId + ",%'"; + } + rs.writeLog("KQLockAttendaUtil>sql="+sql + sqlWhere); + rs.executeQuery(sql + sqlWhere); + if (rs.next()) { + String lockValue = rs.getString(LOCK_LOCK); + if(lockValue.equals("1")){ + return true; + }else{ + return false; + } + } + } + sqlWhere=" and (" + LOCK_COM + "=1) "; + rs.writeLog("KQLockAttendaUtil>sql="+sql + sqlWhere); + rs.executeQuery(sql + sqlWhere); + if (rs.next()) { + String lockValue = rs.getString(LOCK_LOCK); + if(lockValue.equals("1")){ + return true; + }else{ + return false; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + /** + * 判断当前范围内是否存在已被锁定的日期 + * + * @param fromDate 开始日期 + * @param toDate 结束日期 + */ + public boolean isLockDate(String fromDate, String toDate) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + Date startDate = format.parse(fromDate); + Date endDate = format.parse(toDate); + for (KqLockAttenda datas : this.sdkqbb_map) { + Date ksrqDate = format.parse(datas.getLOCK_FROMDATE()); + Date jsrqDate = format.parse(datas.getLOCK_TODATE()); + if (isInterSection(startDate, endDate, ksrqDate, jsrqDate)) { + return true; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + /** + * 两个时间段是否存在交叉 + * + * @param startDateOne 第一个时间段的开始时间 + * @param endDateOne 第一个时间段的结束时间 + * @param startDateTwo 第二个时间段的开始时间 + * @param endDateTwo 第二个时间段的结束时间 + */ + private static boolean isInterSection(Date startDateOne, Date endDateOne, Date startDateTwo, Date endDateTwo) { + Date maxStartDate = startDateOne; + if (maxStartDate.before(startDateTwo)) { + maxStartDate = startDateTwo; + } + Date minEndDate = endDateOne; + if (endDateTwo.before(minEndDate)) { + minEndDate = endDateTwo; + } + return maxStartDate.before(minEndDate) || (maxStartDate.getTime() == minEndDate.getTime()); + } + + + + public boolean isLockDate(Map params) { + JSONObject jsonObj = JSON.parseObject(Util.null2String(params.get("data"))); + String fromDate = Util.null2String(jsonObj.getString("fromDate")); + String toDate = Util.null2String(jsonObj.getString("toDate")); + String typeselect = Util.null2String(jsonObj.getString("typeselect")); + if (typeselect.length() == 0) { + typeselect = "3"; + } + if (!typeselect.equals("0") && !typeselect.equals("6")) { + if (typeselect.equals("1")) { + fromDate = TimeUtil.getCurrentDateString(); + toDate = TimeUtil.getCurrentDateString(); + } else { + fromDate = TimeUtil.getDateByOption(typeselect, "0"); + toDate = TimeUtil.getDateByOption(typeselect, "1"); + } + } + return this.isLockDate(fromDate, toDate); + } + + /** + * 锁定日期范围内的考勤报表数据 + * + * @param params 参数 + * @param user 当前登录用户 + */ + public Map lockReport(Map params, User user) { + Map result = new HashMap<>(); + BaseBean baseBean = new BaseBean(); + JSONObject jsonObj = JSON.parseObject(Util.null2String(params.get("data"))); + String fromDate = Util.null2String(jsonObj.getString("fromDate")); + String toDate = Util.null2String(jsonObj.getString("toDate")); + String typeselect = Util.null2String(jsonObj.getString("typeselect")); + if (typeselect.length() == 0) { + typeselect = "3"; + } + if (!typeselect.equals("0") && !typeselect.equals("6")) { + if (typeselect.equals("1")) { + fromDate = TimeUtil.getCurrentDateString(); + toDate = TimeUtil.getCurrentDateString(); + } else { + fromDate = TimeUtil.getDateByOption(typeselect, "0"); + toDate = TimeUtil.getDateByOption(typeselect, "1"); + } + } + boolean lockDate = this.isLockDate(fromDate, toDate); + if (lockDate) { + result.put("status", "0"); + result.put("message", "当前日期范围内存在被锁定的数据,请重新选择日期范围!"); + return result; + } + // 保存锁定周期 + RecordSet recordSet = new RecordSet(); + String formModeId = baseBean.getPropValue("qc2648525", "sdkqbb.form.mode.id"); + String sql = "insert into uf_sdkqbb (ksrq, jsrq, sfsd, formmodeid) values ('" + fromDate + "', '" + toDate + "', 1, " + formModeId + ")"; + recordSet.execute(sql); +// RunnableTask runnableTask = new RunnableTask(user, fromDate, toDate, params, null, true, true); +// EXECUTOR_SERVICE.execute(runnableTask); +// String finalFromDate = fromDate; +// String finalToDate = toDate; +// new Thread(() -> { +// // 更新初始化缓存 +// this.sdkqbb_map = this.initModuleData(); +// // 未归档流程退回到发起节点 +// this.doForceOver(user); +// // 同步数据到建模表 +// this.syncKqData(user, finalFromDate, finalToDate, params); +// }).start(); + result.put("status", "1"); + result.put("message", "锁定成功!"); + return result; + } + + /** + * 强制归档 + */ + public void doForceOver(User user) { + BaseBean baseBean = new BaseBean(); + String workflowIds = baseBean.getPropValue("qc2648525", "kq.workflow.ids"); + RecordSet recordSet = new RecordSet(); + RecordSet newRecordSet = new RecordSet(); + String newSql = "select requestid, workflowid, requestnamenew from workflow_requestbase where workflowid in (" + workflowIds + ") and (currentnodetype = 1 or currentnodetype = 2)"; + String updateSql = "update workflow_requestbase set requestnamenew = ? where requestid = ?"; + recordSet.execute(newSql); + while (recordSet.next()) { + String requestId = Util.null2String(recordSet.getString("requestid")); + String workflowId = Util.null2String(recordSet.getString("workflowid")); + String requestNameNew = Util.null2String(recordSet.getString("requestnamenew")); + if (this.canContinueWorkflow(workflowId, requestId)) { + continue; + } + Map otherParams = new HashMap<>(); + otherParams.put("ismonitor", "1"); + ReqOperateRequestEntity reqOperateRequestEntity = new ReqOperateRequestEntity(); + reqOperateRequestEntity.setRequestId(Util.getIntValue(requestId)); + reqOperateRequestEntity.setRemark("流程日期存在被锁定的考勤数据,流程强制归档且不计入考勤数据"); + reqOperateRequestEntity.setOtherParams(otherParams); + this.doForceOver(user, reqOperateRequestEntity); + requestNameNew = "(已作废)" + requestNameNew; + newRecordSet.executeUpdate(updateSql, requestNameNew, requestId); + } + } + + /** + * 考勤数据同步到建模表 + * + * @param fromDate 开始日期 + * @param toDate 结束日期 + */ + public void syncKqData(User user, String fromDate, String toDate, Map params) { + try { + BigDecimal hourMins = new BigDecimal("60"); + ResourceComInfo resourceComInfo = new ResourceComInfo(); + RecordSet recordSet = new RecordSet(); + BatchRecordSet batchRecordSet = new BatchRecordSet(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + BaseBean baseBean = new BaseBean(); + String tableName = baseBean.getPropValue("qc2648525", "sync.table.name"); + String formModeId = baseBean.getPropValue("qc2648525", "sync.form.mode.id"); + KQReportBiz kqReportBiz = new KQReportBiz(); + List> allLeaveRules = KQLeaveRulesBiz.getAllLeaveRules(); + Map flowData = kqReportBiz.getDailyFlowData(params, user); + Date startDate = simpleDateFormat.parse(fromDate); + LocalDate l1 = LocalDate.parse(fromDate); + LocalDate l2 = LocalDate.parse(toDate); + long fromEpochDay = l1.toEpochDay(); + long toEpochDay = l2.toEpochDay(); + long diff = toEpochDay - fromEpochDay; + for (long i = 0; i <= diff; i++) { + List> values = new ArrayList<>(); + String syncDate = simpleDateFormat.format(DateUtil.addDay(startDate, (int) i)); + String newSql = "select * from kq_format_total where kqdate = ?"; + recordSet.executeQuery(newSql, syncDate); + while (recordSet.next()) { + List list = new ArrayList<>(); + list.add(formModeId); + String xm = recordSet.getString("resourceid"); + String gs = resourceComInfo.getSubCompanyID(xm); + String bm = resourceComInfo.getDepartmentID(xm); + String rq = recordSet.getString("kqdate"); + String bc = Util.null2s(recordSet.getString("serialid"), "-1"); + list.add(xm); + list.add(gs); + list.add(bm); + list.add(rq); + list.add(bc); + + Map signDetailInfo = getSignDetailInfo(xm, rq, user); + String sbdk1 = Util.null2s(Util.null2String(signDetailInfo.get("signintime1")), "-1"); + String qdkqjg1 = Util.null2s(Util.null2String(signDetailInfo.get("signinstatus1")), "-1"); + String xbdk1 = Util.null2s(Util.null2String(signDetailInfo.get("signouttime1")), "-1"); + String qtkqjg1 = Util.null2s(Util.null2String(signDetailInfo.get("signoutstatus1")), "-1"); + list.add(sbdk1); + list.add(qdkqjg1); + list.add(xbdk1); + list.add(qtkqjg1); + String sbdk2 = Util.null2s(Util.null2String(signDetailInfo.get("signintime2")), "-1"); + String qdkqjg2 = Util.null2s(Util.null2String(signDetailInfo.get("signinstatus2")), "-1"); + String xbdk2 = Util.null2s(Util.null2String(signDetailInfo.get("signouttime2")), "-1"); + String qtkqjg2 = Util.null2s(Util.null2String(signDetailInfo.get("signoutstatus2")), "-1"); + list.add(sbdk2); + list.add(qdkqjg2); + list.add(xbdk2); + list.add(qtkqjg2); + String sbdk3 = Util.null2s(Util.null2String(signDetailInfo.get("signintime3")), "-1"); + String qdkqjg3 = Util.null2s(Util.null2String(signDetailInfo.get("signinstatus3")), "-1"); + String xbdk3 = Util.null2s(Util.null2String(signDetailInfo.get("signouttime3")), "-1"); + String qtkqjg3 = Util.null2s(Util.null2String(signDetailInfo.get("signoutstatus3")), "-1"); + list.add(sbdk3); + list.add(qdkqjg3); + list.add(xbdk3); + list.add(qtkqjg3); + + double ycqts = Util.getDoubleValue(recordSet.getString("workdays"), 0); + BigDecimal ygzsc = new BigDecimal(Util.null2s(recordSet.getString("workmins"), "0")).divide(hourMins, 2, BigDecimal.ROUND_HALF_DOWN); + double sjcqts = Util.getDoubleValue(recordSet.getString("attendancedays"), 0); + BigDecimal sjgzsc = new BigDecimal(Util.null2s(recordSet.getString("attendanceMins"), "0")).divide(hourMins, 2, BigDecimal.ROUND_HALF_DOWN); + list.add(ycqts); + list.add(ygzsc.doubleValue()); + list.add(sjcqts); + list.add(sjgzsc.doubleValue()); + + double cd = Util.getDoubleValue(recordSet.getString("beLate"), 0); + BigDecimal cdsc = new BigDecimal(Util.null2s(recordSet.getString("beLateMins"), "0")).divide(hourMins, 2, BigDecimal.ROUND_HALF_DOWN); + double zt = Util.getDoubleValue(recordSet.getString("leaveEearly"), 0); + BigDecimal ztsc = new BigDecimal(Util.null2s(recordSet.getString("leaveEarlyMins"), "0")).divide(hourMins, 2, BigDecimal.ROUND_HALF_DOWN); + double kg = Util.getDoubleValue(recordSet.getString("absenteeism"), 0); + BigDecimal kgsc = new BigDecimal(Util.null2s(recordSet.getString("absenteeismMins"), "0")).divide(hourMins, 2, BigDecimal.ROUND_HALF_DOWN); + list.add(cd); + list.add(cdsc.doubleValue()); + list.add(zt); + list.add(ztsc.doubleValue()); + list.add(kg); + list.add(kgsc.doubleValue()); + + Map leaveInfo = getLeaveInfo(syncDate, xm, allLeaveRules, flowData); + double leaveType_2 = Util.getDoubleValue(leaveInfo.get("leaveType_2"), 0); + double leaveType_5 = Util.getDoubleValue(leaveInfo.get("leaveType_5"), 0); + double leaveType_6 = Util.getDoubleValue(leaveInfo.get("leaveType_6"), 0); + double leaveType_7 = Util.getDoubleValue(leaveInfo.get("leaveType_7"), 0); + double leaveType_8 = Util.getDoubleValue(leaveInfo.get("leaveType_8"), 0); + double leaveType_9 = Util.getDoubleValue(leaveInfo.get("leaveType_9"), 0); + double leaveType_10 = Util.getDoubleValue(leaveInfo.get("leaveType_10"), 0); + double leaveType_11 = Util.getDoubleValue(leaveInfo.get("leaveType_11"), 0); + double leaveType_12 = Util.getDoubleValue(leaveInfo.get("leaveType_12"), 0); + double leaveType_13 = Util.getDoubleValue(leaveInfo.get("leaveType_13"), 0); + double leaveType_14 = Util.getDoubleValue(leaveInfo.get("leaveType_14"), 0); + double leaveType_15 = Util.getDoubleValue(leaveInfo.get("leaveType_15"), 0); + double leaveType_16 = Util.getDoubleValue(leaveInfo.get("leaveType_16"), 0); + double leaveType_17 = Util.getDoubleValue(leaveInfo.get("leaveType_17"), 0); + list.add(leaveType_2); + list.add(leaveType_5); + list.add(leaveType_6); + list.add(leaveType_7); + list.add(leaveType_8); + list.add(leaveType_9); + list.add(leaveType_10); + list.add(leaveType_11); + list.add(leaveType_12); + list.add(leaveType_13); + list.add(leaveType_14); + list.add(leaveType_15); + list.add(leaveType_16); + list.add(leaveType_17); + + double bgldxgzrjb = Util.getDoubleValue(Util.null2String(flowData.get(xm + "|" + syncDate + "|workingDayOvertime_nonleave"))); + bgldxgzrjb = bgldxgzrjb < 0 ? 0 : bgldxgzrjb; + double bgldxzmjb = Util.getDoubleValue(Util.null2String(flowData.get(xm + "|" + syncDate + "|restDayOvertime_nonleave"))); + bgldxzmjb = bgldxzmjb < 0 ? 0 : bgldxzmjb; + double bgldxjjqjb = Util.getDoubleValue(Util.null2String(flowData.get(xm + "|" + syncDate + "|holidayOvertime_nonleave"))); + bgldxjjqjb = bgldxjjqjb < 0 ? 0 : bgldxjjqjb; + double gldxgzrjb = Util.getDoubleValue(Util.null2String(flowData.get(xm + "|" + syncDate + "|workingDayOvertime_4leave"))); + gldxgzrjb = gldxgzrjb < 0 ? 0 : gldxgzrjb; + double gldxzmjb = Util.getDoubleValue(Util.null2String(flowData.get(xm + "|" + syncDate + "|restDayOvertime_4leave"))); + gldxzmjb = gldxzmjb < 0 ? 0 : gldxzmjb; + double gldxjjrjb = Util.getDoubleValue(Util.null2String(flowData.get(xm + "|" + syncDate + "|holidayOvertime_4leave"))); + gldxjjrjb = gldxjjrjb < 0 ? 0 : gldxjjrjb; + double jbzj = Util.getDoubleValue(KQDurationCalculatorUtil.getDurationRound(String.valueOf(bgldxgzrjb + bgldxzmjb + bgldxjjqjb + gldxgzrjb + gldxzmjb + gldxjjrjb))); + list.add(bgldxgzrjb); + list.add(bgldxzmjb); + list.add(bgldxjjqjb); + list.add(gldxgzrjb); + list.add(gldxzmjb); + list.add(gldxjjrjb); + list.add(jbzj); + + double cc = Util.getDoubleValue(Util.null2String(flowData.get(xm + "|" + syncDate + "|businessLeave"))); + cc = cc < 0 ? 0 : cc; + double gc = Util.getDoubleValue(Util.null2String(flowData.get(xm + "|" + syncDate + "|officialBusiness"))); + gc = gc < 0 ? 0 : gc; + double lq1 = Util.getDoubleValue(recordSet.getString("forgotcheck"), 0); + double lq2 = Util.getDoubleValue(recordSet.getString("forgotBeginWorkCheck"), 0); + double lq = lq1 + lq2; + list.add(cc); + list.add(gc); + list.add(lq); + + values.add(list); + } + // 删除之前同步的数据 + newSql = "delete from " + tableName + " where rq = ?"; + recordSet.executeUpdate(newSql, syncDate); + // 同步新数据到到建模表 + newSql = "insert into " + tableName + "(formmodeid,xm,gs,bm,rq,bc,sbdk1,qdkqjg1,xbdk1,qtkqjg1,sbdk2,qdkqjg2,xbdk2,qtkqjg2,sbdk3,qdkqjg3,xbdk3,qtkqjg3,ycqts,ygzsc,sjcqts,sjgzsc,cd,cdsc,zt,ztsc,kg,kgsc,leaveType_2,leaveType_5,leaveType_6,leaveType_7,leaveType_8,leaveType_9,leaveType_10,leaveType_11,leaveType_12,leaveType_13,leaveType_14,leaveType_15,leaveType_16,leaveType_17,bgldxgzrjb,bgldxzmjb,bgldxjjqjb,gldxgzrjb,gldxzmjb,gldxjjrjb,jbzj,cc,gc,lq) " + + " values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + batchRecordSet.executeBatchSqlNew(newSql, values); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static Map getLeaveInfo(String kqdate, String id, List> allLeaveRules, Map flowData) { + Map map = new HashMap<>(); + for (int i = 0; allLeaveRules != null && i < allLeaveRules.size(); i++) { + Map leaveRule = allLeaveRules.get(i); + String flowType = Util.null2String("leaveType_" + leaveRule.get("id")); + String leaveData = Util.null2String(flowData.get(id + "|" + kqdate + "|" + flowType)); + String flowLeaveBackType = Util.null2String("leavebackType_" + leaveRule.get("id")); + String leavebackData = Util.null2s(Util.null2String(flowData.get(id + "|" + kqdate + "|" + flowLeaveBackType)), "0.0"); + String b_flowLeaveData = ""; + String flowLeaveData = ""; + try { + if (leaveData.length() == 0) { + leaveData = "0.0"; + } + if (leavebackData.length() == 0) { + leavebackData = "0.0"; + } + BigDecimal b_leaveData = new BigDecimal(leaveData); + BigDecimal b_leavebackData = new BigDecimal(leavebackData); + b_flowLeaveData = b_leaveData.subtract(b_leavebackData).toString(); + if (Util.getDoubleValue(b_flowLeaveData, -1) < 0) { + b_flowLeaveData = "0.0"; + } + } catch (Exception e) { + kqLog.info("GetKQReportCmd:leaveData" + leaveData + ":leavebackData:" + leavebackData + ":" + e); + } + if (b_flowLeaveData.length() > 0) { + flowLeaveData = KQDurationCalculatorUtil.getDurationRound(b_flowLeaveData); + } else { + flowLeaveData = KQDurationCalculatorUtil.getDurationRound(Util.null2String(Util.getDoubleValue(leaveData, 0.0) - Util.getDoubleValue(leavebackData, 0.0))); + } + map.put(flowType, flowLeaveData); + } + return map; + } + + public static Map getSignDetailInfo(String resourceId, String kqDate, User user) { + Map data = new HashMap<>(); + Map signStatusInfo = null; + RecordSet rs = new RecordSet(); + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + try { + String sql = " select kqdate,resourceid,serialid,serialnumber,workbegindate,workbegintime, " + + " workenddate,workendtime,workmins,signindate,signintime,signoutdate,signouttime, \n" + + " attendanceMins,belatemins,graveBeLateMins,leaveearlymins,graveLeaveEarlyMins,absenteeismmins,forgotcheckMins,forgotBeginWorkCheckMins," + + " leaveMins,leaveInfo,evectionMins,outMins,signinid,signoutid \n" + + " from kq_format_detail b \n" + + " where resourceid = " + resourceId + " and kqdate ='" + kqDate + "' \n" + + " order by serialnumber \n"; + rs.execute(sql); + while (rs.next()) { + String serialid = Util.null2String(rs.getString("serialid")); + int serialnumber = rs.getInt("serialnumber") + 1; + String workbegindate = Util.null2String(rs.getString("workbegindate")).trim(); + String workbegintime = Util.null2String(rs.getString("workbegintime")).trim(); + String workenddate = Util.null2String(rs.getString("workenddate")).trim(); + String workendtime = Util.null2String(rs.getString("workendtime")).trim(); + String signintime = Util.null2String(rs.getString("signintime")).trim(); + String signouttime = Util.null2String(rs.getString("signouttime")).trim(); + String beLateMins = Util.null2String(rs.getString("beLateMins")).trim(); + String graveBeLateMins = Util.null2String(rs.getString("graveBeLateMins")).trim(); + String leaveEarlyMins = Util.null2String(rs.getString("leaveEarlyMins")).trim(); + String graveLeaveEarlyMins = Util.null2String(rs.getString("graveLeaveEarlyMins")).trim(); + String absenteeismMins = Util.null2String(rs.getString("absenteeismMins")).trim(); + String forgotCheckMins = Util.null2String(rs.getString("forgotcheckMins")).trim(); + String forgotBeginWorkCheckMins = Util.null2String(rs.getString("forgotBeginWorkCheckMins")).trim(); + String signinid = Util.null2String(rs.getString("signinid")).trim(); + String signoutid = Util.null2String(rs.getString("signoutid")).trim(); + int leaveMins = rs.getInt("leaveMins"); + String leaveInfo = Util.null2String(rs.getString("leaveInfo")); + int evectionMins = rs.getInt("evectionMins"); + int outMins = rs.getInt("outMins"); + + if (serialid.length() > 0) { + if (workbegintime.length() > 0) { + signStatusInfo = new HashMap<>(); + signStatusInfo.put("workdate", workbegindate); + signStatusInfo.put("worktime", workbegintime); + signStatusInfo.put("beLateMins", beLateMins); + signStatusInfo.put("forgotBeginWorkCheckMins", forgotBeginWorkCheckMins); + signStatusInfo.put("graveBeLateMins", graveBeLateMins); + signStatusInfo.put("absenteeismMins", absenteeismMins); + signStatusInfo.put("leaveMins", leaveMins); + signStatusInfo.put("leaveInfo", leaveInfo); + signStatusInfo.put("evectionMins", evectionMins); + signStatusInfo.put("outMins", outMins); + data.put("signintime" + serialnumber, signintime.length() == 0 ? SystemEnv.getHtmlLabelName(25994, user.getLanguage()) : signintime); + data.put("signinstatus" + serialnumber, KQReportBiz.getSignStatus(signStatusInfo, user, "on")); + } + + if (workendtime.length() > 0) { + signStatusInfo = new HashMap<>(); + signStatusInfo.put("workdate", workenddate); + signStatusInfo.put("worktime", kqTimesArrayComInfo.turn48to24Time(workendtime)); + signStatusInfo.put("leaveEarlyMins", leaveEarlyMins); + signStatusInfo.put("graveLeaveEarlyMins", graveLeaveEarlyMins); + signStatusInfo.put("forgotCheckMins", forgotCheckMins); + signStatusInfo.put("forgotBeginWorkCheckMins", forgotBeginWorkCheckMins); + signStatusInfo.put("absenteeismMins", absenteeismMins); + signStatusInfo.put("leaveMins", leaveMins); + signStatusInfo.put("leaveInfo", leaveInfo); + signStatusInfo.put("evectionMins", evectionMins); + signStatusInfo.put("outMins", outMins); + data.put("signouttime" + serialnumber, signouttime.length() == 0 ? SystemEnv.getHtmlLabelName(25994, user.getLanguage()) : signouttime); + data.put("signoutstatus" + serialnumber, KQReportBiz.getSignStatus(signStatusInfo, user, "off")); + } + } else { + signStatusInfo = new HashMap(); + signStatusInfo.put("leaveMins", leaveMins); + signStatusInfo.put("leaveInfo", leaveInfo); + signStatusInfo.put("evectionMins", evectionMins); + signStatusInfo.put("outMins", outMins); + if (signinid.length() > 0) { + data.put("signintime" + serialnumber, signintime.length() == 0 ? SystemEnv.getHtmlLabelName(25994, user.getLanguage()) : signintime); + data.put("signinstatus" + serialnumber, KQReportBiz.getSignStatus(signStatusInfo, user, "on")); + if (signoutid.length() > 0) { + data.put("signouttime" + serialnumber, signouttime.length() == 0 ? SystemEnv.getHtmlLabelName(25994, user.getLanguage()) : signouttime); + data.put("signoutstatus" + serialnumber, KQReportBiz.getSignStatus(signStatusInfo, user, "off")); + } + } else { + data.put("signinstatus" + serialnumber, KQReportBiz.getSignStatus(signStatusInfo, user, "on")); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return data; + } + + + /** + * 考勤流程是否能继续提交 + * + * @param request 请求详情 + */ + public String canSubmitWorkflow(RequestInfo request) { + String requestId = request.getRequestid(); + String workflowId = request.getWorkflowid(); + kqLog.info("do canSubmitWorkflow on workflowId:" + workflowId + "|requestId:" + requestId); + if (canContinueWorkflow(workflowId, requestId)) { + return Action.SUCCESS; + } + request.getRequestManager().setMessageid("11111" + request.getRequestid() + "22222"); + request.getRequestManager().setMessagecontent("当前日期周期内存在被锁定的考勤数据,请重新选择日期周期!"); + return Action.FAILURE_AND_CONTINUE; + } + + /** + * 考勤流程能否继续提交 + * + * @param workflowId 流程id + * @param requestId 请求id + */ + public boolean canContinueWorkflow(String workflowId, String requestId) { + try { + int requestIdInt = Util.getIntValue(requestId, 0); + String formId = new WorkflowComInfo().getFormId(workflowId); + // 是否是考勤变更流程 + boolean isProcessChange = false; + // 是否是销假流程 + boolean isLeaveBack = false; + List splitBeans = new ArrayList<>(); + RecordSet recordSet = new RecordSet(); + String sql = "select * from kq_att_proc_set where field001 = ? and field002 = ? "; + recordSet.executeQuery(sql, workflowId, formId); + if (recordSet.next()) { + String proc_set_id = recordSet.getString("id"); + String useDetails = recordSet.getString("usedetail"); + int kqType = Util.getIntValue(recordSet.getString("field006")); + Map map = new HashMap<>(); + if (requestIdInt > 0) { + map.put("requestId", "and t.requestId = " + requestIdInt); + } + KQFlowActiontBiz kqFlowActiontBiz = new KQFlowActiontBiz(); + ResourceComInfo resourceComInfo = new ResourceComInfo(); + DateTimeFormatter datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + Map sqlMap = kqFlowActiontBiz.handleSql(proc_set_id, useDetails, requestIdInt, kqType, map); + if (kqType == KqSplitFlowTypeEnum.LEAVE.getFlowtype()) { + KQFlowLeaveUtil kqFlowLeaveUtil = new KQFlowLeaveUtil(); + kqFlowLeaveUtil.handleKQLeaveAction(sqlMap, splitBeans, datetimeFormatter, Util.getIntValue(workflowId), requestIdInt, resourceComInfo); + } else if (kqType == KqSplitFlowTypeEnum.EVECTION.getFlowtype()) { + KQFlowEvectionUtil kqFlowEvectionUtil = new KQFlowEvectionUtil(); + kqFlowEvectionUtil.handleKQEvectionAction(sqlMap, splitBeans, datetimeFormatter, Util.getIntValue(workflowId), requestIdInt, resourceComInfo); + } else if (kqType == KqSplitFlowTypeEnum.OUT.getFlowtype()) { + KQFlowOutUtil kqFlowOutUtil = new KQFlowOutUtil(); + kqFlowOutUtil.handleKQOutAction(sqlMap, splitBeans, datetimeFormatter, Util.getIntValue(workflowId), requestIdInt, resourceComInfo); + } else if (kqType == KqSplitFlowTypeEnum.OVERTIME.getFlowtype()) { + KQFlowOvertimeUtil kqFlowOvertimeUtil = new KQFlowOvertimeUtil(); + kqFlowOvertimeUtil.handleKQOvertimeAction(sqlMap, splitBeans, datetimeFormatter, Util.getIntValue(workflowId), requestIdInt, resourceComInfo, ""); + } else if (kqType == KqSplitFlowTypeEnum.CARD.getFlowtype()) { + String[] cardFields = KQAttFlowFieldsSetBiz.cardFields; + RecordSet newRecordSet = new RecordSet(); + if (!sqlMap.isEmpty()) { + for (Map.Entry entry : sqlMap.entrySet()) { + String value = entry.getValue(); + newRecordSet.execute(value); + while (newRecordSet.next()) { + String fDetailSignDate = cardFields[3]; + String signDate = Util.null2s(newRecordSet.getString(fDetailSignDate), ""); + if (this.isLockDate(signDate, signDate)) { + return false; + } + } + } + } + } else if (kqType == KqSplitFlowTypeEnum.LEAVEBACK.getFlowtype()) { + isLeaveBack = true; + KQFlowLeaveBackUtil kqFlowLeaveBackUtil = new KQFlowLeaveBackUtil(); + kqFlowLeaveBackUtil.handleKQLeaveBackAction(sqlMap, splitBeans, datetimeFormatter, Util.getIntValue(workflowId), requestIdInt, resourceComInfo); + } else if (kqType == KqSplitFlowTypeEnum.PROCESSCHANGE.getFlowtype()) { + isProcessChange = true; + KQFlowProcessChangeUtil kqFlowProcessChangeUtil = new KQFlowProcessChangeUtil(); + kqFlowProcessChangeUtil.handleKQProcessChangeAction(sqlMap, splitBeans, datetimeFormatter, Util.getIntValue(workflowId), requestIdInt, resourceComInfo); + } + } + for (SplitBean splitBean : splitBeans) { + String fromDate = ""; + String toDate = ""; + if (isProcessChange) { + ProcessChangeSplitBean processChangeSplitBean = splitBean.getProcessChangeSplitBean(); + fromDate = processChangeSplitBean.getFromdatedb(); + toDate = processChangeSplitBean.getTodatedb(); + if (this.isLockDate(fromDate, toDate)) { + return false; + } + fromDate = splitBean.getFromdatedb(); + toDate = splitBean.getTodatedb(); + } else if (isLeaveBack) { + String resourceId = splitBean.getResourceId(); + String leaveBackRequestId = splitBean.getLeavebackrequestid(); + sql = "select fromdatedb, todatedb from kq_flow_split_leave where resourceid = ? and requestid = ? group by fromdatedb, todatedb"; + recordSet.executeQuery(sql, resourceId, leaveBackRequestId); + if (recordSet.next()) { + fromDate = Util.null2String(recordSet.getString("fromdatedb")); + toDate = Util.null2String(recordSet.getString("todatedb")); + } + } else { + fromDate = splitBean.getFromdatedb(); + toDate = splitBean.getTodatedb(); + } + if (this.isLockDate(fromDate, toDate)) { + return false; + } + } + } catch (Exception e) { + return false; + } + return true; + } + + /** + * 强制归档 + * + * @param user 用户 + * @param requestParam 请求参数 + */ + public void doForceOver(User user, ReqOperateRequestEntity requestParam) { + int requestId = requestParam.getRequestId(); + Map otherParams = requestParam.getOtherParams(); + PAResponseEntity pAEntity = RequestOperateBiz.verifyBefore(user, requestId, otherParams); + if (pAEntity.getCode() != null) { + return; + } + WfFunctionManageUtil wfFunctionManageUtil = new WfFunctionManageUtil(); + RequestInfoEntity reqEntity = RequestOperateBiz.initRequestInfo(requestParam, user); + int isremark = reqEntity.getIsremark(); + int agentType = Util.getIntValue(Util.null2String(otherParams.get("agenttype"))); + int agentorByAgentId = Util.getIntValue(Util.null2String(otherParams.get("agentorbyagentid"))); + // 流程代理出去,本人提交,需先收回代理 + if (isremark == 2 && agentType == 1 && agentorByAgentId > 0) { + AgentManager agentManager = new AgentManager(user); + agentManager.agentBackRequest(agentorByAgentId, user.getUID(), reqEntity.getWorkflowId() + "", requestParam.getRequestId()); + reqEntity = RequestOperateBiz.initRequestInfo(requestParam, user); + isremark = reqEntity.getIsremark(); + } + int nodeid = Util.getIntValue(reqEntity.getCurrentNodeId()); + int takisremark = reqEntity.getTakisremark(); + HashMap map = wfFunctionManageUtil.wfFunctionManageByNodeid(reqEntity.getWorkflowId(), FreeNodeBiz.isFreeNode(nodeid) ? -9 : nodeid); + WfForceOver wfo = new WfForceOver(); + String ov = (String) map.get("ov"); + boolean hasRight = (isremark == 0 && (takisremark == 0 || takisremark == -1)) && "1".equals(ov) && wfo.isNodeOperator(requestId, user.getUID()) && !reqEntity.getCurrentNodeType().equals("3"); + boolean isMonitor = "1".equals(Util.null2String(otherParams.get("ismonitor"))); + if (!hasRight && isMonitor) { + MonitorDTO monitorInfo = new Monitor().getMonitorInfo(String.valueOf(user.getUID()), reqEntity.getCreatorId(), String.valueOf(reqEntity.getWorkflowId())); + hasRight = monitorInfo.getIsforceover() && !"3".equals(reqEntity.getCurrentNodeType()); + } + if (hasRight) { + ArrayList requestidlist = new ArrayList(); + requestidlist.add("" + requestId); + wfo.setRemark(requestParam.getRemark()); + wfo.doForceOver(requestidlist, null, null, user); + pAEntity.setCode(PAResponseCode.SUCCESS); + String isnew = new BaseBean().getPropValue("WorkflowOvertimeIsNew", "isNew"); + if ("1".equals(isnew)) { + OvertimeBiz.getInstance().cancelOvertimeTask(requestId, Util.getIntValue(reqEntity.getCurrentNodeId()));// 取消超时任务 + } + } else { + pAEntity.setCode(PAResponseCode.NO_PERMISSION); + } + } + + /** + * 同步建模表里面的打卡数据 + */ + public void importData() { + RecordSet rs = new RecordSet(); + String endDateTime = weaver.common.DateUtil.getDate(new Date(), "yyyy-MM-dd HH:mm"); + Calendar calendar = weaver.common.DateUtil.getCalendar(endDateTime); + calendar.add(Calendar.MINUTE, -45); + String startDateTime = weaver.common.DateUtil.getDate(calendar.getTime(), "yyyy-MM-dd HH:mm"); + + KQScheduleSignImport kqScheduleSignImport = new KQScheduleSignImport(); + BatchRecordSet bRs = new BatchRecordSet(); + List> lsParams = new ArrayList<>(); + List params = null; + List> lsDelParams = new ArrayList<>(); + List delParams = null; + List lsFormatData = new ArrayList<>(); + List> lsFormatParams = new ArrayList<>(); + List formatParams = null; + Map> users = kqScheduleSignImport.getUsers(7); + Map loginidMap = users.get("loginidMap"); + Map lastnameMap = users.get("lastnameMap"); + Map workcodeMap = users.get("workcodeMap"); + List keymap = new ArrayList<>(); + List lsImportSetting = new ArrayList<>(); + ImportSetting importSetting = null; + String sql = " select datasourceid, loginid, workcode, lastname, signdate, signtime, tablename, clientaddress,longitude,latitude,addr,memo from HrmScheduleSignSet "; + rs.execute(sql); + while (rs.next()) { + importSetting = new ImportSetting(); + importSetting.setDatasourceid(Util.null2String(rs.getString("datasourceid")).trim()); + importSetting.setLoginid(Util.null2String(rs.getString("loginid")).trim()); + importSetting.setWorkcode(Util.null2String(rs.getString("workcode")).trim()); + importSetting.setLastname(Util.null2String(rs.getString("lastname")).trim()); + importSetting.setSigndate(Util.null2String(rs.getString("signdate")).trim()); + importSetting.setSigntime(Util.null2String(rs.getString("signtime")).trim()); + importSetting.setTablename(Util.null2String(rs.getString("tablename")).trim()); + importSetting.setClientaddress(Util.null2String(rs.getString("clientaddress")).trim()); + importSetting.setLongitude(Util.null2String(rs.getString("longitude")).trim()); + importSetting.setLatitude(Util.null2String(rs.getString("latitude")).trim()); + importSetting.setAddr(Util.null2String(rs.getString("addr")).trim()); + importSetting.setMemo(Util.null2String(rs.getString("memo")).trim()); + lsImportSetting.add(importSetting); + } + List lsKQScheduleSignData = new ArrayList<>(); + KQScheduleSignEntity kqScheduleSignData = null; + for (int i = 0; i < lsImportSetting.size(); i++) { + try { + importSetting = lsImportSetting.get(i); + String datasourceid = importSetting.getDatasourceid(); + String loginid = importSetting.getLoginid(); + String workcode = importSetting.getWorkcode(); + String lastname = importSetting.getLastname(); + String signdate = importSetting.getSigndate(); + String signtime = importSetting.getSigntime(); + String tablename = importSetting.getTablename(); + String clientaddress = importSetting.getClientaddress(); + String longitude = importSetting.getLongitude(); + String latitude = importSetting.getLatitude(); + String addr = importSetting.getAddr(); + String memo = importSetting.getMemo(); + DateFormat df = new SimpleDateFormat("HH:mm:ss"); + if ("sqlserver".equals(rs.getDBType())) { + sql = "select * from " + tablename + " where " + " " + signdate + "+' '+" + signtime + " >= '" + startDateTime + "' and " + signdate + "+' '+" + signtime + " <= '" + endDateTime + "' "; + } else { + sql = "select * from " + tablename + " where " + " concat(" + signdate + ",' '," + signtime + ") >= '" + startDateTime + "' and concat(" + signdate + ",' '," + signtime + ") <= '" + endDateTime + "' "; + } + // 有遇到外部同步,上面的【conn = ds.getConnection();】这个阻塞住,导致下面的同步不执行,下面的用法和集成领导确认 + RecordSetDataSource rsds = new RecordSetDataSource(datasourceid); + rsds.execute(sql); + while (rsds.next()) { + String tmpLoginid = ""; + String tmpWorkcode = ""; + String tmpLastname = ""; + String tmpSigndate = ""; + String tmpSigntime = ""; + String tmpClientaddress = ""; + String tmpLongitude = ""; + String tmpLatitude = ""; + String tmpAddr = ""; + String tmpMemo = ""; + if (loginid.length() > 0) { + tmpLoginid = Util.null2String(rsds.getString(loginid)).trim(); + } + if (workcode.length() > 0) { + tmpWorkcode = Util.null2String(rsds.getString(workcode)).trim(); + } + if (lastname.length() > 0) { + tmpLastname = Util.null2String(rsds.getString(lastname)).trim(); + } + if (signdate.length() > 0) { + tmpSigndate = Util.null2String(rsds.getString(signdate)).trim(); + } + if (clientaddress.length() > 0) { + tmpClientaddress = Util.null2String(rsds.getString(clientaddress)); + } + if (longitude.length() > 0) { + tmpLongitude = Util.null2String(rsds.getString(longitude)).trim(); + } + if (latitude.length() > 0) { + tmpLatitude = Util.null2String(rsds.getString(latitude)).trim(); + } + if (addr.length() > 0) { + tmpAddr = Util.null2String(rsds.getString(addr)).trim(); + } + if (memo.length() > 0) { + tmpMemo = Util.null2String(rsds.getString(memo)).trim(); + } + if (signtime.length() > 0) { + tmpSigntime = Util.null2String(rsds.getString(signtime)).trim(); + // 判断tmpSigntime格式 08:21:11 如果为长格式需要格式化 + if (tmpSigntime.length() > 8) { + // 有遇到signtime格式为hh:mm:ss.0000的格式导致同步不成功 + if (tmpSigntime.length() < 16) { + tmpSigntime = tmpSigntime.substring(0, 8); + } + // 比如上yyyy-mm-dd hh:mm的格式走原逻辑 + else { + tmpSigntime = df.format(Timestamp.valueOf(tmpSigntime)); + } + } else if (tmpSigntime.length() < 8) { + // 不带秒的情况 自动补齐 + tmpSigntime += ":00"; + } + } else { + tmpSigntime = ""; + } + + if (tmpSigndate.length() > 10) { + // 如果时间为长格式,从signdate字段中格式化时间 + if (tmpSigndate.length() == 16) { + //不带秒的情况 自动补齐 + tmpSigntime += ":00"; + } + // 以signtime字段为有限 + if (tmpSigntime.length() == 0) { + tmpSigndate = tmpSigndate.length() > 19 ? tmpSigndate.substring(0, 19) : tmpSigndate; + tmpSigntime = df.format(Timestamp.valueOf(tmpSigndate)); + } + tmpSigndate = Tools.formatDate(tmpSigndate, "yyyy-MM-dd"); + } + // 如果时间格式不带秒补齐 + if (tmpSigntime.length() <= 5) { + tmpSigntime += ":00"; + } + kqScheduleSignData = new KQScheduleSignEntity(); + kqScheduleSignData.setLoginid(tmpLoginid); + kqScheduleSignData.setWorkcode(tmpWorkcode); + kqScheduleSignData.setLastname(tmpLastname); + kqScheduleSignData.setSigndate(tmpSigndate); + kqScheduleSignData.setSigntime(tmpSigntime); + kqScheduleSignData.setClientaddress(tmpClientaddress); + kqScheduleSignData.setLongitude(tmpLongitude); + kqScheduleSignData.setLatitude(tmpLatitude); + kqScheduleSignData.setAddr(tmpAddr); + kqScheduleSignData.setMemo(tmpMemo); + lsKQScheduleSignData.add(kqScheduleSignData); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + List noRepertSynData = new ArrayList<>(); + for (int i = 0; i < lsKQScheduleSignData.size(); i++) { + kqScheduleSignData = lsKQScheduleSignData.get(i); + String tmpLoginid = kqScheduleSignData.getLoginid(); + String tmpWorkcode = kqScheduleSignData.getWorkcode(); + String tmpLastname = kqScheduleSignData.getLastname(); + String tmpSigndate = kqScheduleSignData.getSigndate(); + String tmpSigntime = kqScheduleSignData.getSigntime(); + String tmpClientaddress = kqScheduleSignData.getClientaddress(); + String tmpLongitude = kqScheduleSignData.getLongitude(); + String tmpLatitude = kqScheduleSignData.getLatitude(); + String tmpAddr = kqScheduleSignData.getAddr(); + String tmpMemo = kqScheduleSignData.getMemo(); + int userid = 0; + if (Util.null2String(tmpLoginid).length() > 0) { + userid = weaver.common.StringUtil.parseToInt(loginidMap.get(tmpLoginid), 0); + } + if (userid == 0 && Util.null2String(tmpWorkcode).length() > 0) { + userid = weaver.common.StringUtil.parseToInt(workcodeMap.get(tmpWorkcode), 0); + } + if (userid == 0 && Util.null2String(tmpLastname).length() > 0) { + userid = weaver.common.StringUtil.parseToInt(lastnameMap.get(tmpLastname), 0); + } + if (userid <= 0) { + continue; + } + String dkParamData = userid + "#" + tmpSigndate + "#" + tmpSigntime; + if (noRepertSynData.contains(dkParamData)) { + continue; + } + noRepertSynData.add(dkParamData); + params = new ArrayList<>(); + params.add(userid); + params.add(1); + params.add(tmpSigndate); + params.add(tmpSigntime); + params.add(tmpClientaddress); + params.add(1); + params.add(1); + params.add("OutDataSourceSyn"); + params.add(tmpLongitude); + params.add(tmpLatitude); + params.add(tmpAddr); + params.add(tmpMemo); + lsParams.add(params); + String belongDate = getBelongDate(new User(userid), tmpSigndate, tmpSigntime); + String formatData = userid + "|" + tmpSigndate + "|" + belongDate; + if (!lsFormatData.contains(formatData)) { + lsFormatData.add(formatData); + } + } + Map> overtimeMap = Maps.newHashMap(); + List overtimeList = Lists.newArrayList(); + // 刷新报表数据 + for (int i = 0; i < lsFormatData.size(); i++) { + formatParams = new ArrayList<>(); + String key = lsFormatData.get(i); + String[] formatData = Util.splitString(lsFormatData.get(i), "|"); + String date_1 = weaver.common.DateUtil.addDate(formatData[1], -1); + formatParams.add(formatData[0]); + formatParams.add(date_1); + lsFormatParams.add(formatParams); + formatParams = new ArrayList<>(); + formatParams.add(formatData[0]); + formatParams.add(formatData[1]); + lsFormatParams.add(formatParams); + if (!keymap.contains(key)) { + keymap.add(key); + delParams = new ArrayList<>(); + delParams.add(formatData[0]); + // delParams.add(formatData[1]); + delParams.add(startDateTime + ":00"); + delParams.add(endDateTime + ":00"); + lsDelParams.add(delParams); + } + String resourceId = formatData[0]; + String kqdate = formatData[1]; + String belongDate = formatData[2]; + if (overtimeMap.containsKey(resourceId)) { + List tmp_overtimeList = overtimeMap.get(resourceId); + if (!tmp_overtimeList.contains(kqdate)) { + tmp_overtimeList.add(kqdate); + if (!kqdate.equals(belongDate)) { + tmp_overtimeList.add(belongDate); + } + } + } else { + if (!overtimeList.contains(kqdate)) { + overtimeList.add(kqdate); + if (!kqdate.equals(belongDate)) { + overtimeList.add(belongDate); + } + } + overtimeMap.put(resourceId, overtimeList); + } + } + // 删除本次同步数据 + // sql = " delete from hrmschedulesign where signfrom='OutDataSourceSyn' and userid =? and signdate = ? "; + if ("sqlserver".equals(rs.getDBType())) { + sql = "delete from hrmschedulesign where signfrom = 'OutDataSourceSyn' and userid = ? and signdate + ' ' + signtime >= ? and signdate + ' ' + signtime <= ?"; + } else { + sql = "delete from hrmschedulesign where signfrom = 'OutDataSourceSyn' and userid = ? and concat(signdate,' ',signtime) >= ? and concat(signdate,' ',signtime) <= ?"; + } + bRs.executeBatchSql(sql, lsDelParams); + sql = " insert into HrmScheduleSign (userid, usertype, signdate, signtime, clientaddress, isincom, isimport, signfrom, longitude, latitude, addr,memo) values(?,?,?,?,?,?,?,?,?,?,?,?)"; + bRs.executeBatchSql(sql, lsParams); + new KQFormatBiz().format(lsFormatParams); + // 处理加班生成 + List tasks = new ArrayList<>(); + for (Map.Entry> mme : overtimeMap.entrySet()) { + String resid = mme.getKey(); + List overList = mme.getValue(); + for (String date : overList) { + SplitActionUtil.pushOverTimeTasks(date, date, resid, tasks); + } + } + if (!tasks.isEmpty()) { + KQQueue.writeTasks(tasks); + } + } + + public String getBelongDate(User user, String curDate, String signDateTime) { + String belongDate = curDate; + Map todayLineMap = KQDurationCalculatorUtil.getWorkButton(user, curDate, true); + if (todayLineMap != null) { + List> preInfo = (ArrayList>) todayLineMap.get("pre_signTime"); + if (preInfo != null) { + for (Map entry : preInfo) { + String pre_endtime_across = entry.get("endtime_across"); + String pre_endtime = entry.get("endtime"); + String signEndInfo = "1".equals(pre_endtime_across) ? (curDate + " " + pre_endtime + ":00") : (weaver.common.DateUtil.addDate(curDate, -1) + " " + pre_endtime + ":00"); + String signOutDateTime = signDateTime; + if (signOutDateTime.compareTo(signEndInfo) < 0) { + belongDate = weaver.common.DateUtil.addDate(curDate, -1); + } + } + } + } + return belongDate; + } + + /** + * 线程池执行任务封装 + */ +// public static class RunnableTask implements Runnable { +// +// private final User user; +// +// private final boolean isSyncData; +// +// private final boolean isDoForceOver; +// +// private final String finalFromDate; +// +// private final String finalToDate; +// +// private Map params; +// +// private final List> formatValues; +// +// public RunnableTask(User user, String finalFromDate, String finalToDate, Map params, List> formatValues, boolean isSyncData, boolean isDoForceOver) { +// this.user = user; +// this.finalFromDate = finalFromDate; +// this.finalToDate = finalToDate; +// this.params = params; +// this.formatValues = formatValues; +// this.isSyncData = isSyncData; +// this.isDoForceOver = isDoForceOver; +// } +// +// @Override +// public void run() { +// BaseBean baseBean = new BaseBean(); +// QC2648525Util qc2648525Util = new QC2648525Util(); +// if (formatValues != null && formatValues.size() > 0) { +// long startTime = System.currentTimeMillis(); +// for (List objs : formatValues) { +// String userId = Util.null2String(objs.get(0)); +// String kqDate = Util.null2String(objs.get(1)); +// new KQFormatData().formatKqDate(userId, kqDate); +// } +// baseBean.writeLog("QC2648525 刷新考勤报表耗时:" + ((System.currentTimeMillis() - startTime) / 1000) + "秒"); +// } +// if (isDoForceOver) { +// long startTime = System.currentTimeMillis(); +// qc2648525Util.doForceOver(user); +// baseBean.writeLog("QC2648525 强制归档流程执行耗时:" + ((System.currentTimeMillis() - startTime) / 1000) + "秒"); +// } +// if (isSyncData) { +// long startTime = System.currentTimeMillis(); +// if (params == null || params.isEmpty()) { +// Map datas = new HashMap<>(); +// datas.put("typeselect", "6"); +// datas.put("fromDate", finalFromDate); +// datas.put("toDate", finalToDate); +// datas.put("attendanceSerial", ""); +// datas.put("isFromMyAttendance", "1"); +// params = new HashMap<>(); +// params.put("data", JSONObject.toJSONString(datas)); +// params.put("reportType", "month"); +// } +// qc2648525Util.syncKqData(user, finalFromDate, finalToDate, params); +// baseBean.writeLog("QC2648525 建模数据同步执行耗时:" + ((System.currentTimeMillis() - startTime) / 1000) + "秒"); +// } +// } +// } + + // --- 王宇负责部分 --- + + public static String[] colors = new String[]{"#47A9FC", "#70C06F", "#F6D65C", "#EA744D", "#4EBCCC", "#EA5C85", "#8F72F2", "#7297F2", "#CA4DE4", "#A7CC62"}; + + public static String getKQGroupId(String userId, String workDate, boolean containFixed) { + String groupId = ""; + KQGroupComInfo kqGroupComInfo = new KQGroupComInfo(); + KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo(); + List lsGroupIds = kqGroupMemberComInfo.getKQGroups(userId,workDate); + for (int i = 0; lsGroupIds != null && i < lsGroupIds.size(); i++) { + String tmpGroupId = Util.null2String((String) lsGroupIds.get(i)); + String kqtype = kqGroupComInfo.getKqtype(tmpGroupId); + String validity = kqGroupComInfo.getValidity(tmpGroupId); + String validityfromdate = kqGroupComInfo.getValidityfromdate(tmpGroupId); + String validityenddate = kqGroupComInfo.getValidityenddate(tmpGroupId); + if (validity.equals("1")) { + if (weaver.common.DateUtil.isInDateRange(workDate, validityfromdate, validityenddate)) { + groupId = tmpGroupId; + } else { + continue; + } + } else { + groupId = tmpGroupId; + } + if (groupId.length() > 0) { + if (containFixed && kqtype.equals("2")) { + KQShiftScheduleComInfo kqShiftScheduleComInfo = new KQShiftScheduleComInfo(); + if (Util.null2String(kqShiftScheduleComInfo.getSerialId(userId, workDate)).length() > 0 && Util.null2String(kqShiftScheduleComInfo.getGroupId(userId, workDate)).equals(groupId)) { + break; + } + } else { + break; + } + } + } + return groupId; + } + + /** + * 从考勤报表中获取班次 + * + * @param resourceId 用户 + * @param kqDate 日期 + * @param groupId 原来的groupId + */ + public static String getGroupId(String resourceId, String kqDate, String groupId) { + + String newGroupId = ""; + String currentDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); + if (kqDate.compareTo(currentDate) > 0) { + return groupId; + } + RecordSet recordSet = new RecordSet(); + String sql = "select groupid from kq_format_total where resourceid = ? and kqdate = ?"; + recordSet.executeQuery(sql, resourceId, kqDate); + if (recordSet.next()) { + newGroupId = Util.null2String(recordSet.getString("groupid")); + } + return StringUtil.isBlank(newGroupId) ? groupId : newGroupId; + } + + /** + * 前台我的排班颜色添加 + * + * @param user 登录用户 + * @param resourceId 展示的用户id + * @param fromDate 开始日期 + * @param toDate 结束日期 + * @param result 结果集 + */ + public static void getScheduleReportInfo(User user, String resourceId, String fromDate, String toDate, Map result) { + RecordSet recordSet = new RecordSet(); + KQGroupComInfo kqGroupComInfo = new KQGroupComInfo(); + ShiftManagementToolKit shiftManagementToolKit = new ShiftManagementToolKit(); + KQWorkTime kqWorkTime = new KQWorkTime(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String sql = ""; + Map data = null; + String currentDate = weaver.common.DateUtil.getCurrentDate(); + // 今天之前的日期在考勤报表中查询 + if (fromDate.compareTo(currentDate) <= 0) { + // 结束日期小于当前日期 当前日期=结束日期 + if (toDate.compareTo(currentDate) < 0) { + LocalDate localDate = LocalDate.parse(toDate); + currentDate = formatter.format(localDate); + } + sql = "select kqdate, groupid, serialid from kq_format_total where resourceid = ? and kqdate >= ? and kqdate <= ?"; + recordSet.executeQuery(sql, resourceId, fromDate, currentDate); + while (recordSet.next()) { + String date = Util.null2String(recordSet.getString("kqdate")); + String serialId = Util.null2String(recordSet.getString("serialid")); + String groupId = Util.null2String(recordSet.getString("groupid")); + if (StringUtil.isBlank(serialId)) { + continue; + } + String color = ""; + String kqType = kqGroupComInfo.getKqtype(groupId); + if ("1".equals(kqType)) { + color = getColorBySerialId(kqGroupComInfo, groupId, serialId); + } else if ("2".equals(kqType)) { + color = getColorBySerialId(kqGroupComInfo, groupId, serialId); + } + String serial = shiftManagementToolKit.getShiftOnOffWorkSections(serialId, user.getLanguage()); + data = new HashMap<>(); + data.put("serial", serial); + data.put("bgColor", color); + result.put(date, data); + } + } + // 今天之后的日期 固定班次保持不变,排班在排班表中查询 + currentDate = weaver.common.DateUtil.getCurrentDate(); + + if (toDate.compareTo(currentDate) >= 0) { + + // 开始日期大于当前日期 当前日期=开始日期 + LocalDate localDate; + if (fromDate.compareTo(currentDate) > 0) { + localDate = LocalDate.parse(fromDate); + } else { + localDate = LocalDate.parse(currentDate).plusDays(1); + } + currentDate = formatter.format(localDate); + String kqGroupId = getKQGroupId(resourceId, currentDate, true); + LocalDate startDate = LocalDate.parse(currentDate); + LocalDate endDate = LocalDate.parse(toDate); + KQHolidaySetComInfo kqHolidaySetComInfo = new KQHolidaySetComInfo(); + long sd = startDate.toEpochDay(); + long ed = endDate.toEpochDay(); + long diff = ed - sd; + for (long i = 0; i <= diff; i++) { + LocalDate td = startDate.plusDays(i); + String targetDate = formatter.format(td); + String changeType = kqHolidaySetComInfo.getChangeType(kqGroupId, targetDate); + if ("1".equals(changeType) || "3".equals(changeType)) { + continue; + } + WorkTimeEntity workTime = kqWorkTime.getWorkTime(resourceId, targetDate); + String serialId = workTime.getSerialId(); + if (serialId != null) { + data = new HashMap<>(); + String serial = shiftManagementToolKit.getShiftOnOffWorkSections(serialId, user.getLanguage()); + data.put("serial", serial); + data.put("bgColor", "#000"); + result.put(targetDate, data); + } + } + } + } + + public static String getColorBySerialId(KQGroupComInfo kqGroupComInfo, String groupId, String serialId) { + String color = ""; + String serialIds = kqGroupComInfo.getSerialids(groupId); + if (StringUtil.isNotBlank(serialIds)) { + String[] serialArr = serialIds.split(","); + for (int i = 0; i < serialArr.length; i++) { + if (serialArr[i].trim().equals(serialId)) { + color = colors[i]; + break; + } + } + } + return color; + } + + /** + * 星期 + * + * @param date 日期 + */ + public static int getDayOfWeek(String date) { + try { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + // 创建Calendar类实例 + Calendar instance = Calendar.getInstance(); + // 根据指定日期获取周几 + instance.setTime(format.parse(date)); + // 因为数组下标从0开始,而返回的是数组的内容,是数组{1,2,3,4,5,6,7}中用1~7来表示 Saturday->7 + int i = instance.get(Calendar.DAY_OF_WEEK); + if (i >= Calendar.MONDAY && i <= Calendar.FRIDAY) { + i = i - 2; + } else if (i == Calendar.SATURDAY) { + i = 5; + } else if (i == Calendar.SUNDAY) { + i = 6; + } + return i; + } catch (Exception e) { + return -1; + } + } + +}