diff --git a/src/com/engine/kq/biz/KQFlowActiontBiz.java b/src/com/engine/kq/biz/KQFlowActiontBiz.java new file mode 100644 index 0000000..dc4d1d3 --- /dev/null +++ b/src/com/engine/kq/biz/KQFlowActiontBiz.java @@ -0,0 +1,1017 @@ +package com.engine.kq.biz; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.engine.kq.biz.chain.duration.WorkDayUnitSplitChain; +import com.engine.kq.biz.chain.duration.WorkDurationChain; +import com.engine.kq.biz.chain.duration.WorkHalfUnitSplitChain; +import com.engine.kq.biz.chain.duration.WorkHourUnitSplitChain; +import com.engine.kq.biz.chain.duration.WorkWholeUnitSplitChain; +import com.engine.kq.biz.chain.shiftinfo.ShiftInfoBean; +import com.engine.kq.entity.TimeScopeEntity; +import com.engine.kq.entity.WorkTimeEntity; +import com.engine.kq.enums.DurationTypeEnum; +import com.engine.kq.enums.KqSplitFlowTypeEnum; +import com.engine.kq.log.KQLog; +import com.engine.kq.wfset.attendance.manager.HrmAttProcSetManager; +import com.engine.kq.wfset.bean.SplitBean; +import com.engine.kq.wfset.util.*; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.general.Util; +import weaver.hrm.resource.ResourceComInfo; + +/** + * 考勤流程action相关数据处理类 + */ +public class KQFlowActiontBiz { + public KQLog kqLog = new KQLog(); + + /** + * 强制收回操作 + * @param requestId + */ + public void handleDel(int requestId) { + RecordSet rs = new RecordSet(); + try { + String updateFreezeSql = "update KQ_ATT_VACATION set status=2 where requestId=? "; + boolean isUpdate = rs.executeUpdate(updateFreezeSql,requestId); + }catch (Exception e){ + e.printStackTrace(); + rs.writeLog("handleDrawBack:删除action报错:"+e.getMessage()); + } + } + /** + * 强制收回操作 + * @param requestId + * @param workflowId + */ + public void handleDrawBack(int requestId, int workflowId) { + kqLog.writeLog("handleDrawBack:进入 强制收回:requestId:"+requestId+":workflowId:"+workflowId); + + RecordSet rs = new RecordSet(); + try { + String updateFreezeSql = "update KQ_ATT_VACATION set status=2 where requestId=? and workflowId = ? "; + boolean isUpdate = rs.executeUpdate(updateFreezeSql,requestId,workflowId); + kqLog.writeLog("handleDrawBack:强制收回isUpdate:"+isUpdate+":updateFreezeSql:"+updateFreezeSql+":requestId:"+requestId+":workflowId:"+workflowId); + }catch (Exception e){ + e.printStackTrace(); + kqLog.writeLog("handleDrawBack:强制收回action报错:"+e.getMessage()); + } + } + + /** + * 强制归档操作 + * @param requestId + * @param workflowId + */ + public void handleforceOver(int requestId, int workflowId) { + RecordSet rs = new RecordSet(); + try { + if(!KQSettingsBiz.isforceflow_attend()){ + return ; + } + String proc_set_sql = "select * from kq_att_proc_set where field001 = ? "; + rs.executeQuery(proc_set_sql, workflowId); + if(rs.next()) { + String proc_set_id = rs.getString("id"); + //得到这个考勤流程设置是否使用明细 + String usedetails = rs.getString("usedetail"); + int kqtype = Util.getIntValue(rs.getString("field006")); + kqLog.info("handleforceOver:proc_set_id:"+proc_set_id+":kqtype:"+kqtype+":requestId:"+requestId); + Map map = new HashMap(); + if(requestId > 0){ + map.put("requestId", "and t.requestId = " + requestId); + } + Map result = handleKQFlowAction(proc_set_id,usedetails,requestId,kqtype,workflowId,true,false,map); + if(!result.isEmpty()){ + kqLog.info("handleforceOver:强制归档action失败:requestId:"+requestId+":workflowId:"+workflowId+":proc_set_id:"+proc_set_id); + } + } + }catch (Exception e){ + e.printStackTrace(); + kqLog.info("handleforceOver:强制归档action报错:"+e.getMessage()); + } + } + + public Map handleKQFlowAction(String proc_set_id, String usedetails, int requestId, int kqtype, + int workflowId,boolean isForce,boolean isUpgrade,Map map) throws Exception{ + Map result = new HashMap<>(); + ResourceComInfo rci = new ResourceComInfo(); + List splitBeans = new ArrayList(); + + DateTimeFormatter datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + //生成处理的sql + Map sqlMap = handleSql(proc_set_id, usedetails, requestId,kqtype,map); + if(sqlMap != null && !sqlMap.isEmpty()){ + KqSplitFlowTypeEnum flowTypeEnum = null; + if(kqtype == KqSplitFlowTypeEnum.LEAVE.getFlowtype()){ + KQFlowLeaveUtil kqFlowLeaveUtil = new KQFlowLeaveUtil(); + result=kqFlowLeaveUtil.handleKQLeaveAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + flowTypeEnum = KqSplitFlowTypeEnum.LEAVE; + }else if(kqtype == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){ + KQFlowEvectionUtil kqFlowEvectionUtil = new KQFlowEvectionUtil(); + result=kqFlowEvectionUtil.handleKQEvectionAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + //flowTypeEKQFlowActiontBiz.javaowTypeEnum.EVECTION; + }else if(kqtype == KqSplitFlowTypeEnum.OUT.getFlowtype()){ + KQFlowOutUtil kqFlowOutUtil = new KQFlowOutUtil(); + result=kqFlowOutUtil.handleKQOutAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + flowTypeEnum = KqSplitFlowTypeEnum.OUT; + }else if(kqtype == KqSplitFlowTypeEnum.OVERTIME.getFlowtype()){ + KQFlowOvertimeUtil kqFlowOvertimeUtil = new KQFlowOvertimeUtil(); + result=kqFlowOvertimeUtil.handleKQOvertimeAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci,""); + flowTypeEnum = KqSplitFlowTypeEnum.OVERTIME; + }else if(kqtype == KqSplitFlowTypeEnum.SHIFT.getFlowtype()){ + KQFlowShiftUtil kqFlowShiftUtil = new KQFlowShiftUtil(); + result = kqFlowShiftUtil.handleKQShiftAction2(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci,result,map); + flowTypeEnum = KqSplitFlowTypeEnum.SHIFT; + }else if(kqtype == KqSplitFlowTypeEnum.OTHER.getFlowtype()){ + KQFlowOtherUtil kqFlowOtherUtil = new KQFlowOtherUtil(); + result=kqFlowOtherUtil.handleKQOtherAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + flowTypeEnum = KqSplitFlowTypeEnum.OTHER; + }else if(kqtype == KqSplitFlowTypeEnum.CARD.getFlowtype()){ + KQFlowCardUtil kqFlowCardUtil = new KQFlowCardUtil(); + result=kqFlowCardUtil.handleKQCardAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + flowTypeEnum = KqSplitFlowTypeEnum.CARD; + }else if(kqtype == KqSplitFlowTypeEnum.LEAVEBACK.getFlowtype()){ + KQFlowLeaveBackUtil kqFlowLeaveBackUtil = new KQFlowLeaveBackUtil(); + result=kqFlowLeaveBackUtil.handleKQLeaveBackAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + flowTypeEnum = KqSplitFlowTypeEnum.LEAVEBACK; + }else if(kqtype == KqSplitFlowTypeEnum.PROCESSCHANGE.getFlowtype()){ + KQFlowProcessChangeUtil kqFlowProcessChangeUtil = new KQFlowProcessChangeUtil(); + result=kqFlowProcessChangeUtil.handleKQProcessChangeAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + flowTypeEnum = KqSplitFlowTypeEnum.PROCESSCHANGE; + }else{ + new BaseBean().writeLog("考勤流程没有找到对应类型:proc_set_id:"+proc_set_id+":requestId:"+requestId+":kqtype:"+kqtype); + } + if(!result.isEmpty()){ + if(!isUpgrade){ + return result; + } + } + if(!splitBeans.isEmpty() && flowTypeEnum != null){ + if(flowTypeEnum == KqSplitFlowTypeEnum.LEAVEBACK){ + KQFlowLeaveBackUtil kqFlowLeaveBackUtil = new KQFlowLeaveBackUtil(); + //销假流程需要再拆分下 + kqFlowLeaveBackUtil.handleSplitFLowActionData4LeaveBack(splitBeans,result,isUpgrade,requestId); + clear_flow_deduct_card(splitBeans,KqSplitFlowTypeEnum.LEAVEBACK.getFlowtype()+"",requestId); + }else if(flowTypeEnum == KqSplitFlowTypeEnum.PROCESSCHANGE){ + KQFlowProcessChangeUtil kqFlowProcessChangeUtil = new KQFlowProcessChangeUtil(); + kqFlowProcessChangeUtil.handleSplitFLowActionData4ProcessChange(splitBeans,result,isUpgrade,requestId); + }else if(flowTypeEnum != KqSplitFlowTypeEnum.CARD && flowTypeEnum != KqSplitFlowTypeEnum.SHIFT){ + KQFlowUtil kqFlowUtil = new KQFlowUtil(); + kqFlowUtil.handleSplitFLowActionData(splitBeans,flowTypeEnum,rci,result,isForce,requestId,workflowId,isUpgrade); + //流程抵扣打卡 + handle_flow_deduct_card(workflowId,splitBeans,requestId); + } + } + } + return result; + } + + /** + * 流程抵扣打卡逻辑 + * @param workflowId + * @param splitBeans + * @param requestId + */ + public void handle_flow_deduct_card(int workflowId, + List splitBeans, int requestId) { + KQAttProcSetComInfo kqAttProcSetComInfo = new KQAttProcSetComInfo(); + String flow_deduct_card = Util.null2String(kqAttProcSetComInfo.getFlow_deduct_card(""+workflowId)); + String kqType = Util.null2String(kqAttProcSetComInfo.getkqType(""+workflowId)); + kqLog.info("handle_flow_deduct_card:flow_deduct_card:"+ flow_deduct_card+":workflowId:"+workflowId+":requestId:"+requestId); + if("1".equalsIgnoreCase(flow_deduct_card)){ + do_flow_deduct_card(splitBeans,kqType,requestId); + }else{ +// 这里扩展个操作,如果没有开启就先把对应的requestid删除掉 + if(requestId > 0){ + RecordSet rs = new RecordSet(); + String sql1 = "select * from kq_flow_deduct_card where requestid = ? "; + rs.executeQuery(sql1,requestId); + List formateList = new ArrayList<>(); + while (rs.next()){ + String resourceid = rs.getString("resourceid"); + String belongdate = rs.getString("belongdate"); + String key = resourceid+"_"+belongdate; + formateList.add(key); + } + String sql = "delete from kq_flow_deduct_card where requestid = ? "; + rs.executeUpdate(sql, requestId); + kqLog.info("clear_flow_deduct_card:formateList:"+formateList); + for(String format: formateList){ + kqLog.info("clear_flow_deduct_card:format:"+ JSON.toJSONString(format)); + String[] formats = format.split("_"); + new KQFormatData().formatKqDate(formats[0],formats[1]); + } + } + } + } + + /** + * 销假流程 消除流程抵扣打卡 + * @param splitBeans + * @param kqType + * @param requestId + */ + public void clear_flow_deduct_card(List splitBeans, String kqType, int requestId) { + RecordSet rs = new RecordSet(); + RecordSet rs1 = new RecordSet(); + List clear_ids = new ArrayList<>(); + List formateList = new ArrayList<>(); + List updateParamList = new ArrayList(); + List updateList = new ArrayList(); + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + for(SplitBean bean : splitBeans){ + String leavebackrequestid = bean.getLeavebackrequestid(); + String resourceId = bean.getResourceId(); + String belongDate = bean.getBelongDate(); + String fromdate = bean.getFromDate(); + String fromtime = bean.getFromTime(); + String todate = bean.getToDate(); + String totime = bean.getToTime(); + String key = resourceId+"_"+belongDate; + formateList.add(key); + int fromtimeIdx = kqTimesArrayComInfo.getArrayindexByTimes(fromtime); + int totimeIdx = kqTimesArrayComInfo.getArrayindexByTimes(totime); + String deduct_sql = "select * from kq_flow_deduct_card where requestid = '"+leavebackrequestid+"' and resourceId='"+resourceId+"' and belongDate='"+belongDate+"'"; + rs.executeQuery(deduct_sql); + while(rs.next()){ + String deduct_id = rs.getString("id"); + String signtype = rs.getString("signtype"); + String deduct_fromtime = rs.getString("fromtime"); + String deduct_totime = rs.getString("totime"); + int deduct_fromtimeIdx = kqTimesArrayComInfo.getArrayindexByTimes(deduct_fromtime); + int deduct_totimeIdx = kqTimesArrayComInfo.getArrayindexByTimes(deduct_totime); + updateList = new ArrayList(); + if("1".equalsIgnoreCase(signtype)){ + if(fromtimeIdx == deduct_fromtimeIdx && !clear_ids.contains(deduct_id)){ + clear_ids.add(deduct_id); + updateList.add(deduct_id); + updateParamList.add(updateList); + } + }else if("2".equalsIgnoreCase(signtype)){ + if(totimeIdx == deduct_totimeIdx && !clear_ids.contains(deduct_id)){ + clear_ids.add(deduct_id); + updateList.add(deduct_id); + updateParamList.add(updateList); + } + } + } + } + kqLog.info("clear_flow_deduct_card:clear_ids:"+ clear_ids.size()); +// if(!clear_ids.isEmpty()){ +// for(String id : clear_ids){ +// String sql = "update kq_flow_deduct_card set isclear=1 where id = "+id; +// rs1.executeUpdate(sql); +// } + /*更新抵扣打卡数据 start*/ + boolean isSuccess = true; + String updateSql = "update kq_flow_deduct_card set isclear=1 where id=?"; + if (updateParamList.size() > 0) { + isSuccess = rs1.executeBatchSql(updateSql, updateParamList); + kqLog.info("clear_flow_deduct_card:formateList:"+formateList); + for(String format: formateList){ + kqLog.info("clear_flow_deduct_card:format:"+ JSON.toJSONString(format)); + String[] formats = format.split("_"); + new KQFormatData().formatKqDate(formats[0],formats[1]); + } + } + /*更新抵扣打卡数据 end*/ + +// } + } + + /** + * 流程抵扣打卡逻辑 + * @param splitBeans + * @param kqType + * @param requestId + */ + public void do_flow_deduct_card(List splitBeans, String kqType, int requestId) { + RecordSet rs = new RecordSet(); + RecordSet rs1 = new RecordSet(); + String batchSql = "insert into kq_flow_deduct_card(requestid,resourceid,belongDate,fromdate,fromtime,todate,totime,workBeginTime,workEndTime,signtype,flowtype,serialnumber)"+ + " values(?,?,?,?,?,?,?,?,?,?,?,?) "; + List params = new ArrayList(); + List formateList = new ArrayList<>(); + kqLog.info("handle_flow_deduct_card:splitBeans:"+ JSON.toJSONString(splitBeans)); + for(SplitBean bean : splitBeans){ + do_flow_deduct_in_table(bean,formateList,params,kqType,requestId, ""); + + if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){ + String companion = Util.null2s(bean.getCompanion(), ""); + if(companion.length() > 0){ + String[] companions = companion.split(","); + if(companions != null && companions.length > 0 ) { + for (int i = 0; i < companions.length; i++) { + String compan_resid = companions[i]; + if(bean.getResourceId().equalsIgnoreCase(compan_resid)){ + //陪同人是自己的不要存到中间表里 + continue; + } + do_flow_deduct_in_table(bean,formateList,params,kqType,requestId,compan_resid); + } + } + } + } + } + if(!params.isEmpty()) { + //先根据requestid删除中间表里的数据,再做啥插入操作 + String delSql = "delete from kq_flow_deduct_card where requestid = " + requestId; + rs.executeUpdate(delSql); + boolean isOk = rs1.executeBatchSql(batchSql, params); + if(!isOk){ + kqLog.info("do_flow_deduct_card:requestId:"+requestId+":kq_flow_deduct_card error:"+params); + return ; + } + kqLog.info("do_flow_deduct_card:formateList:"+formateList); + for(String format: formateList){ + kqLog.info("do_flow_deduct_card:format:"+ JSON.toJSONString(format)); + String[] formats = format.split("_"); + new KQFormatData().formatKqDate(formats[0],formats[1]); + } + }else{ + if(!splitBeans.isEmpty()){ + //有流程数据,但是签到签退都不包含的情况,支持多次归档,所以需要先删除再插入 + String delSql = "delete from kq_flow_deduct_card where requestid = " + requestId; + rs.executeUpdate(delSql); + } + } + } + + /** + * 流程抵扣打卡数据整合到表里 + * @param bean + * @param formateList + * @param params + * @param kqType + * @param requestId + * @param compan_resid 出差流程的陪同人 + */ + public void do_flow_deduct_in_table(SplitBean bean, List formateList, + List params, String kqType, int requestId, String compan_resid) { + KQWorkTime kqWorkTime = new KQWorkTime(); + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + String resourceId = bean.getResourceId(); + if(compan_resid.length() > 0 && Util.getIntValue(kqType) == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){ + resourceId = compan_resid; + } + String belongDate = bean.getBelongDate(); + String fromdate = bean.getFromDate(); + String fromtime = bean.getFromTime(); + String todate = bean.getToDate(); + String totime = bean.getToTime(); + boolean oneSign = false; + WorkTimeEntity workTime = kqWorkTime.getWorkTime(resourceId, belongDate); + String key = resourceId+"_"+belongDate; + formateList.add(key); + List lsWorkTime = new ArrayList<>(); + List lsSignTime = new ArrayList<>(); + if (workTime != null) { + lsWorkTime = workTime.getWorkTime();//工作时间 + lsSignTime = workTime.getSignTime();//允许打卡时间 + oneSign = lsWorkTime!=null&&lsWorkTime.size()==1; + for (int i = 0; lsWorkTime != null && i < lsWorkTime.size(); i++) { + TimeScopeEntity workTimeScope = lsWorkTime.get(i); + String workBeginTime = Util.null2String(workTimeScope.getBeginTime()); + int workBeginIdx = kqTimesArrayComInfo.getArrayindexByTimes(workBeginTime); + boolean workBenginTimeAcross = workTimeScope.getBeginTimeAcross(); + String workEndTime = Util.null2String(workTimeScope.getEndTime()); + int workEndIdx = kqTimesArrayComInfo.getArrayindexByTimes(workEndTime); + boolean workEndTimeAcross = workTimeScope.getEndTimeAcross(); + int[] dayMins = new int[2880];//一天所有分钟数 + int beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(fromtime)); + int endIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(totime)); + if(beginIdx > endIdx){ + continue; + } + if(oneSign){ + boolean is_flow_humanized = KQSettingsBiz.is_flow_humanized(); + if(is_flow_humanized){ + //个性化设置只支持一天一次上下班 + ShiftInfoBean shiftInfoBean = new ShiftInfoBean(); + Map shifRuleMap = Maps.newHashMap(); + shiftInfoBean.setSplitDate(belongDate); + shiftInfoBean.setShiftRuleMap(workTime.getShiftRuleInfo()); + shiftInfoBean.setSignTime(lsSignTime); + shiftInfoBean.setWorkTime(lsWorkTime); + KQShiftRuleInfoBiz.getShiftRuleInfo(shiftInfoBean, resourceId, shifRuleMap); + if(!shifRuleMap.isEmpty()){ + 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); + } + } + 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); + } + } + } + } + } + if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){ + Arrays.fill(dayMins, beginIdx, endIdx, 7);//出差抵扣时段标识 7 + }else if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.OUT.getFlowtype()){ + Arrays.fill(dayMins, beginIdx, endIdx, 8);//公出抵扣时段标识 8 + }else if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.LEAVE.getFlowtype()){ + if (endIdx > beginIdx) { + Arrays.fill(dayMins, beginIdx, endIdx, 5);//流程抵扣时段标识 5 + } + }else{ + if (endIdx > beginIdx) { + Arrays.fill(dayMins, beginIdx, endIdx, 99);//异常流程抵扣时段标识99 + } + } + + int cnt_7 = kqTimesArrayComInfo.getCnt(dayMins, workBeginIdx, workEndIdx, 7); + int cnt_8 = kqTimesArrayComInfo.getCnt(dayMins, workBeginIdx, workEndIdx, 8); + int cnt_5 = kqTimesArrayComInfo.getCnt(dayMins, workBeginIdx, workEndIdx, 5); + int cnt_99 = kqTimesArrayComInfo.getCnt(dayMins, workBeginIdx, workEndIdx, 99); + //流程时长大于0的才去做流程抵扣的处理 + if(cnt_7 > 0 || cnt_8 > 0 || cnt_5 > 0 || cnt_99 > 0){ + //如果流程时长大于0 结束时间因为是下标,需要补1分钟 + if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){ + Arrays.fill(dayMins, endIdx, endIdx+1, 7);//出差抵扣时段标识 7 + }else if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.OUT.getFlowtype()){ + Arrays.fill(dayMins, endIdx, endIdx+1, 8);//公出抵扣时段标识 8 + }else if(Util.getIntValue(kqType) == KqSplitFlowTypeEnum.LEAVE.getFlowtype()){ + Arrays.fill(dayMins, endIdx, endIdx+1, 5);//流程抵扣时段标识 5 + }else{ + Arrays.fill(dayMins, endIdx, endIdx+1, 99);//异常流程抵扣时段标识99 + } + + if(dayMins[workBeginIdx]>=5){//签到时间点有流程 + List beanParams = new ArrayList(); + beanParams.add(requestId); + beanParams.add(resourceId); + beanParams.add(belongDate); + beanParams.add(fromdate); + beanParams.add(fromtime); + beanParams.add(todate); + beanParams.add(totime); + beanParams.add(workBeginTime); + beanParams.add(workEndTime); + beanParams.add("1"); + beanParams.add(kqType); + beanParams.add(i); + params.add(beanParams); + } + + if(dayMins[workEndIdx]>=5){//签退时间点有流程 + List beanParams = new ArrayList(); + beanParams.add(requestId); + beanParams.add(resourceId); + beanParams.add(belongDate); + beanParams.add(fromdate); + beanParams.add(fromtime); + beanParams.add(todate); + beanParams.add(totime); + beanParams.add(workBeginTime); + beanParams.add(workEndTime); + beanParams.add("2"); + beanParams.add(kqType); + beanParams.add(i); + params.add(beanParams); + } + }else{ + kqLog.info("handle_flow_deduct_card::i:"+i+":workBeginIdx:"+ workBeginIdx+":workEndIdx:"+ workEndIdx + +":cnt_7:"+cnt_7+":cnt_8:"+cnt_8+":cnt_5:"+cnt_5+":cnt_99:"+cnt_99); + } + } + }else{ + kqLog.info("handle_flow_deduct_card:workTime is null :resourceId:"+ resourceId+":belongDate:"+belongDate); + } + } + + + /** + * 拆分请假数据 生成splitBeans + * @param sqlMap + * @param splitBeans + * @param datetimeFormatter + * @param workflowId + * @param requestId + * @param rci + * @param durationTypeEnum + * @return + * @throws Exception + */ + public Map handleAction(Map sqlMap, + List splitBeans, DateTimeFormatter datetimeFormatter, int workflowId, + int requestId, ResourceComInfo rci,DurationTypeEnum durationTypeEnum) throws Exception{ + RecordSet rs1 = new RecordSet(); + KQFlowUtil kqFlowUtil = new KQFlowUtil(); + Map result = new HashMap<>(); + + if(!sqlMap.isEmpty()){ + for(Map.Entry me : sqlMap.entrySet()){ + String key = me.getKey(); + String value = me.getValue(); + + rs1.execute(value); + while (rs1.next()) { + SplitBean splitBean = new SplitBean(); + boolean isFillRight = kqFlowUtil.fillSplitBean(splitBean, rs1, ""+requestId, rci, ""+workflowId, durationTypeEnum,key,result,datetimeFormatter, + ""); + if(!isFillRight){ + new BaseBean().writeLog("升级失败:"+requestId+";;result>>>"+JSONObject.toJSONString(result)); + continue ; + } + if(result.containsKey("isProcessDrawBack")){ + result.clear(); + splitBeans.add(splitBean); + }else{ + doWorkSplitChain(splitBean, splitBeans); + } + + if(durationTypeEnum == DurationTypeEnum.EVECTION){ + String companion = Util.null2s(splitBean.getCompanion(), ""); + if(companion.length() > 0){ + List companionList = Util.splitString2List(companion,","); + for(int i = 0 ; i < companionList.size() ; i++){ + String be_companion = Util.null2String(companionList.get(i)); + if(be_companion.length() > 0 && Util.getIntValue(be_companion) > 0){ + SplitBean compSplitBean = new SplitBean(); + boolean compFillRight = kqFlowUtil.fillSplitBean(compSplitBean, rs1, ""+requestId, + rci, ""+workflowId, durationTypeEnum,key,result,datetimeFormatter, ""); + if(!compFillRight){ + return result; + } + if(splitBean.getResourceId().equalsIgnoreCase(be_companion)){ + //陪同人是自己的不要存到中间表里 + continue; + } + compSplitBean.setResourceId(be_companion); + compSplitBean.setSubcompanyid(Util.null2s(rci.getSubCompanyID(be_companion),"0")); + compSplitBean.setDepartmentid(Util.null2s(rci.getDepartmentID(be_companion),"0")); + compSplitBean.setJobtitle(Util.null2s(rci.getJobTitle(be_companion),"0")); + compSplitBean.setIscompanion("1"); + compSplitBean.setCompanion(""); + + if(result.containsKey("isProcessDrawBack")){ + result.clear(); + splitBeans.add(compSplitBean); + }else{ + doWorkSplitChain(compSplitBean, splitBeans); + } + } + } + } + } + } + } + } + return result; + } + + /** + * 生成处理的sql + * @param proc_set_id + * @param usedetails + * @param requestidInt + * @return + */ + public Map handleSql(String proc_set_id,String usedetails,int requestidInt,int kqtype,Map map) { + HrmAttProcSetManager hrmAttProcSetManager= new HrmAttProcSetManager(); + Map sqlMap = new HashMap<>(); + sqlMap = hrmAttProcSetManager.getSQLByField006Map(kqtype, map, false, true, proc_set_id,usedetails); + + return sqlMap; + } + + /** + * 计算工作时长拆分 + * @param splitBean + * @param splitBeans + * @throws Exception + */ + public void doWorkSplitChain(SplitBean splitBean,List splitBeans) throws Exception{ + + WorkDurationChain hourUnitSplitChain = new WorkHourUnitSplitChain(splitBeans); + WorkDurationChain dayUnitSplitChain = new WorkDayUnitSplitChain(splitBeans); + WorkDurationChain halfUnitSplitChain = new WorkHalfUnitSplitChain(splitBeans); + WorkDurationChain wholeUnitSplitChain = new WorkWholeUnitSplitChain(splitBeans); + + //设置执行链 + hourUnitSplitChain.setDurationChain(dayUnitSplitChain); + dayUnitSplitChain.setDurationChain(halfUnitSplitChain); + halfUnitSplitChain.setDurationChain(wholeUnitSplitChain); + //把初始数据设置进去 + hourUnitSplitChain.handleDuration(splitBean); + } + + /** + * 测试流程,删除测试数据的同时 + * 1、需要把冻结数据释放 + * 2、中间表数据清除 + * 3、格式化考勤报表 + * @param temprequestid + * @param workflowid + */ + public void delTest(int temprequestid, String workflowid,String from) { + RecordSet rs = new RecordSet(); + RecordSet rs1 = new RecordSet(); + RecordSet rs2 = new RecordSet(); + RecordSet rs3 = new RecordSet(); + try { + + kqLog.info("KQFlowActiontBiz delTest:workflowid:"+workflowid+":from:"+from); + if(Util.null2s(workflowid,"").length() == 0){ + return ; + } + + String getkqType = "select * from kq_att_proc_set where field001=? "; + rs.executeQuery(getkqType,workflowid); + if(rs.next()){ + boolean isCard = false; + boolean isOvertime = false; + boolean isLeave = false; + String tablename = ""; + + //add + String carddate = ""; + String maintablename = ""; + String detailtablename = ""; + String proc_set_id = ""; + String usedetails = ""; + Map map = new HashMap(); + + int kqtype= Util.getIntValue(rs.getString("field006"),-1); + if(kqtype == KqSplitFlowTypeEnum.LEAVE.getFlowtype()){ + tablename = KqSplitFlowTypeEnum.LEAVE.getTablename(); + isLeave = true; + }else if(kqtype == KqSplitFlowTypeEnum.EVECTION.getFlowtype()){ + tablename = KqSplitFlowTypeEnum.EVECTION.getTablename(); + }else if(kqtype == KqSplitFlowTypeEnum.OUT.getFlowtype()){ + tablename = KqSplitFlowTypeEnum.OUT.getTablename(); + }else if(kqtype == KqSplitFlowTypeEnum.OVERTIME.getFlowtype()){ + tablename = KqSplitFlowTypeEnum.OVERTIME.getTablename(); + isOvertime = true; + }else if(kqtype == KqSplitFlowTypeEnum.SHIFT.getFlowtype()){ + tablename = KqSplitFlowTypeEnum.SHIFT.getTablename(); + }else if(kqtype == KqSplitFlowTypeEnum.OTHER.getFlowtype()){ + tablename = KqSplitFlowTypeEnum.OTHER.getTablename(); + }else if(kqtype == KqSplitFlowTypeEnum.CARD.getFlowtype()){ + tablename = KqSplitFlowTypeEnum.CARD.getTablename(); + isCard = true; + + //add + proc_set_id = rs.getString("id"); + //得到这个考勤流程设置是否使用明细 + usedetails = rs.getString("usedetail"); + maintablename = rs.getString("tablename"); + detailtablename = rs.getString("detailtablename"); + if(temprequestid > 0){ + map.put("requestId", "and t.requestId = " + temprequestid); + } + //end + + }else if(kqtype == KqSplitFlowTypeEnum.LEAVEBACK.getFlowtype()){ + tablename = KqSplitFlowTypeEnum.LEAVEBACK.getTablename(); + }else{ + new BaseBean().writeLog("删除测试流程异常,未找到考勤流程类型:workflowid:"+workflowid); + } + if(tablename.length() > 0){ + KQFormatBiz kqFormatBiz = new KQFormatBiz(); + + List formateList = new ArrayList<>(); + if(isCard){ + + if(detailtablename.length()>0){ + KQFlowActiontBiz kqFlowActiontBiz = new KQFlowActiontBiz(); + boolean isForce1 = false; + boolean isUpgrade1 = false; + + Map sqlMap = handleSql(proc_set_id, usedetails, temprequestid,kqtype,map); + + KQFlowCardUtil kqFlowCardUtil = new KQFlowCardUtil(); + ResourceComInfo rci = new ResourceComInfo(); + List splitBeans = new ArrayList(); + + DateTimeFormatter datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + Map result=delCardAction(sqlMap,splitBeans,datetimeFormatter,Util.getIntValue(workflowid),temprequestid,rci); + + } + }else if(isOvertime){ + SplitActionUtil.clearSameRequestTX(temprequestid+""); + String delTableSql = "delete from "+tablename+" where requestId= ? "; + boolean isUpdate = rs2.executeUpdate(delTableSql,temprequestid); + kqLog.info("KQFlowActiontBiz delTest:delTableSql:"+delTableSql+":temprequestid:"+temprequestid+":isUpdate:"+isUpdate); + }else{ + List backsplitBeans = new ArrayList<>(); + String sql = "select * from "+tablename+" where requestId= ? "; + rs2.executeQuery(sql, temprequestid); + kqLog.info("KQFlowActiontBiz delTest:sql:"+sql+":requestId:"+temprequestid+":counts:"+rs2.getCounts()); + while (rs2.next()){ + String resourceid = rs2.getString("resourceid"); + String belongdate = rs2.getString("belongdate"); + String key = resourceid+"_"+belongdate; + formateList.add(key); + if(isLeave) { + SplitBean splitBean = new SplitBean(); + String requestid = rs2.getString("requestid"); + String newLeaveType = rs2.getString("newleavetype"); + String duration = rs2.getString("duration"); + String durationrule = rs2.getString("durationrule"); + String fromdatedb = rs2.getString("fromdatedb"); + splitBean.setRequestId(requestid); + splitBean.setResourceId(resourceid); + splitBean.setNewLeaveType(newLeaveType); + splitBean.setDuration(duration); + splitBean.setDurationrule(durationrule); + splitBean.setFromdatedb(fromdatedb); + backsplitBeans.add(splitBean); + } + } + kqLog.info("KQFlowActiontBiz delTest:isLeave:"+isLeave+":backsplitBeans:"+JSON.toJSONString(backsplitBeans)); + String delTableSql = "delete from "+tablename+" where requestId= ? "; + boolean isUpdate = rs2.executeUpdate(delTableSql,temprequestid); + kqLog.info("KQFlowActiontBiz delTest:delTableSql:"+delTableSql+":temprequestid:"+temprequestid+":isUpdate:"+isUpdate); + //如果有流程抵扣,删除对应流程抵扣的数据 + String delSql = "delete from kq_flow_deduct_card where requestid = ? "; + isUpdate = rs3.executeUpdate(delSql,temprequestid); + kqLog.info("KQFlowActiontBiz delTest:delSql:"+delSql+":temprequestid:"+temprequestid+":isUpdate:"+isUpdate); + + kqLog.info("KQFlowActiontBiz delTest:formateList:"+formateList); + for(String formateStr : formateList){ + String[] formateStrs = formateStr.split("_"); + new KQFormatData().formatKqDate(formateStrs[0],formateStrs[1]); + } + if(isLeave) { + for (SplitBean splitBean : backsplitBeans) { + String requestid = splitBean.getRequestId(); + String resourceId = splitBean.getResourceId(); + String newLeaveType = splitBean.getNewLeaveType(); + String duration = splitBean.getDuration(); + String durationrule = splitBean.getDurationrule(); + String fromdatedb = splitBean.getFromdatedb(); + boolean isLeaveFlowOver = isLeaveFlowOver(requestid); + kqLog.info("isLeaveFlowOver:"+isLeaveFlowOver); + if (isLeaveFlowOver) { + kqLog.info("流程退回后主动返还假期:delTest:resourceId:" + resourceId + ":duration:" + duration + ":newLeaveType:" + newLeaveType + ":durationrule:" + durationrule + ":requestid:" + requestid + ":fromdatedb:" + fromdatedb); + KQBalanceOfLeaveBiz.reduceUsedAmount(resourceId, fromdatedb, newLeaveType, duration, "", requestid); + } + } + String updateFreezeSql = "update KQ_ATT_VACATION set status=2 where requestId=? "; + isUpdate = rs1.executeUpdate(updateFreezeSql,temprequestid); + kqLog.info("KQFlowActiontBiz delTest:updateFreezeSql:"+updateFreezeSql+":temprequestid:"+temprequestid+":isUpdate:"+isUpdate); + } + } + } + } + }catch (Exception e){ + e.printStackTrace(); + rs.writeLog("KQFlowActiontBiz delTest:temprequestid:"+temprequestid+":workflowid:"+workflowid+":报错:"+e.getMessage()); + } + } + + /** + * 看下请假流程是不是已经归档并生成了扣减 + * @param requestId + * @return + */ + private boolean isLeaveFlowOver(String requestId) { + RecordSet rs = new RecordSet(); + String sql = "select * from kq_UsageHistory where wfRequestId=?"; + rs.executeQuery(sql, requestId); + boolean isOver = false; + if(rs.next()) { + isOver = true; + } + return isOver; + } + + public Map delCardAction(Map sqlMap, + List splitBeans, DateTimeFormatter datetimeFormatter, int workflowId, + int requestId, ResourceComInfo rci) throws Exception{ + + String[] cardFields = KQAttFlowFieldsSetBiz.cardFields; + + KQFormatData kqFormatData = new KQFormatData(); + Map result = new HashMap<>(); + RecordSet rs1 = new RecordSet(); + RecordSet rs2 = new RecordSet(); + + String resourceId = ""; + String detail_scheduletime = ""; + String detail_signtype = ""; + String detail_signdate = ""; + String detail_signtime = ""; + + String userId = ""; + String userType = "1";//默认给1 + String signType = ""; + String signDate = ""; + String signTime = ""; + String isInCom = "1"; + String signfrom = ""; + + String signStatus = ""; + List formateList = new ArrayList<>(); + if(!sqlMap.isEmpty()){ + for(Map.Entry me : sqlMap.entrySet()){ + String concort = "###" ; + String key = me.getKey(); + String value = me.getValue(); + + String wfId = key.split(concort)[3] ; + int usedetail = Util.getIntValue(key.split(concort)[2], 0); + String tableDetailName= key.split(concort)[1] ; + String tableName= key.split(concort)[0] ; + String idVal = ""; + String id = "dataId"; + if(usedetail == 1){ + id = "detailId"; + } + rs1.execute(value); + List belongDateList = Lists.newArrayList(); + List overtimeList = Lists.newArrayList(); + Map> formatMap = Maps.newHashMap(); + Map> overtimeMap = Maps.newHashMap(); + while (rs1.next()) { + idVal = Util.null2s(rs1.getString(id), ""); + String signSource = "card:|wfid|"+wfId+"|requestid|"+requestId+"|detailId|"+idVal; + + String f_resourceId = cardFields[0]; + String f_detail_signdate = cardFields[3]; + String f_detail_scheduletime = cardFields[4]; + String f_detail_signtype = cardFields[6]; + String f_detail_signtime = cardFields[7]; + resourceId = Util.null2s(rs1.getString(f_resourceId), ""); + detail_scheduletime = Util.null2s(rs1.getString(f_detail_scheduletime), ""); + detail_signtype = Util.null2s(rs1.getString(f_detail_signtype), ""); + detail_signdate = Util.null2s(rs1.getString(f_detail_signdate), ""); + detail_signtime = Util.null2s(rs1.getString(f_detail_signtime), ""); + userId = resourceId; + + signType = "0".equalsIgnoreCase(detail_signtype)?"1":"2"; + signDate = detail_signdate; + signTime = detail_signtime+":00"; + signfrom = signSource; + + StringBuffer sql = new StringBuffer("delete from HrmScheduleSign where userid='").append(userId).append("' and signdate='").append(signDate).append("'") + .append(" and signtime='").append(signTime).append("' and signfrom='").append(signfrom).append("'"); + kqLog.info("delcardsql="+sql.toString()); + boolean isOk = rs2.execute(sql.toString()); + + if(!isOk){ + result.put("status", "-1"); + result.put("message", "删除补卡数据失败!"); + return result; + } + kqLog.info("delCardAction:userId:"+userId+":signDate:"+signDate+":signTime:"+signTime); + + String format_key = userId+"_"+signDate; + formateList.add(format_key); + } + + } + kqLog.info("KQFlowActiontBiz isCard delTest:formateList:"+formateList); + if(null != formateList && formateList.size()>0){ + for(String formateStr : formateList){ + String[] formateStrs = formateStr.split("_"); + new KQFormatData().formatKqDate(formateStrs[0],formateStrs[1]); + } + } + } + + return result; + } + + /** + * 拆分请假数据 生成splitBeans + * @param sqlMap + * @param splitBeans + * @param datetimeFormatter + * @param workflowId + * @param requestId + * @param rci + * @return + * @throws Exception + */ + public Map handleKQLeaveAction(Map sqlMap, + List splitBeans, DateTimeFormatter datetimeFormatter, int workflowId, + int requestId, ResourceComInfo rci) throws Exception{ + KQFlowLeaveUtil kqFlowLeaveUtil = new KQFlowLeaveUtil(); + return kqFlowLeaveUtil.handleKQLeaveAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + } + + /** + * 拆分出差数据 生成splitBeans + * @param sqlMap + * @param splitBeans + * @param datetimeFormatter + * @param workflowId + * @param requestId + * @param rci + * @return + * @throws Exception + */ + public Map handleKQEvectionAction(Map sqlMap, + List splitBeans, DateTimeFormatter datetimeFormatter, int workflowId, + int requestId, ResourceComInfo rci) throws Exception{ + KQFlowEvectionUtil kqFlowEvectionUtil = new KQFlowEvectionUtil(); + return kqFlowEvectionUtil.handleKQEvectionAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + } + + /** + * 拆分公出数据 生成splitBeans + * @param sqlMap + * @param splitBeans + * @param datetimeFormatter + * @param workflowId + * @param requestId + * @param rci + * @return + * @throws Exception + */ + public Map handleKQOutAction(Map sqlMap, + List splitBeans, DateTimeFormatter datetimeFormatter, int workflowId, + int requestId, ResourceComInfo rci) throws Exception{ + KQFlowOutUtil kqFlowOutUtil = new KQFlowOutUtil(); + return kqFlowOutUtil.handleKQOutAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + } + + /** + * 拆分加班数据 生成splitBeans + * @param sqlMap + * @param splitBeans + * @param datetimeFormatter + * @param workflowId + * @param requestId + * @param rci + * @return + * @throws Exception + */ + public Map handleKQOvertimeAction(Map sqlMap, + List splitBeans, DateTimeFormatter datetimeFormatter, int workflowId, + int requestId, ResourceComInfo rci) throws Exception{ + KQFlowOvertimeUtil kqFlowOvertimeUtil = new KQFlowOvertimeUtil(); + return kqFlowOvertimeUtil.handleKQOvertimeAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci,""); + } + /** + * 拆分排班数据 + * @param sqlMap + * @param splitBeans + * @param datetimeFormatter + * @param workflowId + * @param requestId + * @param rci + * @return + * @throws Exception + */ + public void handleKQShiftAction(Map sqlMap, + List splitBeans, DateTimeFormatter datetimeFormatter, int workflowId, + int requestId, ResourceComInfo rci) throws Exception{ + KQFlowShiftUtil kqFlowShiftUtil = new KQFlowShiftUtil(); + kqFlowShiftUtil.handleKQShiftAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + } + /** + * 补卡流程数据 生成签到签退数据并更新考勤报表 + * @param sqlMap + * @param splitBeans + * @param datetimeFormatter + * @param workflowId + * @param requestId + * @param rci + * @return + * @throws Exception + */ + public Map handleKQCardAction(Map sqlMap, + List splitBeans, DateTimeFormatter datetimeFormatter, int workflowId, + int requestId, ResourceComInfo rci) throws Exception{ + KQFlowCardUtil kqFlowCardUtil = new KQFlowCardUtil(); + return kqFlowCardUtil.handleKQCardAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + } + /** + * 拆分销假流程数据 生成数据到splitBeans和backsplitBeans + * @param sqlMap + * @param splitBeans + * @param datetimeFormatter + * @param workflowId + * @param requestId + * @param rci + * @return + * @throws Exception + */ + public Map handleKQLeaveBackAction(Map sqlMap, + List splitBeans, DateTimeFormatter datetimeFormatter, int workflowId, + int requestId, ResourceComInfo rci) throws Exception{ + KQFlowLeaveBackUtil kqFlowLeaveBackUtil = new KQFlowLeaveBackUtil(); + return kqFlowLeaveBackUtil.handleKQLeaveBackAction(sqlMap,splitBeans,datetimeFormatter,workflowId,requestId,rci); + } +} diff --git a/src/com/engine/kq/biz/KQFlowDataBiz.java b/src/com/engine/kq/biz/KQFlowDataBiz.java new file mode 100644 index 0000000..768addf --- /dev/null +++ b/src/com/engine/kq/biz/KQFlowDataBiz.java @@ -0,0 +1,796 @@ +package com.engine.kq.biz; + +import com.engine.kq.enums.FlowReportTypeEnum; +import com.engine.kq.enums.KqSplitFlowTypeEnum; +import com.engine.kq.wfset.bean.SplitBean; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.general.Util; + +/** + * 考勤流程数据 相关类 + */ +public class KQFlowDataBiz { + + private String resourceid; + private String fromDate; + private String toDate; + private String fromTime; + private String toTime; + private String belongDate; + private String newLeaveType; + private String orderby_sql; + + public KQFlowDataBiz(FlowDataParamBuilder build){ + this.resourceid = build.resourceid; + this.fromDate = build.fromDate; + this.toDate = build.toDate; + this.fromTime = build.fromTime; + this.toTime = build.toTime; + this.belongDate = build.belongDate; + this.newLeaveType = build.newLeaveType; + this.orderby_sql = build.orderby_sql; + } + + /** + * 获取所有的考勤数据 + * 请假,出差,公出,加班的 + * @param flowMaps + * @param isAll true的时候也返回加班的,false的时候不返回加班的,只返回可以抵扣异常的 + * @return + */ + public List getAllFlowData(Map flowMaps,boolean isAll){ + List allSplitBeans = new ArrayList<>(); + + Map flowDeductCard = getFlowDeductCard(); + + allSplitBeans.addAll(getLeaveData(flowMaps,flowDeductCard)); + allSplitBeans.addAll(getEvectionData(flowMaps,flowDeductCard)); + allSplitBeans.addAll(getOutData(flowMaps,flowDeductCard)); + if(isAll){ + allSplitBeans.addAll(getOverTimeData(flowMaps)); + } + allSplitBeans.addAll(getOtherData(flowMaps)); + + return allSplitBeans; + } + + /** + * 流程抵扣考勤 + */ + public Map getFlowDeductCard() { + + RecordSet rs = new RecordSet(); + RecordSet rs1 = new RecordSet(); + Map flowDeductCard = new HashMap<>(); + + String flowDeductCardSql = "select * from kq_flow_deduct_card t where 1=1 and (isclear is null or isclear<>1) "; + String sqlWhere = sqlFlowCardParamWhere(); + if(sqlWhere.length() > 0){ + flowDeductCardSql += sqlWhere; + } + rs.execute(flowDeductCardSql); + while(rs.next()){ + String requestId= rs.getString("requestId"); + String resourceid= rs.getString("resourceid"); + String signtype= rs.getString("signtype"); + String serialnumber= rs.getString("serialnumber"); + String flowtype= rs.getString("flowtype"); + String key = requestId+"_"+resourceid+"_"+flowtype; + String serial_signtype = serialnumber+"_"+signtype; + if(flowDeductCard.containsKey(key)){ + String tmpSignType = Util.null2String(flowDeductCard.get(key)); + flowDeductCard.put(key, tmpSignType+","+serial_signtype); + }else{ + flowDeductCard.put(key, serial_signtype); + } + } + return flowDeductCard; + } + + /** + * 获取请假相关的数据 + */ + public List getLeaveData(Map flowMaps, + Map flowDeductCard){ + + RecordSet rs = new RecordSet(); + RecordSet rs1 = new RecordSet(); + + String tablename = "select a.* from "+KqSplitFlowTypeEnum.LEAVE.getTablename()+" a left join workflow_requestbase b on a.requestid = b.requestid where b.requestid > 0 "; + String leaveSql = "select * from ("+tablename+") t where 1=1 and (status is null or status <> '1') "; + String sqlWhere = sqlParamWhere(); + + if(sqlWhere.length() > 0){ + leaveSql += sqlWhere; + } + List splitBeans = new ArrayList<>(); + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + + int[] initArrays = kqTimesArrayComInfo.getInitArr(); + + rs.execute(leaveSql); + while(rs.next()){ + SplitBean splitBean = new SplitBean(); + String requestId= rs.getString("requestId"); + String resourceid= rs.getString("resourceid"); + String fromdate= rs.getString("fromdate"); + String belongdate= rs.getString("belongdate"); + String fromtime= rs.getString("fromtime"); + String todate= rs.getString("todate"); + String totime= rs.getString("totime"); + String newleavetype= rs.getString("newleavetype"); + String duration= rs.getString("duration"); + String durationrule= rs.getString("durationrule"); + String leavebackrequestid= Util.null2String(rs.getString("leavebackrequestid")); + + String fromtimedb= rs.getString("fromtimedb"); + String totimedb= rs.getString("totimedb"); + + if(Util.getDoubleValue(duration) <= 0){ + continue; + } + //计算规则 1-按天请假 2-按半天请假 3-按小时请假 4-按整天请假 + String unitType = "4".equalsIgnoreCase(durationrule)?"1":"2"; + String card_key = requestId+"_"+resourceid+"_"+KqSplitFlowTypeEnum.LEAVE.getFlowtype(); + String serial_signtype = ""; + String serial = ""; + String signtype = ""; + if(!flowDeductCard.isEmpty() && flowDeductCard.containsKey(card_key)){ + serial_signtype = Util.null2String(flowDeductCard.get(card_key)); + if(serial_signtype.split("_") != null && serial_signtype.split("_").length == 2){ + serial = serial_signtype.split("_")[0]; + signtype = serial_signtype.split("_")[1]; + } + } + + Map infoMap = new HashMap<>(); + infoMap.put("requestId", requestId); + infoMap.put(newleavetype, duration); + infoMap.put("begintime", fromtime); + infoMap.put("endtime", totime); + infoMap.put("unitType", unitType); + infoMap.put("durationrule", durationrule); + if("2".equals(durationrule) && Util.getDoubleValue(duration)<1){ + infoMap.put("ishalf", "true"); + }else{ + infoMap.put("ishalf", "false"); + } + infoMap.put("flowtype", FlowReportTypeEnum.LEAVE.getFlowType()); + infoMap.put("newleavetype", newleavetype); + infoMap.put("signtype", signtype); + infoMap.put("serial", serial); + infoMap.put("fromtimedb", fromtimedb); + infoMap.put("totimedb", totimedb); + + String key = resourceid+"|"+belongdate; + if(flowMaps != null){ + if(flowMaps.get(key) != null){ + if(leavebackrequestid.length() > 0 && leavebackrequestid.startsWith(",")){ + initArrays = kqTimesArrayComInfo.getInitArr(); + int fromTimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(fromtime); + int toTimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(totime); + Arrays.fill(initArrays, fromTimeIndex, toTimeIndex+1, 1); + leavebackrequestid = leavebackrequestid.substring(1); + String backSql = "select * from "+KqSplitFlowTypeEnum.LEAVEBACK.getTablename()+" where "+Util.getSubINClause(leavebackrequestid, "requestid", "in")+" and fromdate= '"+fromdate+"'"; + rs1.executeQuery(backSql); + + while (rs1.next()){ + String back_fromtime = rs1.getString("fromtime"); + String back_totime = rs1.getString("totime"); + String back_duration= rs.getString("duration"); + if(Util.getDoubleValue(back_duration) <= 0){ + continue; + } + if(back_fromtime.equalsIgnoreCase(fromtime)){ + Arrays.fill(initArrays, kqTimesArrayComInfo.getArrayindexByTimes(back_fromtime), kqTimesArrayComInfo.getArrayindexByTimes(back_totime), -1); + }else{ + Arrays.fill(initArrays, kqTimesArrayComInfo.getArrayindexByTimes(back_fromtime)+1, kqTimesArrayComInfo.getArrayindexByTimes(back_totime), -1); + } + } + List> backLists = new ArrayList<>(); + List backList = new ArrayList<>(); + for(int i = fromTimeIndex ; i <= toTimeIndex ; i ++){ + if(initArrays[i] == 1){ + backList.add(kqTimesArrayComInfo.getTimesByArrayindex(i)); + }else{ + if(!backList.isEmpty()){ + backLists.add(backList); + backList = new ArrayList<>(); + }else{ + continue; + } + } + } + if(!backList.isEmpty()){ + backLists.add(backList); + } + if(backLists != null && !backLists.isEmpty()){ + List> time_list_tmp = (List>)flowMaps.get(key); + for(int j = 0 ; j < backLists.size() ;j++){ + List backListTmp = backLists.get(j); + String back_tmp_fromtime = backListTmp.get(0); + String back_tmp_totime = backListTmp.get(backListTmp.size()-1); + infoMap = new HashMap<>(); + infoMap.put("requestId", requestId); + infoMap.put(newleavetype, duration); + infoMap.put("begintime", back_tmp_fromtime); + infoMap.put("endtime", back_tmp_totime); + infoMap.put("unitType", unitType); + infoMap.put("durationrule", durationrule); + if("2".equals(durationrule)){ + infoMap.put("ishalf", "true"); + } + infoMap.put("flowtype", FlowReportTypeEnum.LEAVE.getFlowType()); + infoMap.put("newleavetype", newleavetype); + time_list_tmp.add(infoMap); + } + } + }else{ + List> time_list_tmp = (List>)flowMaps.get(key); + time_list_tmp.add(infoMap); + } + }else{ + if(leavebackrequestid.length() > 0 && leavebackrequestid.startsWith(",")){ + initArrays = kqTimesArrayComInfo.getInitArr(); + int fromTimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(fromtime); + int toTimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(totime); + Arrays.fill(initArrays, fromTimeIndex, toTimeIndex+1, 1); + leavebackrequestid = leavebackrequestid.substring(1); + String backSql = "select * from "+KqSplitFlowTypeEnum.LEAVEBACK.getTablename()+" where "+Util.getSubINClause(leavebackrequestid, "requestid", "in")+" and fromdate= '"+fromdate+"'"; + rs1.executeQuery(backSql); + + while (rs1.next()){ + String back_fromtime = rs1.getString("fromtime"); + String back_totime = rs1.getString("totime"); + if(back_fromtime.equalsIgnoreCase(fromtime)){ + Arrays.fill(initArrays, kqTimesArrayComInfo.getArrayindexByTimes(back_fromtime), kqTimesArrayComInfo.getArrayindexByTimes(back_totime), -1); + }else{ + if(back_fromtime.compareTo(back_totime) < 0){ + Arrays.fill(initArrays, kqTimesArrayComInfo.getArrayindexByTimes(back_fromtime)+1, kqTimesArrayComInfo.getArrayindexByTimes(back_totime), -1); + } + } + } + List> backLists = new ArrayList<>(); + List backList = new ArrayList<>(); + for(int i = fromTimeIndex ; i <= toTimeIndex ; i ++){ + if(initArrays[i] == 1){ + backList.add(kqTimesArrayComInfo.getTimesByArrayindex(i)); + }else{ + if(!backList.isEmpty()){ + backLists.add(backList); + backList = new ArrayList<>(); + }else{ + continue; + } + } + } + if(!backList.isEmpty()){ + backLists.add(backList); + } + if(backLists != null && !backLists.isEmpty()){ + List> time_list = new ArrayList<>(); + for(int j = 0 ; j < backLists.size() ;j++){ + List backListTmp = backLists.get(j); + String back_tmp_fromtime = backListTmp.get(0); + String back_tmp_totime = backListTmp.get(backListTmp.size()-1); + infoMap = new HashMap<>(); + infoMap.put("requestId", requestId); + infoMap.put(newleavetype, duration); + infoMap.put("begintime", back_tmp_fromtime); + infoMap.put("endtime", back_tmp_totime); + infoMap.put("unitType", unitType); + infoMap.put("durationrule", durationrule); + if("2".equals(durationrule)){ + infoMap.put("ishalf", "true"); + } + infoMap.put("flowtype", FlowReportTypeEnum.LEAVE.getFlowType()); + infoMap.put("newleavetype", newleavetype); + time_list.add(infoMap); + } + flowMaps.put(key, time_list); + } + }else{ + List> time_list = new ArrayList<>(); + time_list.add(infoMap); + flowMaps.put(key, time_list); + } + } + } + + } + return splitBeans; + } + + /** + * 获取出差相关的数据 + */ + public List getEvectionData(Map flowMaps, + Map flowDeductCard){ + + RecordSet rs = new RecordSet(); + String tablename = "select a.* from "+KqSplitFlowTypeEnum.EVECTION.getTablename()+" a left join workflow_requestbase b on a.requestid = b.requestid where b.requestid > 0 "; + String leaveSql = "select * from ("+tablename+") t where 1=1 and (status is null or status <> '1') "; + String sqlWhere = sqlParamWhere(); + + if(sqlWhere.length() > 0){ + leaveSql += sqlWhere; + } + + List splitBeans = new ArrayList<>(); + rs.execute(leaveSql); + while(rs.next()){ + SplitBean splitBean = new SplitBean(); + String requestId= rs.getString("requestId"); + String resourceid= rs.getString("resourceid"); + String fromdate= rs.getString("fromdate"); + String belongdate= rs.getString("belongdate"); + String fromtime= rs.getString("fromtime"); + String todate= rs.getString("todate"); + String totime= rs.getString("totime"); + String newleavetype= rs.getString("newleavetype"); + String duration= rs.getString("duration"); + String durationrule= rs.getString("durationrule"); + + splitBean.setRequestId(requestId); + splitBean.setResourceId(resourceid); + splitBean.setFromDate(fromdate); + splitBean.setFromTime(fromtime); + splitBean.setToDate(todate); + splitBean.setToTime(totime); + splitBean.setNewLeaveType(newleavetype); + splitBean.setDuration(duration); + splitBean.setDurationrule(durationrule); + splitBeans.add(splitBean); + + if(Util.getDoubleValue(duration) <= 0){ + continue; + } + //计算规则 1-按天请假 2-按半天请假 3-按小时请假 4-按整天请假 + String unitType = "4".equalsIgnoreCase(durationrule)?"1":"2"; + String card_key = requestId+"_"+resourceid+"_"+KqSplitFlowTypeEnum.EVECTION.getFlowtype(); + String serial_signtype = ""; + String serial = ""; + String signtype = ""; + if(!flowDeductCard.isEmpty() && flowDeductCard.containsKey(card_key)){ + serial_signtype = Util.null2String(flowDeductCard.get(card_key)); + if(serial_signtype.split("_") != null && serial_signtype.split("_").length == 2){ + serial = serial_signtype.split("_")[0]; + signtype = serial_signtype.split("_")[1]; + } + } + + Map infoMap = new HashMap<>(); + infoMap.put(FlowReportTypeEnum.businessLeave.getFlowType(), duration); + infoMap.put("requestId", requestId); + infoMap.put("begintime", fromtime); + infoMap.put("endtime", totime); + infoMap.put("unitType", unitType); + infoMap.put("durationrule", durationrule); + if("2".equals(durationrule) && Util.getDoubleValue(duration)<1){ + infoMap.put("ishalf", "true"); + }else{ + infoMap.put("ishalf", "false"); + } + infoMap.put("duration", duration); + infoMap.put("flowtype", FlowReportTypeEnum.EVECTION.getFlowType()); + infoMap.put("signtype", signtype); + infoMap.put("serial", serial); + + String key = resourceid+"|"+belongdate; + if(flowMaps != null){ + if(flowMaps.get(key) != null){ + List> time_list_tmp = (List>)flowMaps.get(key); + time_list_tmp.add(infoMap); + }else{ + List> time_list = new ArrayList<>(); + time_list.add(infoMap); + flowMaps.put(key, time_list); + } + } + + } + return splitBeans; + } + + /** + * 获取公出相关的数据 + */ + public List getOutData(Map flowMaps, + Map flowDeductCard){ + + RecordSet rs = new RecordSet(); + String tablename = "select a.* from "+KqSplitFlowTypeEnum.OUT.getTablename()+" a left join workflow_requestbase b on a.requestid = b.requestid where b.requestid > 0 "; + String leaveSql = "select * from ("+tablename+") t where 1=1 and (status is null or status <> '1') "; + String sqlWhere = sqlParamWhere(); + + if(sqlWhere.length() > 0){ + leaveSql += sqlWhere; + } + List splitBeans = new ArrayList<>(); + rs.execute(leaveSql); + while(rs.next()){ + SplitBean splitBean = new SplitBean(); + String requestId= rs.getString("requestId"); + String resourceid= rs.getString("resourceid"); + String fromdate= rs.getString("fromdate"); + String belongdate= rs.getString("belongdate"); + String fromtime= rs.getString("fromtime"); + String todate= rs.getString("todate"); + String totime= rs.getString("totime"); + String newleavetype= rs.getString("newleavetype"); + String duration= rs.getString("duration"); + String durationrule= rs.getString("durationrule"); + + splitBean.setRequestId(requestId); + splitBean.setResourceId(resourceid); + splitBean.setFromDate(fromdate); + splitBean.setFromTime(fromtime); + splitBean.setToDate(todate); + splitBean.setToTime(totime); + splitBean.setNewLeaveType(newleavetype); + splitBean.setDuration(duration); + splitBean.setDurationrule(durationrule); + splitBeans.add(splitBean); + + if(Util.getDoubleValue(duration) <= 0){ + continue; + } + //计算规则 1-按天请假 2-按半天请假 3-按小时请假 4-按整天请假 + String unitType = "4".equalsIgnoreCase(durationrule)?"1":"2"; + String card_key = requestId+"_"+resourceid+"_"+KqSplitFlowTypeEnum.OUT.getFlowtype(); + String serial_signtype = ""; + String serial = ""; + String signtype = ""; + if(!flowDeductCard.isEmpty() && flowDeductCard.containsKey(card_key)){ + serial_signtype = Util.null2String(flowDeductCard.get(card_key)); + if(serial_signtype.split("_") != null && serial_signtype.split("_").length == 2){ + serial = serial_signtype.split("_")[0]; + signtype = serial_signtype.split("_")[1]; + } + } + + Map infoMap = new HashMap<>(); + infoMap.put(FlowReportTypeEnum.officialBusiness.getFlowType(), duration); + infoMap.put("requestId", requestId); + infoMap.put("begintime", fromtime); + infoMap.put("endtime", totime); + infoMap.put("unitType", unitType); + infoMap.put("durationrule", durationrule); + if("2".equals(durationrule) && Util.getDoubleValue(duration)<1){ + infoMap.put("ishalf", "true"); + }else{ + infoMap.put("ishalf", "false"); + } + infoMap.put("duration", duration); + infoMap.put("flowtype", FlowReportTypeEnum.OUT.getFlowType()); + infoMap.put("signtype", signtype); + infoMap.put("serial", serial); + + String key = resourceid+"|"+belongdate; + if(flowMaps != null){ + if(flowMaps.get(key) != null){ + List> time_list_tmp = (List>)flowMaps.get(key); + time_list_tmp.add(infoMap); + }else{ + List> time_list = new ArrayList<>(); + time_list.add(infoMap); + flowMaps.put(key, time_list); + } + } + + } + return splitBeans; + } + + /** + * 获取加班相关的数据 + */ + public List getOverTimeData(Map flowMaps){ + + RecordSet rs = new RecordSet(); + String tablename = "select a.* from "+KqSplitFlowTypeEnum.OVERTIME.getTablename()+" a left join workflow_requestbase b on a.requestid = b.requestid where b.requestid > 0 "; + String leaveSql = "select * from ("+tablename+") t where 1=1 "; + String sqlWhere = sqlParamWhere(); + + if(sqlWhere.length() > 0){ + leaveSql += sqlWhere; + } + List splitBeans = new ArrayList<>(); + if(orderby_sql.length() > 0){ + leaveSql = leaveSql+orderby_sql; + } + new BaseBean().writeLog("加班流程获取Sql=>"+leaveSql); + rs.execute(leaveSql); + while(rs.next()){ + + SplitBean splitBean = new SplitBean(); + String dataid= rs.getString("dataid"); + String detailid= rs.getString("detailid"); + String requestId= rs.getString("requestId"); + new BaseBean().writeLog("start"+requestId); + String resourceid= rs.getString("resourceid"); + String fromdate= rs.getString("fromdate"); + String belongdate= rs.getString("belongdate"); + String fromtime= rs.getString("fromtime"); + String todate= rs.getString("todate"); + String totime= rs.getString("totime"); + String newleavetype= rs.getString("newleavetype"); + String duration= rs.getString("duration"); + String durationrule= rs.getString("durationrule"); + String changetype= rs.getString("changetype"); + String d_mins= rs.getString("d_mins"); + String overtime_type= rs.getString("overtime_type"); + + String fromdatedb= rs.getString("fromdatedb"); + String fromtimedb= rs.getString("fromtimedb"); + String todatedb= rs.getString("todatedb"); + String totimedb= rs.getString("totimedb"); + + splitBean.setDataId(dataid); + splitBean.setDetailId(detailid); + splitBean.setRequestId(requestId); + splitBean.setResourceId(resourceid); + splitBean.setFromDate(fromdate); + splitBean.setFromTime(fromtime); + splitBean.setToDate(todate); + splitBean.setToTime(totime); + splitBean.setNewLeaveType(newleavetype); + splitBean.setDuration(duration); + splitBean.setDurationrule(durationrule); + splitBean.setChangeType(Util.getIntValue(changetype)); + splitBean.setD_Mins(Util.getDoubleValue(d_mins)); + splitBean.setOvertime_type(overtime_type); + splitBean.setFromdatedb(fromdatedb); + splitBean.setFromtimedb(fromtimedb); + splitBean.setTodatedb(todatedb); + splitBean.setTotimedb(totimedb); + splitBeans.add(splitBean); + + //计算规则 1-按天请假 2-按半天请假 3-按小时请假 4-按整天请假 + String unitType = "4".equalsIgnoreCase(durationrule)?"1":"2"; + unitType = "2".equalsIgnoreCase(durationrule)?"1":"2"; + + Map infoMap = new HashMap<>(); + infoMap.put(FlowReportTypeEnum.businessLeave.getFlowType(), duration); + infoMap.put("begintime", fromtime); + infoMap.put("endtime", totime); + infoMap.put("unitType", unitType); + infoMap.put("duration", duration); + infoMap.put("flowtype", FlowReportTypeEnum.OVERTIME.getFlowType()); + + String key = resourceid+"|"+belongdate; + if(flowMaps != null){ + if(flowMaps.get(key) != null){ + List> time_list_tmp = (List>)flowMaps.get(key); + time_list_tmp.add(infoMap); + }else{ + List> time_list = new ArrayList<>(); + time_list.add(infoMap); + flowMaps.put(key, time_list); + } + } + } + return splitBeans; + } + + /** + * 获取异常流程的数据 + */ + public List getOtherData(Map flowMaps){ + + RecordSet rs = new RecordSet(); + String tablename = "select a.* from "+KqSplitFlowTypeEnum.OTHER.getTablename()+" a left join workflow_requestbase b on a.requestid = b.requestid where b.requestid > 0 "; + String leaveSql = "select * from ("+tablename+") t where 1=1 "; + String sqlWhere = sqlParamWhere(); + + if(sqlWhere.length() > 0){ + leaveSql += sqlWhere; + } + List splitBeans = new ArrayList<>(); + rs.execute(leaveSql); + while(rs.next()){ + SplitBean splitBean = new SplitBean(); + String requestId= rs.getString("requestId"); + String resourceid= rs.getString("resourceid"); + String fromdate= rs.getString("fromdate"); + String belongdate= rs.getString("belongdate"); + String fromtime= rs.getString("fromtime"); + String todate= rs.getString("todate"); + String totime= rs.getString("totime"); + String newleavetype= rs.getString("newleavetype"); + String duration= rs.getString("duration"); + String durationrule= rs.getString("durationrule"); + + splitBean.setRequestId(requestId); + splitBean.setResourceId(resourceid); + splitBean.setFromDate(fromdate); + splitBean.setFromTime(fromtime); + splitBean.setToDate(todate); + splitBean.setToTime(totime); + splitBean.setNewLeaveType(newleavetype); + splitBean.setDuration(duration); + splitBean.setDurationrule(durationrule); + splitBeans.add(splitBean); + + //计算规则 1-按天请假 2-按半天请假 3-按小时请假 4-按整天请假 + String unitType = "4".equalsIgnoreCase(durationrule)?"1":"2"; + + Map infoMap = new HashMap<>(); + infoMap.put(FlowReportTypeEnum.businessLeave.getFlowType(), duration); + infoMap.put("begintime", fromtime); + infoMap.put("endtime", totime); + infoMap.put("unitType", unitType); + + String key = resourceid+"|"+belongdate; + if(flowMaps != null){ + if(flowMaps.get(key) != null){ + List> time_list_tmp = (List>)flowMaps.get(key); + time_list_tmp.add(infoMap); + }else{ + List> time_list = new ArrayList<>(); + time_list.add(infoMap); + flowMaps.put(key, time_list); + } + } + } + return splitBeans; + } + + /** + * 根据请假类型判断是否被流程引用 + * @param ruleid + * @return true表示被引用 + */ + public static boolean leaveTypeUsed(String ruleid){ + KQFlowDataBiz kqFlowDataBiz = new FlowDataParamBuilder().newLeaveTypeParam(ruleid).build(); + List splitBeans = kqFlowDataBiz.getLeaveData(null, new HashMap<>()); + if(!splitBeans.isEmpty()){ + return true; + }else{ + return false; + } + } + + /** + * 生成相应的查询条件 + * @return + */ + private String sqlParamWhere() { + String sqlWhere = ""; + if(resourceid.length() > 0){ + sqlWhere += " and resourceid in ( "+resourceid+" )"; + } + if(fromDate.length() > 0 && toDate.length() > 0){ + sqlWhere += " and ( fromdate between '"+fromDate+"' and '"+toDate+"' or todate between '"+fromDate+"' and '"+toDate+"' )"; + }else{ + if(fromDate.length() > 0){ + sqlWhere += " and fromdate between '"+fromDate+"' and '"+fromDate+"' "; + } + if(toDate.length() > 0){ + sqlWhere += " and todate between '"+toDate+"' and '"+toDate+"' "; + } + } + if(belongDate.length() > 0){ + sqlWhere += " and belongdate = '"+belongDate+"' "; + } + if(fromTime.length() > 0){ + sqlWhere += " and fromtime >= '"+fromTime+"' "; + } + if(toTime.length() > 0){ + sqlWhere += " and totime <= '"+toTime+"' "; + } + if(newLeaveType.length() > 0){ + sqlWhere += " and newleavetype in ( "+newLeaveType+" )"; + } + return sqlWhere; + } + + private String sqlFlowCardParamWhere() { + String sqlWhere = ""; + if(resourceid.length() > 0){ + sqlWhere += " and resourceid in ( "+resourceid+" )"; + } + if(fromDate.length() > 0 && toDate.length() > 0){ + sqlWhere += " and ( fromdate between '"+fromDate+"' and '"+toDate+"' or todate between '"+fromDate+"' and '"+toDate+"' )"; + }else{ + if(fromDate.length() > 0){ + sqlWhere += " and fromdate between '"+fromDate+"' and '"+fromDate+"' "; + } + if(toDate.length() > 0){ + sqlWhere += " and todate between '"+toDate+"' and '"+toDate+"' "; + } + } + if(belongDate.length() > 0){ + sqlWhere += " and belongdate = '"+belongDate+"' "; + } + if(fromTime.length() > 0){ + sqlWhere += " and fromtime >= '"+fromTime+"' "; + } + if(toTime.length() > 0){ + sqlWhere += " and totime <= '"+toTime+"' "; + } + return sqlWhere; + } + + /** + * 针对可能存在的多种参数类型 创建参数静态内部类Builder + */ + public static class FlowDataParamBuilder { + + private String resourceid = ""; + private String fromDate = ""; + private String toDate = ""; + private String fromTime = ""; + private String toTime = ""; + private String belongDate = ""; + /** + * 请假用的请假类型 + */ + private String newLeaveType = ""; + private String orderby_sql = ""; + + public FlowDataParamBuilder() { + this.resourceid = ""; + //初始化的时候需要把其他参数先清空下 + this.fromDate = ""; + this.toDate = ""; + this.fromTime = ""; + this.toTime = ""; + this.newLeaveType = ""; + this.belongDate = ""; + this.orderby_sql = ""; + } + + //成员方法返回其自身,所以可以链式调用 + public FlowDataParamBuilder resourceidParam(final String resourceid) { + this.resourceid = resourceid; + return this; + } + + public FlowDataParamBuilder fromDateParam(final String fromDate) { + this.fromDate = fromDate; + return this; + } + + public FlowDataParamBuilder toDateParam(final String toDate) { + this.toDate = toDate; + return this; + } + + public FlowDataParamBuilder fromTimeParam(final String fromTime) { + this.fromTime = fromTime; + return this; + } + + public FlowDataParamBuilder toTimeParam(final String toTime) { + this.toTime = toTime; + return this; + } + + public FlowDataParamBuilder newLeaveTypeParam(final String newLeaveType) { + this.newLeaveType = newLeaveType; + return this; + } + + public FlowDataParamBuilder belongDateParam(final String belongDate) { + this.belongDate = belongDate; + return this; + } + + public FlowDataParamBuilder orderby_sqlParam(final String orderby_sql) { + this.orderby_sql = orderby_sql; + return this; + } + + //Builder的build方法,返回外部类的实例 + public KQFlowDataBiz build() { + return new KQFlowDataBiz(this); + } + } +} diff --git a/src/com/engine/kq/biz/KQOverTimeRuleCalBiz.java b/src/com/engine/kq/biz/KQOverTimeRuleCalBiz.java index 7400c8c..1ec28a3 100644 --- a/src/com/engine/kq/biz/KQOverTimeRuleCalBiz.java +++ b/src/com/engine/kq/biz/KQOverTimeRuleCalBiz.java @@ -18,6 +18,7 @@ import java.sql.Timestamp; import org.apache.commons.collections4.CollectionUtils; import weaver.common.DateUtil; import weaver.conn.RecordSet; +import weaver.general.BaseBean; import weaver.general.Util; import java.io.PrintWriter; @@ -111,6 +112,7 @@ public class KQOverTimeRuleCalBiz { int computingMode = Util.getIntValue(""+computingModeMap.get(changeType_key),-1); boolean isOk = true; + new BaseBean().writeLog("新加班规则计算开始 ==>"+computingMode); //把原来下面一个方法里的内容要抽出来,是因为存在如下的问题,如果我是跨天打卡,次日3点,加班归属点设置的是次日2点,2-3这部分的是属于第二天的,需要判断下第二天的加班方式是不是doComputingMode2,如果不是就需要去走对应的doComputingMode方法 if(2 == computingMode){ isOk = doComputingMode2WithCard(kqOvertimeCardBean,mapKey,resourceid,changeTypeMap, @@ -124,6 +126,10 @@ public class KQOverTimeRuleCalBiz { isOk = doComputingMode4WithCard(kqOvertimeCardBean,mapKey,resourceid,changeTypeMap, dateFormatter,overtimeLogMap,splitDate,overRulesDetailMap,eventMap,kqTimesArrayComInfo, restTimeMap,kqEventLogBiz,uuid,realSplitDate); + }else if(5 == computingMode){ + isOk = doComputingMode5WithCard(kqOvertimeCardBean,mapKey,resourceid,changeTypeMap, + dateFormatter,overtimeLogMap,splitDate,overRulesDetailMap,eventMap,kqTimesArrayComInfo, + restTimeMap,kqEventLogBiz,uuid,realSplitDate); } if(!isOk){ continue; @@ -326,6 +332,263 @@ public class KQOverTimeRuleCalBiz { } + /** + * todo 二开新加班规则为5 取流程和打卡的并集 + */ + private boolean doComputingMode5WithCard(KQOvertimeCardBean kqOvertimeCardBean, String mapKey, String resourceid, Map changeTypeMap, DateTimeFormatter dateFormatter, Map overtimeLogMap, + String splitDate, Map overRulesDetailMap, Map eventMap, KQTimesArrayComInfo kqTimesArrayComInfo, Map> restTimeMap, KQOvertimeLogBiz kqEventLogBiz, String uuid, + String realSplitDate) throws Exception{ + BaseBean bb = new BaseBean(); + Map> splitBeanMaps = Maps.newHashMap(); + //获取加班流程数据 + getOverTimeFlowData(resourceid,realSplitDate,realSplitDate,splitBeanMaps,dateFormatter); + + String change_key = realSplitDate+"_"+resourceid; + int changeType = Util.getIntValue(""+changeTypeMap.get(change_key),-1); + String changeType_key = realSplitDate+"_"+changeType; + LocalDate localbelongDate = LocalDate.parse(realSplitDate); + LocalDate preLocalDate = localbelongDate.minusDays(1); + String preSplitDate = preLocalDate.format(dateFormatter); + String preChange_key = preSplitDate+"_"+resourceid; + int preChangeType = Util.getIntValue(""+changeTypeMap.get(preChange_key),-1); + String preChangeType_key = preSplitDate+"_"+preChangeType; + LocalDate nextLocalDate = localbelongDate.plusDays(1); + String nextSplitDate = nextLocalDate.format(dateFormatter); + String nextChange_key = nextSplitDate+"_"+resourceid; + int nextChangeType = Util.getIntValue(""+changeTypeMap.get(nextChange_key),-1); + String nextChangeType_key = nextSplitDate+"_"+nextChangeType; + + String changetypeName = 1==changeType ? "节假日" : (2 == changeType ? "工作日" : (3 == changeType ? "休息日" : "异常")); + String changetypeLogInfo = change_key+"|changeType|"+changeType+"|"+changetypeName; + logOvertimeMap(overtimeLogMap, changetypeLogInfo, mapKey+"|"+"加班日期属性|changetypeLogInfo"); + + clearOvertimeTX(resourceid, realSplitDate,overtimeLogMap,splitDate); + logOvertimeMap(overtimeLogMap, kqOvertimeCardBean, mapKey+"|"+"打卡和上下班数据|KQOvertimeCardBean"); + + KQOvertimeRulesDetailEntity kqOvertimeRulesDetailEntity = overRulesDetailMap.get(changeType_key); + if(kqOvertimeRulesDetailEntity == null){ + String overRuleInfo = "changeType_key:"+changeType_key+":kqOvertimeRulesDetailEntity:"+kqOvertimeRulesDetailEntity; + logOvertimeMap(overtimeLogMap, overRuleInfo, mapKey+"|"+"加班规则为null|kqOvertimeRulesDetailEntity"); + return false; + } + int overtimeEnable = kqOvertimeRulesDetailEntity.getOvertimeEnable(); + if(overtimeEnable != 1){ + String overtimeEnableInfo = "overtimeEnable:"+overtimeEnable; + logOvertimeMap(overtimeLogMap, overtimeEnableInfo, mapKey+"|"+"未开启加班规则|overtimeEnable"); + return false; + } + + if(kqOvertimeCardBean != null){ + + + int[] initArrays = kqTimesArrayComInfo.getInitArr(); + bb.writeLog("初始化一天时间数组==>"+ Arrays.toString(initArrays)); + + List> hasOverTime4SignList = Lists.newArrayList(); + getHasOverTimeData(resourceid,realSplitDate,hasOverTime4SignList); + Map signinoffMap = buildOvertimeCard(kqOvertimeCardBean, resourceid, realSplitDate, kqTimesArrayComInfo, restTimeMap, changeType_key,initArrays,hasOverTime4SignList, + overRulesDetailMap,true,overtimeLogMap, preChangeType_key,nextChangeType_key); + logOvertimeMap(overtimeLogMap, signinoffMap, mapKey+"|"+"获取上下班打卡数据|signinoffMap"); + + String signinTime = Util.null2String(signinoffMap.get("signinTime")); + String signoutTime = Util.null2String(signinoffMap.get("signoutTime")); + String signinDate = Util.null2String(signinoffMap.get("signinDate")); + String signoutDate = Util.null2String(signinoffMap.get("signoutDate")); + + int signinTimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(signinTime); + int signoutTimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(signoutTime); + + if(signinTimeIndex < signoutTimeIndex){ + //先覆盖打卡 打卡区间都是1 + int over_count = kqTimesArrayComInfo.getCnt(initArrays, signinTimeIndex, signoutTimeIndex, 1); + String overCountLogInfo = "signinTimeIndex:"+signinTimeIndex+":signoutTimeIndex:"+signoutTimeIndex+":over_count:"+over_count; + + bb.writeLog("打卡时长获取:"+overCountLogInfo+"=>"+Arrays.toString(initArrays)); + logOvertimeMap(overtimeLogMap, overCountLogInfo, mapKey+"|"+"打卡区间,得到打卡时长|over_count"); + if(over_count > 0){ + int restTimeType = 1; + String kqOvertimeRulesDetailEntityLogInfo = kqOvertimeRulesDetailEntity==null ? "" :JSON.toJSONString(kqOvertimeRulesDetailEntity); + logOvertimeMap(overtimeLogMap, kqOvertimeRulesDetailEntityLogInfo, mapKey+"|具体这个人这一天对应的加班规则|KQOvertimeRulesDetailEntity"); + int minimumLen = -1; + if(kqOvertimeRulesDetailEntity != null){ + minimumLen = kqOvertimeRulesDetailEntity.getMinimumLen(); + if(over_count < minimumLen){ + String minInfo = "over_count:"+over_count+":minimumLen:"+minimumLen; + bb.writeLog("打卡时长小于最小加班时长=>"+minInfo); + logOvertimeMap(overtimeLogMap, minInfo, mapKey+"|打卡时长小于最小加班时长|over_count "+splitBeanMaps.containsKey(mapKey)); + if(splitBeanMaps.containsKey(mapKey)) { + List splitBeans = splitBeanMaps.get(mapKey); + String flowinfo = ""; + if(splitBeans != null && !splitBeans.isEmpty()){ + flowinfo = JSON.toJSONString(splitBeans, SerializerFeature.DisableCheckSpecialChar,SerializerFeature.DisableCircularReferenceDetect); + } + eventMap.put(mapKey+"|"+"加班流程数据|flowinfo", flowinfo); + bb.writeLog("splitBeans size => "+splitBeans.isEmpty()); + if(splitBeans == null || splitBeans.isEmpty()){ + return false; + } + + for (int m = 0; m < splitBeans.size(); m++) { + SplitBean splitBean = splitBeans.get(m); + String dataid = splitBean.getDataId(); + String detailid = splitBean.getDetailId(); + String flow_fromdate = splitBean.getFromDate(); + String flow_fromtime = splitBean.getFromTime(); + String flow_todate = splitBean.getToDate(); + String flow_totime = splitBean.getToTime(); + String fromdatedb = splitBean.getFromdatedb(); + String fromtimedb = splitBean.getFromtimedb(); + String todatedb = splitBean.getTodatedb(); + String totimedb = splitBean.getTotimedb(); + String requestid = splitBean.getRequestId(); + double d_mins = splitBean.getD_Mins(); + + + if(d_mins <= 0){ + continue; + } + String flow_key = mapKey+"|"+"flow_fromdate|"+flow_fromdate+"|flow_todate|"+flow_todate + +"|flow_fromtime|"+flow_fromtime+"|flow_totime|"+flow_totime; + bb.writeLog("加班流程数据集:"+flow_key); + + //如果打卡数据有了,再拿流程数据去覆盖,得到有效的打卡区间,这个区间肯定已经是去除了上下班时间和休息时间还有重复打卡的部分 + List cross_time_list = Lists.newArrayList(); + // cross_time_list里存的是排除了工作时间的打卡段,找到1表示找到打卡开始的点了,找到-2表示找到打卡结束的点了 + get_cross_time_list(cross_time_list,initArrays,signinTimeIndex,signoutTimeIndex,1,-2); + + bb.writeLog("cross_time_list集合=>"+cross_time_list.toString()+"覆盖前1=>"+Arrays.toString(initArrays)); + logOvertimeMap(overtimeLogMap, cross_time_list, flow_key+"|cross_time_list"); + + if(flow_fromdate.compareTo(realSplitDate) > 0){ + flow_fromtime = kqTimesArrayComInfo.turn24to48Time(flow_fromtime); + } + if(flow_todate.compareTo(realSplitDate) > 0){ + flow_totime = kqTimesArrayComInfo.turn24to48Time(flow_totime); + } + int flow_fromIndex = kqTimesArrayComInfo.getArrayindexByTimes(flow_fromtime); + int flow_toIndex = kqTimesArrayComInfo.getArrayindexByTimes(flow_totime); + bb.writeLog("流程加班开始和结束索引=>"+flow_fromIndex+"=>"+flow_toIndex); + + //2.根据流程加班时间 在已有的数组上覆盖成2 + Arrays.fill(initArrays, flow_fromIndex, flow_toIndex,2); + bb.writeLog("覆盖2后=>"+Arrays.toString(initArrays)); + + int across_mins = 0; + //3.获取一天数组中有多少2(流程)和多少 1(打卡) + int flow_count = kqTimesArrayComInfo.getCnt(initArrays, flow_fromIndex, flow_toIndex, 2); + bb.writeLog("flow_count => "+flow_count); + int dk_count = 0; + int mins = signoutTimeIndex-signinTimeIndex; + if(mins <= 0){ + String crossInfo = "flow_cross_fromtime_index:"+signinTimeIndex+":flow_cross_totime_index:"+signoutTimeIndex+":mins:"+mins; + bb.writeLog("打卡时长小于最小加班时长|crossInfo"+crossInfo); + logOvertimeMap(overtimeLogMap, crossInfo, flow_key+"|打卡时长小于最小加班时长|crossInfo"); + }else { + dk_count = kqTimesArrayComInfo.getCnt(initArrays, signinTimeIndex, signoutTimeIndex, 1); + } + across_mins = flow_count + dk_count; + + String flow_cross_key = "加班计算区间|"+kqTimesArrayComInfo.getTimesByArrayindex(signinTimeIndex)+"-"+kqTimesArrayComInfo.getTimesByArrayindex(signoutTimeIndex); + logOvertimeMap(overtimeLogMap, mins, flow_cross_key+"|原始加班区间生成的加班时长|mins"); + bb.writeLog("原始加班区间生成的加班时长|mins"+mins); + bb.writeLog("across_mins => "+across_mins); + + + + if(kqOvertimeRulesDetailEntity != null){ + //我这个方法是针对每次生成的加班数据做排除休息时长的处理 + restTimeType = kqOvertimeRulesDetailEntity.getRestTimeType(); + if(restTimeType == 2){ + across_mins = new KQOverTimeFlowBiz().handle_restlength(across_mins,restTimeMap,changeType_key); + } + } + int card_mins = over_count; + double double_mins = getD_MinsByUnit((1.0*across_mins)); + across_mins = (int)double_mins; + if(across_mins <= 0){ + logOvertimeMap(overtimeLogMap, across_mins, flow_key+"|经过单位换算之后时长为0|across_mins"); + continue; + } + if(across_mins < minimumLen){ + String minInfo = "across_mins:"+across_mins+":minimumLen:"+minimumLen; + logOvertimeMap(overtimeLogMap, minInfo, flow_key+"|打卡时长小于最小加班时长|over_count otherParam = Maps.newHashMap(); + otherParam.put("overtime_type", overtime_type); + otherParam.put("changeType", String.valueOf(changeType)); + int paidLeaveEnableType = kqOvertimeRulesDetailEntity.getPaidLeaveEnableType(); + if(2 == paidLeaveEnableType){ + logOvertimeMap(overtimeLogMap, overtime_type, flow_key+"|关联调休与否来自于流程选择,加班类型下拉框值|overtime_type"); + } + + int paidLeaveEnable = getPaidLeaveEnable(kqOvertimeRulesDetailEntity, overtime_type); + + otherParam.put("overtimeLogMap", overtimeLogMap); + logOvertimeMap(overtimeLogMap, across_mins, flow_key+"|最终生成的加班分钟数|overtime_mins"); + tiaoxiuId = KQBalanceOfLeaveBiz.addExtraAmountByDis5(resourceid,realSplitDate,across_mins+"","0",workingHours,requestid,"1",realSplitDate,otherParam); + if(Util.getIntValue(tiaoxiuId) > 0){ + kqLog.info("doComputingMode4 生成调休成功,调休id:"+tiaoxiuId+":resourceid:"+resourceid+":realSplitDate:"+realSplitDate); + }else{ + kqLog.info("doComputingMode4 生成调休失败,调休id:"+tiaoxiuId+":resourceid:"+resourceid+":realSplitDate:"+realSplitDate); + } + logOvertimeMap(overtimeLogMap, tiaoxiuId, flow_key+"|最终生成的调休id|tiaoxiuId"); + + String flow_overtime_sql = "insert into kq_flow_overtime (requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate," + + "workMins,durationrule,changetype,paidLeaveEnable,computingMode,tiaoxiuId,uuid,fromdatedb,fromtimedb,todatedb,totimedb,flow_mins,card_mins,ori_belongdate,flow_dataid,create_time,update_time,creator)"+ + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + if (rs.getDBType().equals("postgresql")) { + flow_overtime_sql = "insert into kq_flow_overtime (requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate," + + "workMins,durationrule,changetype,paidLeaveEnable,computingMode,tiaoxiuId,uuid,fromdatedb,fromtimedb,todatedb,totimedb,flow_mins,card_mins,ori_belongdate,flow_dataid,create_time,update_time,creator)"+ + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?::timestamp,?::timestamp,?) "; + } + signinTime = kqTimesArrayComInfo.turn48to24Time(signinTime); + signoutTime = kqTimesArrayComInfo.turn48to24Time(signoutTime); + if(signinTime.length() == 5){ + signinTime = signinTime+":00"; + } + if(signoutTime.length() == 5){ + signoutTime = signoutTime+":00"; + } + Long cur = System.currentTimeMillis(); + Timestamp date = new Timestamp(cur); + boolean isUp = rs.executeUpdate(flow_overtime_sql, requestid,resourceid,signinDate,signinTime,signoutDate,signoutTime,across_mins,"",realSplitDate, + "",unit,changeType,paidLeaveEnable,computingMode,tiaoxiuId,overtime_uuid,fromdatedb,fromtimedb,todatedb,totimedb,d_mins,card_mins,splitDate,flow_dataid,date,date,Util.getIntValue(resourceid)); + + String overtimeid = get_overtime_uuid(overtime_uuid); + kqEventLogBiz.updateOvertimeId(uuid, overtimeid); + } + }else{ + //有打卡没有流程 + logOvertimeMap(overtimeLogMap, mapKey, mapKey+"|"+"加班流程为空"); + } + }else{ + logOvertimeMap(overtimeLogMap, overCountLogInfo, mapKey+"|"+"打卡数据时长为0"); + } + }else{ + String overCountLogInfo = "signinTimeIndex:"+signinTimeIndex+":signoutTimeIndex:"+signoutTimeIndex; + logOvertimeMap(overtimeLogMap, overCountLogInfo, mapKey+"|"+"打卡数据异常"); + } + }else{ + logOvertimeMap(overtimeLogMap, "打卡数据KQOvertimeCardBean为null", mapKey+"|"+"打卡和上下班数据|KQOvertimeCardBean"); + } + return true; + } + /** * 把获取打卡数据后处理的部分拆出来 */ diff --git a/src/com/engine/kq/wfset/action/KqSplitAction.java b/src/com/engine/kq/wfset/action/KqSplitAction.java new file mode 100644 index 0000000..f132419 --- /dev/null +++ b/src/com/engine/kq/wfset/action/KqSplitAction.java @@ -0,0 +1,73 @@ +package com.engine.kq.wfset.action; + +import com.engine.kq.biz.KQFlowActiontBiz; +import com.engine.kq.log.KQLog; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.general.Util; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.RequestInfo; +import weaver.workflow.workflow.WorkflowComInfo; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; + +/** + * 考勤流程数据拆分action + */ +public class KqSplitAction extends BaseBean implements Action { + private KQLog kqLog = new KQLog(); + + @Override + public String execute(RequestInfo request) { + this.writeLog("KqSplitAction", "do action on request:" + request.getRequestid()); + String requestid = request.getRequestid(); + kqLog.info("do KqSplitAction on request:"+request.getRequestid()); + int requestidInt = Util.getIntValue(requestid, 0); + + String workflowid = request.getWorkflowid(); + String formid = new WorkflowComInfo().getFormId(workflowid); + + try { + KQFlowActiontBiz kqFlowActiontBiz = new KQFlowActiontBiz(); + RecordSet rs = new RecordSet(); + String proc_set_sql = "select * from kq_att_proc_set where field001 = ? and field002 = ? "; + rs.executeQuery(proc_set_sql, workflowid,formid); + if(rs.next()){ + String proc_set_id = rs.getString("id"); + //得到这个考勤流程设置是否使用明细 + String usedetails = rs.getString("usedetail"); + + int kqtype = Util.getIntValue(rs.getString("field006")); + kqLog.info("do action on kqtype:" + kqtype+":requestidInt:"+requestidInt); + Map map = new HashMap(); + if(requestidInt > 0){ + map.put("requestId", "and t.requestId = " + requestidInt); + map.put("operatorId", ""+request.getRequestManager().getCreater()); + } + Map result = kqFlowActiontBiz.handleKQFlowAction(proc_set_id, usedetails, requestidInt, kqtype, Util.getIntValue(workflowid), false,false,map); + + if(!result.isEmpty()){ + String error = Util.null2String(result.get("message")); + request.getRequestManager().setMessageid("666" + request.getRequestid() + "999"); + request.getRequestManager().setMessagecontent(error); + return Action.FAILURE_AND_CONTINUE; + } + } + } catch (Exception e) { + kqLog.info("流程数据报错:KqSplitAction:"); + StringWriter errorsWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(errorsWriter)); + kqLog.info(errorsWriter.toString()); + request.getRequestManager().setMessageid("11111" + request.getRequestid() + "22222"); + request.getRequestManager().setMessagecontent("【考勤报表统计action】报错,请联系管理员!"); + return Action.FAILURE_AND_CONTINUE; + } + + return Action.SUCCESS; + + } + +} diff --git a/src/com/engine/kq/wfset/util/KQFlowUtil.java b/src/com/engine/kq/wfset/util/KQFlowUtil.java new file mode 100644 index 0000000..c423679 --- /dev/null +++ b/src/com/engine/kq/wfset/util/KQFlowUtil.java @@ -0,0 +1,457 @@ +package com.engine.kq.wfset.util; + +import com.alibaba.fastjson.JSON; +import com.engine.kq.biz.KQExitRulesBiz; +import com.engine.kq.biz.KQFormatData; +import com.engine.kq.biz.KQLeaveRulesBiz; +import com.engine.kq.biz.KQOvertimeRulesBiz; +import com.engine.kq.biz.KQTravelRulesBiz; +import com.engine.kq.enums.DurationTypeEnum; +import com.engine.kq.enums.KqSplitFlowTypeEnum; +import com.engine.kq.log.KQLog; +import com.engine.kq.wfset.bean.SplitBean; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import weaver.conn.RecordSet; +import weaver.general.Util; +import weaver.hrm.resource.ResourceComInfo; +import weaver.workflow.workflow.WorkflowRequestComInfo; + +public class KQFlowUtil { + private KQLog kqLog = new KQLog(); + + /** + * 把通用的bean部分在这里进行填充 + * @param splitBean + * @param rs1 + * @param requestId + * @param rci + * @param workflowId + * @param durationTypeEnum + * @param key + * @param result + * @param datetimeFormatter + * @param uuid + */ + public boolean fillSplitBean(SplitBean splitBean, RecordSet rs1, String requestId, + ResourceComInfo rci, String workflowId, DurationTypeEnum durationTypeEnum, String key, + Map result, DateTimeFormatter datetimeFormatter, String uuid){ + + boolean isFillRight = true; + String concort = "###" ; + int usedetail = Util.getIntValue(key.split(concort)[2], 0); + String tableDetailName= key.split(concort)[1] ; + String tableName= key.split(concort)[0] ; + String prefix = ""; + String id = "dataId"; + if(usedetail == 1){ + prefix = "detail_"; + id = "detailId"; + } + + boolean isLeaveBack = false; + if(durationTypeEnum == DurationTypeEnum.LEAVEBACK){ + isLeaveBack = true; + } + boolean isProcessChange = false; + boolean isProcessDrawBack = false; + if(durationTypeEnum == DurationTypeEnum.PROCESSCHANGE){ + isProcessChange = true; + String changetype = Util.null2s(rs1.getString("changetype"), ""); + if("1".equalsIgnoreCase(changetype)){ + //如果是撤销的话,没有开始日期时间和结束日期时间 + isProcessDrawBack = true; + } + } + + String resourceId = ""; + //查询到的requestid + String requestId_rs = ""; + + String idVal = Util.null2s(rs1.getString(id), "0"); + String fromDate = Util.null2s(rs1.getString(prefix+"fromDate"), ""); + String toDate = Util.null2s(rs1.getString(prefix+"toDate"), ""); + String fromTime = Util.null2s(rs1.getString(prefix+"fromTime"), ""); + String toTime = Util.null2s(rs1.getString(prefix+"toTime"), ""); + String durationDB = Util.null2s(rs1.getString(prefix+"duration"), ""); + if(isLeaveBack || isProcessChange){ + resourceId = Util.null2s(rs1.getString("resourceId"), ""); + }else{ + resourceId = Util.null2s(rs1.getString(prefix+"resourceId"), ""); + } + if(Util.getIntValue(requestId,0) <= 0){ + requestId_rs = Util.null2s(rs1.getString("requestId"), "0"); + } + + boolean isVal = checkActionValidate(result, fromDate, toDate, fromTime, toTime, datetimeFormatter); + if(isProcessDrawBack){ + result.clear(); + result.put("isProcessDrawBack", "1"); + isVal = true; + } + if(!isVal){ + isFillRight = false; + return isFillRight; + } + if(isLeaveBack){ + LocalDateTime localFromDateTime = LocalDateTime.parse(fromDate+" "+fromTime,datetimeFormatter); + LocalDateTime localToDateTime = LocalDateTime.parse(toDate+" "+toTime,datetimeFormatter); + + isFillRight = KQFlowLeaveBackUtil.leaveBackCheck(rs1 ,datetimeFormatter,prefix,localFromDateTime,localToDateTime,result); + if(!isFillRight){ + return isFillRight; + } + } + if(isProcessChange){ + isFillRight = KQFlowProcessChangeUtil.processChangeCheck(rs1 ,requestId_rs,result); + if(!isFillRight){ + return isFillRight; + } + } + + if(usedetail == 1){ + splitBean.setDataId("0"); + splitBean.setDetailId(idVal); + splitBean.setTablenamedb(tableDetailName); + }else{ + splitBean.setDataId(idVal); + splitBean.setDetailId("0"); + splitBean.setTablenamedb(tableName); + } + splitBean.setFromdatedb(fromDate); + splitBean.setFromtimedb(fromTime); + splitBean.setTodatedb(toDate); + splitBean.setTotimedb(toTime); + + if(requestId_rs.length() > 0){ + WorkflowRequestComInfo workflowRequestComInfo = new WorkflowRequestComInfo(); + splitBean.setRequestId(requestId_rs); + splitBean.setWorkflowId(workflowRequestComInfo.getWorkflowId(requestId_rs)); + }else{ + splitBean.setRequestId(requestId); + splitBean.setWorkflowId(workflowId); + } + splitBean.setUsedetail(""+usedetail); + splitBean.setResourceId(resourceId); + splitBean.setSubcompanyid(Util.null2s(rci.getSubCompanyID(resourceId),"0")); + splitBean.setDepartmentid(Util.null2s(rci.getDepartmentID(resourceId),"0")); + splitBean.setJobtitle(Util.null2s(rci.getJobTitle(resourceId),"0")); + splitBean.setFromDate(fromDate); + splitBean.setFromTime(fromTime); + splitBean.setToDate(toDate); + splitBean.setToTime(toTime); + splitBean.setDurationDB(durationDB); + //默认记录的状态都为0 + splitBean.setStatus("0"); + splitBean.setDurationTypeEnum(durationTypeEnum); + + switch (durationTypeEnum){ + case LEAVE: + KQFlowLeaveUtil.bean4Leave(prefix,rs1,splitBean); + break; + case EVECTION: + KQFlowEvectionUtil.bean4Evection(prefix,rs1,splitBean); + break; + case OUT: + KQFlowOutUtil.bean4Out(splitBean); + break; + case OVERTIME: + KQFlowOvertimeUtil.bean4Overtime(prefix,rs1,splitBean); + break; + case LEAVEBACK: + KQFlowLeaveBackUtil.bean4LeaveBack(prefix,rs1,splitBean); + break; + case OTHER: + bean4Other(prefix,rs1,splitBean); + break; + case PROCESSCHANGE: + KQFlowProcessChangeUtil.bean4ProcessChange(prefix,rs1,splitBean); + break; + default: + break; + } + String computingMode = splitBean.getComputingMode(); + String newLeaveType = splitBean.getNewLeaveType(); + if("2".equalsIgnoreCase(computingMode)){ + if(durationTypeEnum == DurationTypeEnum.PROCESSCHANGE){ + double oneDayHour = getOneDayHour(splitBean.getDurationTypeEnum(),newLeaveType); + splitBean.setOneDayHour(oneDayHour); + }else{ + double oneDayHour = getOneDayHour(durationTypeEnum,newLeaveType); + splitBean.setOneDayHour(oneDayHour); + } + } + return isFillRight; + + } + + private void bean4Other(String prefix, RecordSet rs1, SplitBean splitBean) { + String minimumUnit = "1"; + String computingMode = "1"; + splitBean.setDurationrule(minimumUnit); + splitBean.setComputingMode(computingMode); + } + + + /** + * 获取按照自然日计算的时候,按天/半天计算的时候一天对应的小时数 + * @param durationTypeEnum + * @param newLeaveType + * @return + */ + public static double getOneDayHour(DurationTypeEnum durationTypeEnum,String newLeaveType){ + double oneDayHour = 0.0; + //TODO KQLeaveRulesBiz.getHoursToDay如果单位是小时的时候取不到日折算时长 + switch (durationTypeEnum){ + case LEAVE: + oneDayHour = Util.getDoubleValue(KQLeaveRulesBiz.getHoursToDay(newLeaveType), 0.0); + break; + case EVECTION: + oneDayHour = Util.getDoubleValue(KQTravelRulesBiz.getHoursToDay(), 0.0); + break; + case OUT: + oneDayHour = Util.getDoubleValue(KQExitRulesBiz.getHoursToDay(), 0.0); + break; + case OVERTIME: + oneDayHour = KQOvertimeRulesBiz.getHoursToDay(); + break; + case LEAVEBACK: + oneDayHour = Util.getDoubleValue(KQLeaveRulesBiz.getHoursToDay(newLeaveType), 0.0); + break; + default: + } + return oneDayHour; + } + + public boolean checkActionValidate(Map result,String fromDate,String toDate,String fromTime,String toTime, DateTimeFormatter datetimeFormatter){ + + boolean isVal = true; + + if(Util.null2String(fromDate,"").length() == 0 || + Util.null2String(toDate,"").length() == 0 || + Util.null2String(fromTime,"").length() == 0 || + Util.null2String(toTime,"").length() == 0){ + result.put("status", "-1"); + result.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005411,weaver.general.ThreadVarLanguage.getLang())+""); + isVal = false; + return isVal; + } + if((fromDate+" "+fromTime).length() != 16 || (toDate+" "+toTime).length() != 16){ + result.put("status", "-1"); + result.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005412,weaver.general.ThreadVarLanguage.getLang())+""+(fromDate+" "+fromTime)+":"+(toDate+" "+toTime)); + isVal = false; + return isVal; + } + LocalDate localFromDate = LocalDate.parse(fromDate); + LocalDate localToDate = LocalDate.parse(toDate); + LocalDateTime localFromDateTime = LocalDateTime.parse(fromDate+" "+fromTime,datetimeFormatter); + LocalDateTime localToDateTime = LocalDateTime.parse(toDate+" "+toTime,datetimeFormatter); + + if(localFromDateTime.isAfter(localToDateTime)){ + result.put("status", "-1"); + result.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(511480,weaver.general.ThreadVarLanguage.getLang())+""); + isVal = false; + return isVal; + } + + if (localFromDate.isAfter(localToDate)) { + result.put("status", "-1"); + result.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005413,weaver.general.ThreadVarLanguage.getLang())+""); + isVal = false; + return isVal; + } + return isVal; + } + + + /** + * 插入数据到中间表 + * @param splitBeans + * @param flowTypeEnum + * @param rci + * @param result + * @param isForce + * @param requestId + * @param workflowId + * @param isUpgrade 是否是升级,升级的话不需要处理假期余额数据 + * @throws Exception + */ + public void handleSplitFLowActionData( + List splitBeans, KqSplitFlowTypeEnum flowTypeEnum, + ResourceComInfo rci, Map result, boolean isForce, int requestId, + int workflowId,boolean isUpgrade) throws Exception{ + + RecordSet rs = new RecordSet(); + RecordSet rs1 = new RecordSet(); + Map custome_map = Maps.newHashMap(); + List custome_field = Lists.newArrayList(); + if(flowTypeEnum == KqSplitFlowTypeEnum.OVERTIME){ + custome_field.add("overtime_type"); + } + + String batchSql = "insert into "+flowTypeEnum.getTablename()+" (" + + "requestid,workflowid,dataid,detailid,resourceid,fromdate,fromtime," + + "todate,totime,newleavetype,duration,usedetail,durationrule,tablenamedb,fromdatedb," + + "fromtimedb,todatedb,totimedb,durationdb,status,belongDate,D_Mins,serialid," + + "changeType,subcompanyid,departmentid,jobtitle,companion,iscompanion"+getCustomField(custome_field,"field",null, + custome_map)+")"+ + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?"+getCustomField(custome_field,"param",null, + custome_map)+") "; + List params = new ArrayList(); + + List formateList = new ArrayList<>(); + for(SplitBean bean : splitBeans){ + List beanParams = new ArrayList(); + beanParams.add(bean.getRequestId()); + beanParams.add(bean.getWorkflowId()); + beanParams.add(bean.getDataId()); + beanParams.add(bean.getDetailId()); + beanParams.add(bean.getResourceId()); + beanParams.add(bean.getFromDate()); + beanParams.add(bean.getFromTime()); + beanParams.add(bean.getToDate()); + beanParams.add(bean.getToTime()); + beanParams.add(bean.getNewLeaveType()); + beanParams.add(Util.null2s(bean.getDuration(),"0")); + beanParams.add(bean.getUsedetail()); + beanParams.add(bean.getDurationrule()); + beanParams.add(bean.getTablenamedb()); + beanParams.add(bean.getFromdatedb()); + beanParams.add(bean.getFromtimedb()); + beanParams.add(bean.getTodatedb()); + beanParams.add(bean.getTotimedb()); + beanParams.add(bean.getDurationDB()); + beanParams.add(bean.getStatus()); + beanParams.add(bean.getBelongDate()); + beanParams.add(bean.getD_Mins()); + beanParams.add(bean.getSerialid()); + beanParams.add(bean.getChangeType()); + beanParams.add(bean.getSubcompanyid()); + beanParams.add(bean.getDepartmentid()); + beanParams.add(bean.getJobtitle()); + beanParams.add(bean.getCompanion()); + beanParams.add(bean.getIscompanion()); + if(!custome_field.isEmpty()){ + if(flowTypeEnum == KqSplitFlowTypeEnum.OVERTIME){ + custome_map.put("overtime_type", bean.getOvertime_type()); + } + getCustomField(custome_field, "value",beanParams,custome_map); + } + + String format = bean.getResourceId()+"_"+bean.getBelongDate(); + formateList.add(format); + + params.add(beanParams); + + if(flowTypeEnum == KqSplitFlowTypeEnum.EVECTION && false){ + //qc898997 已经改成根据每个人的班次来计算了,这里就屏蔽了 + KQFlowEvectionUtil kqFlowEvectionUtil = new KQFlowEvectionUtil(); + String companion = Util.null2s(bean.getCompanion(), ""); + if(companion.length() > 0){ + kqFlowEvectionUtil.splitEvectionCompanion(companion,bean,params,rci,formateList); + } + } + } + if(!params.isEmpty()){ + //先根据requestid删除中间表里的数据,再做啥插入操作 + String delSql = "delete from "+flowTypeEnum.getTablename()+" where requestid = "+requestId; + rs.executeUpdate(delSql); + + for(int i = 0 ; i < params.size() ; i++){ + List beanParams = params.get(i); + boolean isOk = rs1.executeUpdate(batchSql, beanParams); + if(!isOk){ + delSql = "delete from "+flowTypeEnum.getTablename()+" where requestid = "+requestId; + rs.executeUpdate(delSql); + result.put("status", "-1"); + result.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005408,weaver.general.ThreadVarLanguage.getLang())+":"+flowTypeEnum.getTablename()+""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005414,weaver.general.ThreadVarLanguage.getLang())+""); + kqLog.info("handleSplitFLowActionData:"+flowTypeEnum.getTablename()+"拆分保存失败:"+params); + return ; + } + } + kqLog.info("handleSplitFLowActionData:formateList:"+formateList+":flowTypeEnum:"+flowTypeEnum); + for(String format: formateList){ + kqLog.info("handleSplitFLowActionData:format:"+ JSON.toJSONString(format)+":flowTypeEnum:"+flowTypeEnum); + String[] formats = format.split("_"); + if(!isUpgrade){ + //考勤设置升级的话 流程数据就不需要格式化考勤了 + new KQFormatData().formatKqDate(formats[0],formats[1]); + } + } + if(!isUpgrade){ + if(isForce){ + if(flowTypeEnum == KqSplitFlowTypeEnum.LEAVE){ + //先在这里执行扣减动作 + SplitActionUtil.handleLeaveAction(splitBeans,""+requestId); + //然后再把扣减的了数据更新下KQ_ATT_VACATION表 + String updateFreezeSql = "update KQ_ATT_VACATION set status=0 where requestId=? and workflowId = ? "; + boolean isUpdate = rs.executeUpdate(updateFreezeSql,requestId,""+workflowId); + if(!isUpdate){ + result.put("status", "-1"); + result.put("message", (""+weaver.systeminfo.SystemEnv.getHtmlLabelName(82823,weaver.general.ThreadVarLanguage.getLang())+"action"+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005361,weaver.general.ThreadVarLanguage.getLang())+""+updateFreezeSql+"(0,"+requestId+","+workflowId+")")); + kqLog.info("扣减action保存失败:"+updateFreezeSql+"(0,"+requestId+","+workflowId+")"); + return ; + } + }else if(flowTypeEnum == KqSplitFlowTypeEnum.OVERTIME){ + // 强制归档,加班数据第一第二种规则都需要处理 + SplitActionUtil.handleOverTimeAction(splitBeans, ""+requestId,true, ""); + } + }else{ + if(flowTypeEnum == KqSplitFlowTypeEnum.OVERTIME){ + //正常归档的时候 单独针对加班规则的第一 第二种模式 生成加班数据 + SplitActionUtil.handleOverTimeActionMode2(splitBeans, ""+requestId); + } + } + }else{ + if(flowTypeEnum == KqSplitFlowTypeEnum.OVERTIME){ + if(!splitBeans.isEmpty()){ + for (SplitBean splitBean : splitBeans) { + String sql = "delete from kq_flow_overtime where requestid=? "; + rs.executeUpdate(sql, splitBean.getRequestId()); + } + } + SplitActionUtil.handleOverTimeActionMode2(splitBeans, ""+requestId); + } + } + }else{ + rs1.writeLog(flowTypeEnum.getTablename()+"生成的params是空:"); + return ; + } + } + + /** + * 考勤流程中间表针对某个流程扩展字段 + * @param custome_field + * @param key + * @param beanParams + * @param custome_map + * @return + */ + public String getCustomField(List custome_field, String key, List beanParams, + Map custome_map) { + String fieldValue = ""; + if(!custome_field.isEmpty()){ + for(int i = 0 ; i < custome_field.size() ; i++){ + String tmp_value = Util.null2String(custome_field.get(i)); + if(tmp_value.length() > 0){ + if("field".equalsIgnoreCase(key)){ + fieldValue += ","+tmp_value; + }else if("param".equalsIgnoreCase(key)){ + fieldValue += ",?"; + }else if("value".equalsIgnoreCase(key)){ + String value = custome_map.get(tmp_value); + beanParams.add(value); + } + } + } + } + return fieldValue; + } + +} diff --git a/src/com/engine/kq/wfset/util/SplitActionUtil.java b/src/com/engine/kq/wfset/util/SplitActionUtil.java new file mode 100644 index 0000000..700a249 --- /dev/null +++ b/src/com/engine/kq/wfset/util/SplitActionUtil.java @@ -0,0 +1,3419 @@ +package com.engine.kq.wfset.util; + +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSON; +import com.engine.kq.bean.KQHrmScheduleSign; +import com.engine.kq.biz.*; +import com.engine.kq.biz.chain.duration.WorkHalfUnitSplitChain; +import com.engine.kq.biz.chain.shiftinfo.ShiftInfoBean; +import com.engine.kq.entity.KQOvertimeRulesDetailEntity; +import com.engine.kq.enums.DurationTypeEnum; +import com.engine.kq.jucailin.util.KQDateUtil; +import com.engine.kq.log.KQLog; +import com.engine.kq.timer.KQQueue; +import com.engine.kq.timer.KQTaskBean; +import com.engine.kq.util.KQDurationCalculatorUtil; +import com.engine.kq.wfset.bean.SplitBean; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.apache.commons.collections.CollectionUtils; +import weaver.common.DateUtil; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.general.Util; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.sql.Date; +import java.sql.Timestamp; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +public class SplitActionUtil extends BaseBean { + public static KQLog kqLog = new KQLog(); + + private static BaseBean baseBean = new BaseBean(); + + /** + * 现在先用正常的去执行吧 + * + * @param splitBeans + * @param requestid + */ + public static void handleLeaveAction(List splitBeans, String requestid) { + for (int i = 0; i < splitBeans.size(); i++) { + SplitBean splitBean = splitBeans.get(i); + String resourceId = splitBean.getResourceId(); + String duration = splitBean.getDuration(); + String newLeaveType = splitBean.getNewLeaveType(); + String durationrule = splitBean.getDurationrule(); + String fromdate = splitBean.getFromDate(); + String fromdatedb = splitBean.getFromdatedb(); + kqLog.info("请假扣减:resourceId:" + resourceId + ":fromdate:" + fromdate + ":duration:" + duration + ":newLeaveType:" + newLeaveType + ":durationrule:" + durationrule + ":requestid:" + requestid + ":fromdatedb:" + fromdatedb); + if(Util.getDoubleValue(duration) <= 0){ + continue; + } + KQBalanceOfLeaveBiz.addUsedAmount(resourceId, fromdate, newLeaveType, duration, "", requestid, fromdatedb); + } + } + + /** + * 单独针对加班规则的第二种模式 生成加班数据 + * + * @param splitBeans + * @param requestid + */ + public static void handleOverTimeActionMode2(List splitBeans, String requestid) { + clearSameRequestTX(requestid); + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + List overKeys = new ArrayList<>(); + for (int i = 0; i < splitBeans.size(); i++) { + SplitBean splitBean = splitBeans.get(i); + int computingMode = Util.getIntValue(splitBean.getComputingMode()); + if (computingMode == 2 || computingMode == 4) { + //判断流程对应的日期下有没有打卡数据,如果有的话,需要生成相应的调休数据 + String belongDate = splitBean.getBelongDate(); + String resourceId = splitBean.getResourceId(); + String fromtime = splitBean.getFromTime(); + int fromtimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(fromtime); + String key = resourceId + "_" + belongDate + "_" + belongDate; + if (fromtimeIndex > 1439) { + //跨天了 + key = resourceId + "_" + belongDate + "_" + DateUtil.addDate(belongDate, 1); + } + if (!overKeys.contains(key)) { + overKeys.add(key); + } + } + if (computingMode == 1) { + doComputingMode1_splitBean(splitBean); + } + } + KQOverTimeRuleCalBiz kqOvertimeCalBiz = new KQOverTimeRuleCalBiz(); + kqLog.info("加班生成调休:handleOverTimeActionMode2 overKeys:" + JSON.toJSONString(overKeys)); + if (overKeys != null && !overKeys.isEmpty()) { + for (String key : overKeys) { + String[] keys = key.split("_", -1); + if (keys.length == 3) { + String resourceId = keys[0]; + String fromDate = keys[1]; + String belongToDate = keys[2]; + if(checkHasKTCard(resourceId, fromDate)){ + fromDate = DateUtil.addDate(fromDate,-1); + } + kqOvertimeCalBiz.buildOvertime(resourceId, fromDate, belongToDate, "加班流程生成加班#flow,requestId:" + requestid); + } + } + } + } + + /** + * 判斷下昨日的打卡有沒有落在今日的數據,如果有,則加班需要往前多算一天 + * @param resourceId + * @param belongDate + * @return + */ + public static boolean checkHasKTCard(String resourceId, String belongDate){ + RecordSet recordSet = new RecordSet(); + //如果打卡存在跨天的情况 + String sql = "select count(*) as cnt from KQ_FORMAT_DETAIL where RESOURCEID="+resourceId+" and KQDATE='"+ DateUtil.addDate(belongDate, -1)+"' and (SIGNOUTDATE='"+belongDate+"' or signindate='"+belongDate+"')"; + recordSet.executeQuery(sql); + if(recordSet.next()){ + String cnt = recordSet.getString("cnt"); + if(Util.getIntValue(cnt, 0) > 0){ + return true; + } + } + return false; + } + + public static void turnOvertimeBeansWithRule(List splitBeans) { + + Map> resourceMap = new HashMap<>(); + //公众假日加班时长 + double D_Pub_Duration = 0.0; + double D_Pub_Mins = 0.0; + //工作日加班时长 + double D_Work_Duration = 0.0; + double D_Work_Mins = 0.0; + //休息日加班时长 + double D_Rest_Duration = 0.0; + double D_Rest_Mins = 0.0; + + //公众假日加班 + List holiday = new ArrayList<>(); + //工作日加班 + List work = new ArrayList<>(); + //休息日加班 + List rest = new ArrayList<>(); + + String pub_date = ""; + String work_date = ""; + String rest_date = ""; + + //每一天的流程时长都在这里了,搞吧 + for (SplitBean sb : splitBeans) { +// * 1-公众假日、2-工作日、3-休息日 + String tmpResid = sb.getResourceId(); + if (resourceMap.containsKey(tmpResid)) { + resourceMap.get(tmpResid).add(sb); + } else { + List splitBeans_tmp = new ArrayList<>(); + splitBeans_tmp.add(sb); + resourceMap.put(tmpResid, splitBeans_tmp); + } + } + if (!resourceMap.isEmpty()) { + for (Map.Entry> me : resourceMap.entrySet()) { + String resourceid = me.getKey(); + List tmp_splitbeans = me.getValue(); + for (SplitBean sb : tmp_splitbeans) { +// * 1-公众假日、2-工作日、3-休息日 + int changeType = sb.getChangeType(); + double durations = Util.getDoubleValue(sb.getDuration(), 0.0); + double durationMins = sb.getD_Mins(); + if (1 == changeType) { + D_Pub_Duration += durations; + D_Pub_Mins += durationMins; + pub_date = sb.getBelongDate(); + holiday.add(sb); + } + if (2 == changeType) { + D_Work_Duration += durations; + D_Work_Mins += durationMins; + work_date = sb.getBelongDate(); + work.add(sb); + } + if (3 == changeType) { + D_Rest_Duration += durations; + D_Rest_Mins += durationMins; + rest_date = sb.getBelongDate(); + rest.add(sb); + } + } + + if (D_Pub_Duration > 0) { + int minimumUnit = KQOvertimeRulesBiz.getMinimumLen(resourceid, pub_date); + if (D_Pub_Mins < minimumUnit) { + for (SplitBean tmp : holiday) { + tmp.setDuration("0.0"); + tmp.setD_Mins(0.0); + } + } + } + if (D_Work_Duration > 0) { + int minimumUnit = KQOvertimeRulesBiz.getMinimumLen(resourceid, work_date); + if (D_Work_Mins < minimumUnit) { + for (SplitBean tmp : work) { + tmp.setDuration("0.0"); + tmp.setD_Mins(0.0); + } + } + } + if (D_Rest_Duration > 0) { + int minimumUnit = KQOvertimeRulesBiz.getMinimumLen(resourceid, rest_date); + if (D_Rest_Mins < minimumUnit) { + for (SplitBean tmp : rest) { + tmp.setDuration("0.0"); + tmp.setD_Mins(0.0); + } + } + } + } + } + + } + + /** + * 生成加班数据 + * + * @param splitBeans + * @param requestid + * @param canMode2 是否是归档节点 归档节点才可以把加班数据写到加班中间表,不是归档节点的话意味着只生成调休不生成加班,只有强制归档canMode2才是true + * @param from_uuid 来自action的uuid + */ + public static void handleOverTimeAction(List splitBeans, String requestid, + boolean canMode2, String from_uuid) throws Exception { +// 保证同一个requestid能重复生成调休和加班 + if (canMode2) { + clearSameRequestTX(requestid); + } + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + RecordSet rs = new RecordSet(); + List overKeys = new ArrayList<>(); + for (int i = 0; i < splitBeans.size(); i++) { + SplitBean splitBean = splitBeans.get(i); + String resourceId = splitBean.getResourceId(); + String belongDate = splitBean.getBelongDate(); + String toDate = splitBean.getToDate(); + String duration = splitBean.getDuration(); + String durationrule = splitBean.getDurationrule(); + + int computingMode = Util.getIntValue(splitBean.getComputingMode()); + int changeType = splitBean.getChangeType(); + String paidSql = "insert into KQ_PAID_VACATION (requestId,workflowId,dataid,detailid,resourceId,fromDate,fromTime,toDate,toTime,duration,durationrule,computingMode,changeType)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?) "; + boolean isLog = rs.executeUpdate(paidSql, splitBean.getRequestId(), splitBean.getWorkflowId(), + splitBean.getDataId(), splitBean.getDetailId(), splitBean.getResourceId(), + splitBean.getFromDate(), splitBean.getFromTime(), splitBean.getToDate(), + splitBean.getToTime(), splitBean.getDuration(), splitBean.getDurationrule(), computingMode, changeType); + if (isLog) { + kqLog.info("加班生成调休:resourceId:" + resourceId + ":computingMode:" + computingMode + ":belongDate:" + belongDate + ":duration:" + duration + ":durationrule:" + durationrule + ":requestid:" + requestid); + + if (computingMode == 1) { + doComputingMode1_4TX(splitBean); + if (canMode2) { + doComputingMode1_splitBean(splitBean); + } + } + if (canMode2 && (computingMode == 2 || computingMode == 4)) { + //判断流程对应的日期下有没有打卡数据,如果有的话,需要生成相应的调休数据 + String fromtime = splitBean.getFromTime(); + int fromtimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(fromtime); + String key = resourceId + "_" + belongDate + "_" + belongDate; + if (fromtimeIndex > 1439) { + //跨天了 + key = resourceId + "_" + belongDate + "_" + DateUtil.addDate(belongDate, 1); + } + if (!overKeys.contains(key)) { + overKeys.add(key); + } + } + } + } + KQOverTimeRuleCalBiz kqOvertimeCalBiz = new KQOverTimeRuleCalBiz(); + kqLog.info("加班生成调休:handleOverTimeAction overKeys:" + JSON.toJSONString(overKeys)); + if (overKeys != null && !overKeys.isEmpty()) { + for (String key : overKeys) { + String[] keys = key.split("_", -1); + if (keys.length == 3) { + String resourceId = keys[0]; + String fromDate = keys[1]; + String belongToDate = keys[2]; + if(checkHasKTCard(resourceId, fromDate)){ + fromDate = DateUtil.addDate(fromDate,-1); + } + kqOvertimeCalBiz.buildOvertime(resourceId, fromDate, belongToDate, "加班流程生成加班#flow,requestId:" + requestid + "#from_uuid|" + from_uuid); + } + } + } + } + + /** + * 保证同一个requestid能重复生成调休和加班 + * + * @param requestid + */ + public static void clearSameRequestTX(String requestid) { + String all_tiaoxiuids = ""; + List all_tiaoxiuidList = Lists.newArrayList(); + RecordSet rs = new RecordSet(); + String sql = "select * from kq_flow_overtime where requestid = ? "; + rs.executeQuery(sql, requestid); + while (rs.next()) { + String tiaoxiuid = Util.null2String(rs.getString("tiaoxiuid"), ""); + if (tiaoxiuid.length() > 0 && Util.getIntValue(tiaoxiuid) > 0) { + all_tiaoxiuids += "," + tiaoxiuid; + all_tiaoxiuidList.add(tiaoxiuid); + } + } + if (all_tiaoxiuids.length() > 0) { + all_tiaoxiuids = all_tiaoxiuids.substring(1); + String tiaoxiuidis0 = ""; + String delSql0 = "select * from kq_balanceofleave where " + Util.getSubINClause(all_tiaoxiuids, "id", "in") + " and " + + " baseamount =0 and extraamount=0 and usedamount=0 and baseamount2=0 and extraamount2=0 and usedamount2=0 "; + + if (rs.getDBType().equalsIgnoreCase("oracle")) { + delSql0 = "select * from kq_balanceofleave where " + Util.getSubINClause(all_tiaoxiuids, "id", "in") + " and " + + " nvl(baseamount,0) =0 and nvl(extraamount,0)=0 and nvl(usedamount,0)=0 and nvl(baseamount2,0)=0 " + + " and nvl(extraamount2,0)=0 and nvl(usedamount2,0)=0 "; + } else if ((rs.getDBType()).equalsIgnoreCase("mysql")) { + delSql0 = "select * from kq_balanceofleave where " + Util.getSubINClause(all_tiaoxiuids, "id", "in") + " and " + + " ifnull(baseamount,0) =0 and ifnull(extraamount,0)=0 and ifnull(usedamount,0)=0 and ifnull(baseamount2,0)=0 " + + " and ifnull(extraamount2,0)=0 and ifnull(usedamount2,0)=0 "; + } else { + delSql0 = "select * from kq_balanceofleave where " + Util.getSubINClause(all_tiaoxiuids, "id", "in") + " and " + + " isnull(baseamount,0) =0 and isnull(extraamount,0)=0 and isnull(usedamount,0)=0 and isnull(baseamount2,0)=0 " + + " and isnull(extraamount2,0)=0 and isnull(usedamount2,0)=0 "; + } + rs.executeQuery(delSql0); + kqLog.info("all_tiaoxiuidList:" + all_tiaoxiuidList); + kqLog.info("clearSameRequestTX:" + delSql0); + while (rs.next()) { + String tiaoxiuid = Util.null2String(rs.getString("id"), ""); + if (tiaoxiuid.length() > 0 && Util.getIntValue(tiaoxiuid) > 0) { + tiaoxiuidis0 += "," + tiaoxiuid; + all_tiaoxiuidList.remove(tiaoxiuid); + } + } + kqLog.info("all_tiaoxiuidList:" + all_tiaoxiuidList); + kqLog.info("tiaoxiuidis0:" + tiaoxiuidis0); + if (tiaoxiuidis0.length() > 0) { + tiaoxiuidis0 = tiaoxiuidis0.substring(1); + String delSql = "delete from kq_balanceofleave where " + Util.getSubINClause(tiaoxiuidis0, "id", "in"); + boolean isok = rs.executeUpdate(delSql); + kqLog.info("delSql:" + delSql + ":isok:" + isok); + } + if (!all_tiaoxiuidList.isEmpty()) { + String clear_tiaoxiuids = all_tiaoxiuidList.stream().collect(Collectors.joining(",")); + String clearSql = "update kq_balanceofleave set tiaoxiuamount=0.0,update_time=? where " + Util.getSubINClause(clear_tiaoxiuids, "id", "in"); + if (rs.getDBType().equals("postgresql")) { + clearSql = "update kq_balanceofleave set tiaoxiuamount=0.0,update_time=?::timestamp where " + Util.getSubINClause(clear_tiaoxiuids, "id", "in"); + } + boolean isclearOk = rs.executeUpdate(clearSql, KQDateUtil.getUpdateTimeStamp()); + kqLog.info("clearSql:" + clearSql + ":isclearOk:" + isclearOk); + } + + String delUsageSql = "delete from kq_usagehistory where " + Util.getSubINClause(all_tiaoxiuids, "balanceofleaveid", "in"); + boolean isdelUsageOk = rs.executeUpdate(delUsageSql); + kqLog.info("delUsageSql:" + delUsageSql + ":isdelUsageOk:" + isdelUsageOk); + } + String delSql = "delete from kq_flow_overtime where requestid = ? "; + boolean isDelOk = rs.executeUpdate(delSql, requestid); + kqLog.info("delSql:" + delSql + ":requestid:" + requestid + ":isDelOk:" + isDelOk); + } + + /** + * 加班方式是第一种,如果是先生成调休,后面才生成加班,需要先把调休给按照加班规则给生成出来 + * + * @param splitBean + */ + public static void doComputingMode1_4TX(SplitBean splitBean) { + RecordSet rs = new RecordSet(); + int changeType = splitBean.getChangeType(); + String resourceId = splitBean.getResourceId(); + String belongDate = splitBean.getBelongDate(); + String duration = splitBean.getDuration(); + String fromdateDB = splitBean.getFromdatedb(); + String requestId = splitBean.getRequestId(); + String fromdate = splitBean.getFromDate(); + String fromtime = splitBean.getFromTime(); + String todate = splitBean.getToDate(); + String totime = splitBean.getToTime(); + String overtime_type = splitBean.getOvertime_type(); + double D_Mins = splitBean.getD_Mins(); + int workMins = splitBean.getWorkmins(); + String workingHours = Util.null2String(workMins / 60.0); + Map changeTypeMap = Maps.newHashMap(); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + KQOverTimeRuleCalBiz kqOverTimeRuleCalBiz = new KQOverTimeRuleCalBiz(); + Map overRulesDetailMap = Maps.newHashMap(); + Map> restTimeMap = Maps.newHashMap(); + Map computingModeMap = Maps.newHashMap(); + //先获取一些前提数据,加班規則和假期規則 + kqOverTimeRuleCalBiz.getOverTimeDataMap(resourceId, belongDate, belongDate, dateFormatter, changeTypeMap, overRulesDetailMap, restTimeMap, computingModeMap); + + String changeType_key = belongDate + "_" + changeType; + if (!overRulesDetailMap.containsKey(changeType_key)) { + return; + } +// 根据加班单位重新生成下加班分钟数 + D_Mins = kqOverTimeRuleCalBiz.getD_MinsByUnit(D_Mins); + + KQOvertimeRulesDetailEntity kqOvertimeRulesDetailEntity = overRulesDetailMap.get(changeType_key); + int paidLeaveEnable = kqOverTimeRuleCalBiz.getPaidLeaveEnable(kqOvertimeRulesDetailEntity, overtime_type); + Map otherParam = Maps.newHashMap(); + otherParam.put("overtime_type", overtime_type); + + String tiaoxiuId = KQBalanceOfLeaveBiz.addExtraAmountByDis5(resourceId, belongDate, D_Mins + "", "0", workingHours, requestId, "1", fromdateDB, otherParam); + if (Util.getIntValue(tiaoxiuId) > 0) { + //为啥要用kq_overtime_tiaoxiu这个表呢,因为kqpaidleaveaction可能和splitaction不是在同一个归档前节点 + String split_key = splitBean.getRequestId() + "_" + splitBean.getDataId() + "_" + splitBean.getDetailId() + "_" + + splitBean.getFromDate() + "_" + splitBean.getFromTime() + "_" + splitBean.getToDate() + "_" + + splitBean.getToTime() + "_" + splitBean.getD_Mins(); + String tiaoxiuId_sql = "insert into kq_overtime_tiaoxiu(split_key,tiaoxiu_id) values(?,?) "; + rs.executeUpdate(tiaoxiuId_sql, split_key, tiaoxiuId); + kqLog.info("doComputingMode1 加班生成调休成功!!!"); + } else { + kqLog.info("doComputingMode1 加班生成调休失败!!!"); + } + } + + /** + * 加班方式是第一种,然后再流程归档的时候把加班数据写到加班中间表里 + * + * @param splitBean + */ + public static void doComputingMode1_splitBean(SplitBean splitBean) { + try { + kqLog.info("doComputingMode1_splitBean:splitBean: " + (splitBean != null ? JSON.toJSONString(splitBean) : "null")); + RecordSet rs = new RecordSet(); + RecordSet rs1 = new RecordSet(); + int changeType = splitBean.getChangeType(); + String requestId = splitBean.getRequestId(); + String resourceId = splitBean.getResourceId(); + String belongDate = splitBean.getBelongDate(); + String duration = splitBean.getDuration(); + String durationrule = splitBean.getDurationrule(); + String fromdateDB = splitBean.getFromdatedb(); + String fromtimedb = splitBean.getFromtimedb(); + String todatedb = splitBean.getTodatedb(); + String totimedb = splitBean.getTotimedb(); + String fromdate = splitBean.getFromDate(); + String fromtime = splitBean.getFromTime(); + String todate = splitBean.getToDate(); + String totime = splitBean.getToTime(); + double D_Mins = splitBean.getD_Mins(); + Map changeTypeMap = Maps.newHashMap(); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + KQOverTimeRuleCalBiz kqOverTimeRuleCalBiz = new KQOverTimeRuleCalBiz(); + Map overRulesDetailMap = Maps.newHashMap(); + Map> restTimeMap = Maps.newHashMap(); + Map computingModeMap = Maps.newHashMap(); + //先获取一些前提数据,加班規則和假期規則 + kqOverTimeRuleCalBiz.getOverTimeDataMap(resourceId, belongDate, belongDate, dateFormatter, changeTypeMap, overRulesDetailMap, restTimeMap, computingModeMap); + String overtime_type = splitBean.getOvertime_type(); + String changeType_key = belongDate + "_" + changeType; + if (!overRulesDetailMap.containsKey(changeType_key)) { + return; + } + KQOvertimeRulesDetailEntity kqOvertimeRulesDetailEntity = overRulesDetailMap.get(changeType_key); + int paidLeaveEnable = kqOverTimeRuleCalBiz.getPaidLeaveEnable(kqOvertimeRulesDetailEntity, overtime_type); + int unit = KQOvertimeRulesBiz.getMinimumUnit(); + + String tiaoxiu_id = ""; + String overtime_tiaoxiu_id = ""; + + String split_key = splitBean.getRequestId() + "_" + splitBean.getDataId() + "_" + splitBean.getDetailId() + "_" + + splitBean.getFromDate() + "_" + splitBean.getFromTime() + "_" + splitBean.getToDate() + "_" + + splitBean.getToTime() + "_" + splitBean.getD_Mins(); + String check_tiaoxiu_sql = "select * from kq_overtime_tiaoxiu where split_key=? "; + rs1.executeQuery(check_tiaoxiu_sql, split_key); + if (rs1.next()) { + overtime_tiaoxiu_id = rs1.getString("id"); + tiaoxiu_id = rs1.getString("tiaoxiu_id"); + } + + fromtime = fromtime + ":00"; + totime = totime + ":00"; + Long cur = System.currentTimeMillis(); + Timestamp date = new Timestamp(cur); + String flow_overtime_sql = "insert into kq_flow_overtime(requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,fromdatedb,fromtimedb,todatedb,totimedb,tiaoxiuid,create_time,update_time,creator)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + if (rs.getDBType().equals("postgresql")) { + flow_overtime_sql = "insert into kq_flow_overtime(requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,fromdatedb,fromtimedb,todatedb,totimedb,tiaoxiuid,create_time,update_time,creator)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?::timestamp,?::timestamp,?) "; + } + boolean isUp = rs.executeUpdate(flow_overtime_sql, requestId, resourceId, fromdate, fromtime, todate, totime, D_Mins, "", belongDate, "", + unit, changeType, paidLeaveEnable, "1", fromdateDB, fromtimedb, todatedb, totimedb, tiaoxiu_id,date,date, Util.getIntValue(resourceId)); + if (!isUp) { + kqLog.info("doComputingMode1 加班数据flow_overtime_sql记录失败!!!"); + } else { + kqLog.info("doComputingMode1:flow_overtime_sql: " + flow_overtime_sql); + kqLog.info("doComputingMode1:requestId:" + requestId + ":resourceId:" + resourceId + ":fromdate:" + fromdate + ":fromtime:" + fromtime + + ":todate:" + todate + ":totime:" + totime + ":D_Mins:" + D_Mins + ":belongDate:" + belongDate + ":unit:" + unit + ":changeType:" + changeType + + ":paidLeaveEnable:" + paidLeaveEnable + ":fromdateDB:" + fromdateDB + ":fromtimedb:" + fromtimedb + ":todatedb:" + todatedb + ":totimedb:" + totimedb); + } + if (overtime_tiaoxiu_id.length() > 0 && Util.getIntValue(overtime_tiaoxiu_id) > 0) { + String delSql = "delete from kq_overtime_tiaoxiu where id = ? "; + rs1.executeUpdate(delSql, overtime_tiaoxiu_id); + } + } catch (Exception e) { + kqLog.info("加班生成数据报错:doComputingMode1_splitBean:"); + StringWriter errorsWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(errorsWriter)); + kqLog.info(errorsWriter.toString()); + } + + } + + public static List> getSplitHalfDayListRepeat(String fromDate, String toDate, String fromTime, String toTime) { + List> splitLists = new ArrayList<>(); + Map splitMap = new HashMap<>(); + + LocalDate localFromDate = LocalDate.parse(fromDate); + LocalDate localToDate = LocalDate.parse(toDate); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + long betweenDays = localToDate.toEpochDay() - localFromDate.toEpochDay(); + for (int i = 0; i <= betweenDays; i++) { + splitMap = new HashMap<>(); + LocalDate curLocalDate = localFromDate.plusDays(i); + splitMap.put("splitDate", curLocalDate.format(dateFormatter)); + int foreOrAfter = SplitSelectSet.foreOrAfter(fromTime, toTime); + splitMap.put("foreOrAfter", "" + foreOrAfter); + splitLists.add(splitMap); + } + return splitLists; + } + + /** + * 签到签退 生成加班数据 + * + * @param taskBeans + */ + public void handleOverTime(List taskBeans) throws Exception { + try { + if (true) { + KQOverTimeRuleCalBiz kqOverTimeRuleCalBiz = new KQOverTimeRuleCalBiz(); + for (int i = 0; i < taskBeans.size(); i++) { + KQTaskBean taskBean = taskBeans.get(i); + String tasktype = taskBean.getTasktype(); + String eventtype = ""; + if ("punchcard".equalsIgnoreCase(tasktype)) { + eventtype = "考勤打卡生成加班."; + } + kqOverTimeRuleCalBiz.buildOvertime(taskBean.getResourceId(), taskBean.getOvertime_fromdate(), taskBean.getOvertime_todate(), + eventtype); + } + } else { + handleOverTime_old(taskBeans); + } + } catch (Exception e) { + kqLog.info("加班生成数据报错:handleOverTime:"); + StringWriter errorsWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(errorsWriter)); + kqLog.info(errorsWriter.toString()); + } + } + + /** + * 这个加班方法后面废弃 + * 新的加班都在这里kqOverTimeRuleCalBiz.buildOvertime + * @param taskBeans + * @throws Exception + */ + @Deprecated + public void handleOverTime_old(List taskBeans) throws Exception { + DateTimeFormatter fullFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + int workMins = (int) (KQFlowUtil.getOneDayHour(DurationTypeEnum.OVERTIME, "") * 60); + kqLog.info("handleOverTime:start:" + (taskBeans != null ? JSON.toJSONString(taskBeans) : "is empty")); + //防止bean里重复的 + List repeat_taskBeans = new ArrayList<>(); + for (int i = 0; i < taskBeans.size(); i++) { + KQTaskBean taskBean = taskBeans.get(i); + if (repeat_taskBeans.contains(taskBean)) { + continue; + } else { + repeat_taskBeans.add(taskBean); + } + taskBean.setWorkmins(workMins); + String resourceId = taskBean.getResourceId(); + String taskDate = taskBean.getTaskDate(); + int overtimeEnable = KQOvertimeRulesBiz.getOvertimeEnable(resourceId, taskDate); + + //如果人再当前指定日期下未开启加班,直接跳过 + if (overtimeEnable != 1) { + kqLog.info("签到签退 生成加班数据 handleOverTimeBySign:resourceId:" + resourceId + ":taskDate:" + taskDate + "不允许加班"); + continue; + } + + int computingMode = KQOvertimeRulesBiz.getComputingMode(resourceId, taskDate); + kqLog.info("加班生成调休方式:resourceId:" + resourceId + ":taskDate:" + taskDate + ":computingMode:" + computingMode); + if (computingMode == 1) { +// 需审批,以审批单为准 + doComputingMode1(taskBean, fullFormatter); + } + if (computingMode == 2) { +// 需审批,以打卡为准,但是不能超过审批时长 + doComputingMode2(taskBean, fullFormatter); + } + if (computingMode == 3) { +// 无需审批,根据打卡时间计算加班时长 + doComputingMode3(taskBean, fullFormatter); + } + } + } + + /** + * 流程为主的就在流程归档的时候处理下,不在队列里进行处理了 + * + * @param taskBean + * @param fullFormatter + * @throws Exception + */ + @Deprecated + private void doComputingMode1(KQTaskBean taskBean, + DateTimeFormatter fullFormatter) throws Exception { + SplitBean splitBean = taskBean.getSplitBean(); + kqLog.info("doComputingMode1:splitBean: start"); + if (splitBean != null) { + RecordSet rs = new RecordSet(); + int changeType = splitBean.getChangeType(); + String requestId = splitBean.getRequestId(); + String resourceId = splitBean.getResourceId(); + String belongDate = splitBean.getBelongDate(); + String duration = splitBean.getDuration(); + String durationrule = splitBean.getDurationrule(); + String fromdateDB = splitBean.getFromdatedb(); + String fromtimedb = splitBean.getFromtimedb(); + String todatedb = splitBean.getTodatedb(); + String totimedb = splitBean.getTotimedb(); + String fromdate = splitBean.getFromDate(); + String fromtime = splitBean.getFromTime(); + String todate = splitBean.getToDate(); + String totime = splitBean.getToTime(); + double D_Mins = splitBean.getD_Mins(); + + int unit = KQOvertimeRulesBiz.getMinimumUnit(); + int paidLeaveEnable = KQOvertimeRulesBiz.getPaidLeaveEnable(resourceId, belongDate); + paidLeaveEnable = paidLeaveEnable == 1 ? 1 : 0; + + fromtime = fromtime + ":00"; + totime = totime + ":00"; + Long cur = System.currentTimeMillis(); + Date date = new Date(cur); + String flow_overtime_sql = "insert into kq_flow_overtime(requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,fromdatedb,fromtimedb,todatedb,totimedb,create_time,update_time,creator)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + if (rs.getDBType().equals("postgresql")) { + flow_overtime_sql = "insert into kq_flow_overtime(requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,fromdatedb,fromtimedb,todatedb,totimedb,create_time,update_time,creator)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?::timestamp,?::timestamp,?) "; + } + boolean isUp = rs.executeUpdate(flow_overtime_sql, requestId, resourceId, fromdate, fromtime, todate, totime, D_Mins, "", belongDate, "", + unit, changeType, paidLeaveEnable, "1", fromdateDB, fromtimedb, todatedb, totimedb,date,date, Util.getIntValue(resourceId)); + if (!isUp) { + kqLog.info("doComputingMode1 加班数据flow_overtime_sql记录失败!!!"); + } else { + kqLog.info("doComputingMode1:flow_overtime_sql: " + flow_overtime_sql); + kqLog.info("doComputingMode1:requestId:" + requestId + ":resourceId:" + resourceId + ":fromdate:" + fromdate + ":fromtime:" + fromtime + + ":todate:" + todate + ":totime:" + totime + ":D_Mins:" + D_Mins + ":belongDate:" + belongDate + ":unit:" + unit + ":changeType:" + changeType + + ":paidLeaveEnable:" + paidLeaveEnable + ":fromdateDB:" + fromdateDB + ":fromtimedb:" + fromtimedb + ":todatedb:" + todatedb + ":totimedb:" + totimedb); + } + } + } + + /** + * 无需审批,以打卡为准,但是不能超过审批时长 + * + * @param taskBean + * @param fullFormatter + */ + private void doComputingMode2(KQTaskBean taskBean, + DateTimeFormatter fullFormatter) throws Exception { + String resourceId = taskBean.getResourceId(); + String taskDate = taskBean.getTaskDate(); + KQFlowDataBiz kqFlowDataBiz = new KQFlowDataBiz.FlowDataParamBuilder().belongDateParam(taskDate).resourceidParam(resourceId).build(); + Map flowMaps = new HashMap<>(); + List splitBeans = kqFlowDataBiz.getOverTimeData(flowMaps); + if (!splitBeans.isEmpty()) { + Map flowMap = new HashMap<>(); + Map requestMap = new HashMap<>(); + for (int i = 0; i < splitBeans.size(); i++) { + SplitBean splitBean = splitBeans.get(i); + String changeTpe = "" + splitBean.getChangeType(); + String requestid = splitBean.getRequestId(); + String flowMins = Util.null2String(splitBean.getD_Mins()); + if (flowMap.get(changeTpe) != null) { + double tmpMins = Util.getDoubleValue(Util.null2String(flowMap.get(changeTpe)), 0.0); + flowMap.put(changeTpe, "" + (tmpMins + Util.getDoubleValue(flowMins))); + } else { + flowMap.put(changeTpe, flowMins); + } + if (requestMap.get(changeTpe) != null) { + String tmpRequestid = Util.null2String(requestMap.get(changeTpe)); + if (("," + tmpRequestid + ",").indexOf(requestid) < 0) { + requestMap.put(changeTpe, tmpRequestid + "," + requestid); + } + } else { + requestMap.put(changeTpe, requestid); + } + } + int changeType = KQOvertimeRulesBiz.getChangeType(resourceId, taskDate); + if (requestMap.get("" + changeType) != null) { + taskBean.setRequestId(requestMap.get("" + changeType)); + } + kqLog.info("签到签退 生成加班数据为 doComputingMode2:加班流程数据为 flowMap:" + flowMap); +// 1-节假日、2-工作日、3-休息日 + if (changeType == 1) { + doMode2ChangeType1(taskBean, fullFormatter, flowMap.get("1")); + } + if (changeType == 2) { + doMode2ChangeType2(taskBean, fullFormatter, flowMap.get("2")); + } + if (changeType == 3) { + doMode2ChangeType3(taskBean, fullFormatter, flowMap.get("3")); + } + } else { + kqLog.info("签到签退 生成加班数据为 doComputingMode2:加班流程数据为空:resourceId:" + resourceId + ":taskDate:" + taskDate); + } + } + + + /** + * 需审批,以打卡为准 + * 休息日 + * + * @param taskBean + * @param fullFormatter + * @param flowMins + */ + private void doMode2ChangeType3(KQTaskBean taskBean, DateTimeFormatter fullFormatter, + String flowMins) throws Exception { + String taskDate = taskBean.getTaskDate(); + String resourceId = taskBean.getResourceId(); + String taskSignTime = taskBean.getTaskSignTime(); + String signInTime4Out = taskBean.getSignInTime4Out(); + String requestid = taskBean.getRequestId(); + String signDate = taskBean.getSignDate(); + String signEndDate = taskBean.getSignEndDate(); + String timesource = Util.null2String(taskBean.getTimesource()); + boolean isBefore = false; + if ("before".equalsIgnoreCase(timesource)) { + isBefore = true; + } + if (taskSignTime.length() > 0 && signInTime4Out.length() > 0) { + + long mins = calNonWorkDuration(signInTime4Out, taskSignTime, taskDate, resourceId); + if (isBefore && signEndDate.compareTo(signDate) < 0) { + //打卡日期和归属日期不是同一天的话 + String fromDateTime = signEndDate + " " + signInTime4Out; + String toDateTime = signDate + " " + taskSignTime; +// 还需要交换一下开始日期和结束日期 + String tmpDate = signDate; + signDate = signEndDate; + signEndDate = tmpDate; + mins = Duration.between(LocalDateTime.parse(fromDateTime, fullFormatter), LocalDateTime.parse(toDateTime, fullFormatter)).toMinutes(); + } + if (mins > 0) { + int unit = KQOvertimeRulesBiz.getMinimumUnit(); + int paidLeaveEnable = KQOvertimeRulesBiz.getPaidLeaveEnable(resourceId, taskDate); + int minimumUnit = KQOvertimeRulesBiz.getMinimumLen(resourceId, taskDate); + paidLeaveEnable = paidLeaveEnable == 1 ? 1 : 0; + if (mins >= minimumUnit && Util.getDoubleValue(flowMins) >= minimumUnit) { + RecordSet rs = new RecordSet(); + String fromtime = ""; + String totime = ""; + double D_flowMins = Util.getDoubleValue(flowMins); + String tmp_taskSignTime = signEndDate + " " + taskSignTime; + Map mutiMap = checkMultiSign(resourceId, taskDate, tmp_taskSignTime, fullFormatter, timesource); + String hasSign = Util.null2String(mutiMap.get("hasSign")); + Map> sourceMap = (Map>) mutiMap.get("sourceMap"); + String before_checkLastSignTime = ""; + String before_checkLastSignDate = ""; + double before_hasMins = 0.0; + + String after_checkLastSignTime = ""; + String after_checkLastSignDate = ""; + double after_hasMins = 0.0; + if (sourceMap.containsKey("before")) { + Map tmpMap = sourceMap.get("before"); + before_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + before_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + before_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + if (sourceMap.containsKey("after")) { + Map tmpMap = sourceMap.get("after"); + after_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + after_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + after_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + long hasMins = Long.parseLong(Util.null2String(mutiMap.get("hasMins"))); + + if ("1".equalsIgnoreCase(hasSign)) { + String checkLastSignTime = ""; + if (isBefore) { + checkLastSignTime = before_checkLastSignTime; + } else { + checkLastSignTime = after_checkLastSignTime; + } + if (checkLastSignTime.compareTo(signInTime4Out) > 0) { + fromtime = checkLastSignTime; + } else { + fromtime = signInTime4Out; + } + totime = taskSignTime; + if (hasMins >= D_flowMins) { + //如果已经生成过的加班数据已经大于等于流程时长了,那么此次的加班时长就是0 + mins = 0; + } else { + if (isBefore) { + //如果是上班前 当前的打卡时长+下班后已经生成过的加班时长,和流程总时长的比较 + double before_after_mins = mins + after_hasMins; + if (before_after_mins > D_flowMins) { + mins = (long) (D_flowMins - after_hasMins - before_hasMins); + } else { + mins = (long) (mins - before_hasMins); + } + } else { + //如果是下班后 当前的打卡时长+上班前已经生成过的加班时长,和流程总时长的比较 + double before_after_mins = mins + before_hasMins; + if (before_after_mins > D_flowMins) { + mins = (long) (D_flowMins - before_hasMins - after_hasMins); + } else { + mins = (long) (mins - after_hasMins); + } + } + } + } else { + fromtime = signInTime4Out; + totime = taskSignTime; + if (D_flowMins > 0 && mins > D_flowMins) { + //之前没有生成过加班 打卡加班时长不能超过流程时长 + mins = (long) D_flowMins; + } + } + mins = mins < 0 ? 0 : mins; + if (mins <= 0) { + return; + } + + String tiaoxiuId = KQBalanceOfLeaveBiz.addExtraAmountByDis5(resourceId, taskDate, mins + "", "0", "", requestid, "", taskDate, null); + if (Util.getIntValue(tiaoxiuId) > 0) { + kqLog.info("生成加班数据成功 doMode2ChangeType3:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins); + } else { + kqLog.info("生成加班数据失败 doMode2ChangeType3:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins); + } + String uuid = UUID.randomUUID().toString(); + String flow_overtime_sql = "insert into kq_flow_overtime (requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,tiaoxiuId,uuid)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + boolean isUp = rs.executeUpdate(flow_overtime_sql, requestid, resourceId, signDate, fromtime, signEndDate, totime, mins, "", taskDate, "", unit, "3", paidLeaveEnable, "2", tiaoxiuId, uuid); + if (!isUp) { + kqLog.info("doMode2ChangeType3 加班数据记录失败!!!"); + } + + logMultiSign(resourceId, taskDate, taskSignTime, "", 0, signInTime4Out, mins, signEndDate, timesource, + uuid, tiaoxiuId); + } else { + kqLog.info("签到签退 生成加班数据为 doMode2ChangeType2:实际加班时长mins:" + mins + ":最小加班时长minimumUnit:" + minimumUnit + ":流程时长:Util.getDoubleValue(flowMins):" + Util.getDoubleValue(flowMins)); + } + + } else { + kqLog.info("签到签退 生成加班数据为 doMode2ChangeType3:taskSignTime:" + taskSignTime + ":signInTime4Out:" + signInTime4Out); + } + } else { + kqLog.info("签到签退 生成加班数据异常 doMode2ChangeType3:taskSignTime:" + taskSignTime + ":signInTime4Out:" + signInTime4Out); + } + + } + + /** + * 需审批,以打卡为准 + * 工作日 + * + * @param taskBean + * @param fullFormatter + * @param flowMins + */ + private void doMode2ChangeType2(KQTaskBean taskBean, DateTimeFormatter fullFormatter, + String flowMins) throws Exception { + String taskDate = taskBean.getTaskDate(); + String resourceId = taskBean.getResourceId(); + String taskSignTime = taskBean.getTaskSignTime(); + String lastWorkTime = taskBean.getLastWorkTime(); + String signDate = taskBean.getSignDate(); + String signEndDate = taskBean.getSignEndDate(); + String requestid = taskBean.getRequestId(); + String timesource = Util.null2String(taskBean.getTimesource()); + boolean isBefore = false; + if ("before".equalsIgnoreCase(timesource)) { + isBefore = true; + } + int workMins = taskBean.getWorkmins(); + if (taskSignTime.length() > 0 && lastWorkTime.length() > 0) { + if (lastWorkTime.length() == 5) { + lastWorkTime = lastWorkTime + ":00"; + } + String fromDateTime = signDate + " " + lastWorkTime; + String toDateTime = signEndDate + " " + taskSignTime; + int startTime = KQOvertimeRulesBiz.getStartTime(resourceId, taskDate); + startTime = startTime < 0 ? 0 : startTime; + if (isBefore) { + //上班前就不不需要考虑下班后多久算加班这个逻辑了 + startTime = 0; + } + long mins = Duration.between(LocalDateTime.parse(fromDateTime, fullFormatter).plusMinutes(startTime), LocalDateTime.parse(toDateTime, fullFormatter)).toMinutes(); + if (mins > 0) { + String workingHours = Util.null2String(workMins / 60.0); + int minimumUnit = KQOvertimeRulesBiz.getMinimumLen(resourceId, taskDate); + int unit = KQOvertimeRulesBiz.getMinimumUnit(); + int paidLeaveEnable = KQOvertimeRulesBiz.getPaidLeaveEnable(resourceId, taskDate); + paidLeaveEnable = paidLeaveEnable == 1 ? 1 : 0; + if (mins >= minimumUnit && Util.getDoubleValue(flowMins) >= minimumUnit) { + RecordSet rs = new RecordSet(); + boolean isLateoutlatein = checkIsLateoutlatein(resourceId, taskDate); + if (!isLateoutlatein) { + String fromDate = ""; + String fromtime = ""; + String toDate = ""; + String totime = ""; + double D_flowMins = Util.getDoubleValue(flowMins); + String tmp_taskSignTime = signEndDate + " " + taskSignTime; + Map mutiMap = checkMultiSign(resourceId, taskDate, tmp_taskSignTime, fullFormatter, timesource); + String hasSign = Util.null2String(mutiMap.get("hasSign")); + Map> sourceMap = (Map>) mutiMap.get("sourceMap"); + String before_checkLastSignTime = ""; + String before_checkLastSignDate = ""; + String before_checkLastSignTimesource = ""; + double before_hasMins = 0.0; + + String after_checkLastSignTime = ""; + String after_checkLastSignDate = ""; + String after_checkLastSignTimesource = ""; + double after_hasMins = 0.0; + if (sourceMap.containsKey("before")) { + Map tmpMap = sourceMap.get("before"); + before_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + before_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + before_checkLastSignTimesource = Util.null2String(tmpMap.get("checkLastSignTimesource")); + before_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + if (sourceMap.containsKey("after")) { + Map tmpMap = sourceMap.get("after"); + after_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + after_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + after_checkLastSignTimesource = Util.null2String(tmpMap.get("checkLastSignTimesource")); + after_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + + long hasMins = Long.parseLong(Util.null2String(mutiMap.get("hasMins"))); + if ("1".equalsIgnoreCase(hasSign)) { + String checkLastSignTime = ""; + String checkLastSignDate = ""; + String checkLastSignTimesource = ""; + if (isBefore) { + checkLastSignTime = before_checkLastSignTime; + checkLastSignDate = before_checkLastSignDate; + checkLastSignTimesource = before_checkLastSignTimesource; + } else { + checkLastSignTime = after_checkLastSignTime; + checkLastSignDate = after_checkLastSignDate; + checkLastSignTimesource = after_checkLastSignTimesource; + } + if (isBefore) { + fromDate = signDate; + fromtime = lastWorkTime; + if ("before".equalsIgnoreCase(checkLastSignTimesource)) { + toDate = checkLastSignDate; + totime = checkLastSignTime; + } else { + String[] toDateTimes = toDateTime.split(" "); + if (toDateTimes.length == 2) { + toDate = toDateTimes[0]; + totime = toDateTimes[1]; + } + } + } else { + if (checkLastSignDate.length() > 0 && checkLastSignTime.length() > 0) { + fromDate = checkLastSignDate; + fromtime = checkLastSignTime; + } else { + fromDate = signDate; + fromtime = lastWorkTime; + } + toDate = signEndDate; + totime = taskSignTime; + } + + if (hasMins >= D_flowMins) { + //如果已经生成过的加班数据已经大于等于流程时长了,那么此次的加班时长就是0 + mins = 0; + } else { + if (isBefore) { + //如果是上班前 当前的打卡时长+下班后已经生成过的加班时长,和流程总时长的比较 + double before_after_mins = mins + after_hasMins; + if (before_after_mins > D_flowMins) { + mins = (long) (D_flowMins - after_hasMins - before_hasMins); + } else { + mins = (long) (mins - before_hasMins); + } + } else { + //如果是下班后 当前的打卡时长+上班前已经生成过的加班时长,和流程总时长的比较 + double before_after_mins = mins + before_hasMins; + if (before_after_mins > D_flowMins) { + mins = (long) (D_flowMins - before_hasMins - after_hasMins); + } else { + mins = (long) (mins - after_hasMins); + } + } + } + } else { + String[] fromDateTimes = fromDateTime.split(" "); + String[] toDateTimes = toDateTime.split(" "); + if (fromDateTimes.length == 2) { + fromDate = fromDateTimes[0]; + fromtime = fromDateTimes[1]; + } + if (toDateTimes.length == 2) { + toDate = toDateTimes[0]; + totime = toDateTimes[1]; + } + if (D_flowMins > 0 && mins > D_flowMins) { + //之前没有生成过加班 打卡加班时长不能超过流程时长 + mins = (long) D_flowMins; + } + } + mins = mins < 0 ? 0 : mins; + if (mins <= 0) { + return; + } + + String tiaoxiuId = KQBalanceOfLeaveBiz.addExtraAmountByDis5(resourceId, taskDate, mins + "", "0", workingHours, requestid, "", taskDate, null); + if (Util.getIntValue(tiaoxiuId) > 0) { + kqLog.info("生成加班数据为成功 doMode2ChangeType2:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins + ":workingHours:" + workingHours); + } else { + kqLog.info("生成加班数据为失败 doMode2ChangeType2:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins + ":workingHours:" + workingHours); + } + String uuid = UUID.randomUUID().toString(); + String flow_overtime_sql = "insert into kq_flow_overtime (requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,tiaoxiuId,uuid)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + boolean isUp = rs.executeUpdate(flow_overtime_sql, requestid, resourceId, signDate, fromtime, signEndDate, totime, mins, "", taskDate, "", unit, "2", paidLeaveEnable, "2", tiaoxiuId, uuid); + if (!isUp) { + kqLog.info("doMode2ChangeType2 加班数据记录失败!!!"); + } + + logMultiSign(resourceId, taskDate, taskSignTime, lastWorkTime, 0, "", mins, signEndDate, timesource, + uuid, tiaoxiuId); + } + } else { + kqLog.info("签到签退 生成加班数据为 doMode2ChangeType2:实际加班时长mins:" + mins + ":最小加班时长minimumUnit:" + minimumUnit + ":流程时长:Util.getDoubleValue(flowMins):" + Util.getDoubleValue(flowMins)); + } + } else { + kqLog.info("签到签退 生成加班数据为 doMode2ChangeType2:fromDateTime:" + fromDateTime + ":toDateTime:" + toDateTime + ":mins:" + mins); + } + } else { + kqLog.info("签到签退 生成加班数据异常 doMode2ChangeType2:taskSignTime:" + taskSignTime + ":lastWorkTime:" + lastWorkTime); + } + + } + + /** + * 需审批,以打卡为准 + * 节假日 + * + * @param taskBean + * @param fullFormatter + * @param flowMins + */ + private void doMode2ChangeType1(KQTaskBean taskBean, DateTimeFormatter fullFormatter, + String flowMins) throws Exception { + String taskDate = taskBean.getTaskDate(); + String resourceId = taskBean.getResourceId(); + String taskSignTime = taskBean.getTaskSignTime(); + String signInTime4Out = taskBean.getSignInTime4Out(); + String requestid = taskBean.getRequestId(); + String signDate = taskBean.getSignDate(); + String signEndDate = taskBean.getSignEndDate(); + String timesource = Util.null2String(taskBean.getTimesource()); + boolean isBefore = false; + if ("before".equalsIgnoreCase(timesource)) { + isBefore = true; + } + if (taskSignTime.length() > 0 && signInTime4Out.length() > 0) { + + long mins = calNonWorkDuration(signInTime4Out, taskSignTime, taskDate, resourceId); + if (isBefore && signEndDate.compareTo(signDate) < 0) { + //打卡日期和归属日期不是同一天的话 + String fromDateTime = signEndDate + " " + signInTime4Out; + String toDateTime = signDate + " " + taskSignTime; +// 还需要交换一下开始日期和结束日期 + String tmpDate = signDate; + signDate = signEndDate; + signEndDate = tmpDate; + mins = Duration.between(LocalDateTime.parse(fromDateTime, fullFormatter), LocalDateTime.parse(toDateTime, fullFormatter)).toMinutes(); + } + if (mins > 0) { + int minimumUnit = KQOvertimeRulesBiz.getMinimumLen(resourceId, taskDate); + int unit = KQOvertimeRulesBiz.getMinimumUnit(); + int paidLeaveEnable = KQOvertimeRulesBiz.getPaidLeaveEnable(resourceId, taskDate); + paidLeaveEnable = paidLeaveEnable == 1 ? 1 : 0; + if (mins >= minimumUnit && Util.getDoubleValue(flowMins) >= minimumUnit) { + RecordSet rs = new RecordSet(); + String fromtime = ""; + String totime = ""; + double D_flowMins = Util.getDoubleValue(flowMins); + String tmp_taskSignTime = signEndDate + " " + taskSignTime; + Map mutiMap = checkMultiSign(resourceId, taskDate, tmp_taskSignTime, fullFormatter, timesource); + String hasSign = Util.null2String(mutiMap.get("hasSign")); + Map> sourceMap = (Map>) mutiMap.get("sourceMap"); + String before_checkLastSignTime = ""; + String before_checkLastSignDate = ""; + double before_hasMins = 0.0; + + String after_checkLastSignTime = ""; + String after_checkLastSignDate = ""; + double after_hasMins = 0.0; + if (sourceMap.containsKey("before")) { + Map tmpMap = sourceMap.get("before"); + before_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + before_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + before_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + if (sourceMap.containsKey("after")) { + Map tmpMap = sourceMap.get("after"); + after_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + after_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + after_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + long hasMins = Long.parseLong(Util.null2String(mutiMap.get("hasMins"))); + if ("1".equalsIgnoreCase(hasSign)) { + String checkLastSignTime = ""; + if (isBefore) { + checkLastSignTime = before_checkLastSignTime; + } else { + checkLastSignTime = after_checkLastSignTime; + } + if (checkLastSignTime.compareTo(signInTime4Out) > 0) { + fromtime = checkLastSignTime; + } else { + fromtime = signInTime4Out; + } + totime = taskSignTime; + if (hasMins >= D_flowMins) { + //如果已经生成过的加班数据已经大于等于流程时长了,那么此次的加班时长就是0 + mins = 0; + } else { + if (mins > D_flowMins) { + //如果打卡时长大于流程时长 + mins = (long) (D_flowMins - hasMins); + } else { + if (isBefore) { + //如果是上班前 当前的打卡时长+下班后已经生成过的加班时长,和流程总时长的比较 + double before_after_mins = mins + after_hasMins; + if (before_after_mins > D_flowMins) { + mins = (long) (D_flowMins - after_hasMins - before_hasMins); + } else { + mins = (long) (mins - before_hasMins); + } + } else { + //如果是下班后 当前的打卡时长+上班前已经生成过的加班时长,和流程总时长的比较 + double before_after_mins = mins + before_hasMins; + if (before_after_mins > D_flowMins) { + mins = (long) (D_flowMins - before_hasMins - after_hasMins); + } else { + mins = (long) (mins - after_hasMins); + } + } + } + } + } else { + fromtime = signInTime4Out; + totime = taskSignTime; + if (D_flowMins > 0 && mins > D_flowMins) { + //之前没有生成过加班 打卡加班时长不能超过流程时长 + mins = (long) D_flowMins; + } + } + mins = mins < 0 ? 0 : mins; + if (mins <= 0) { + return; + } + + String tiaoxiuId = KQBalanceOfLeaveBiz.addExtraAmountByDis5(resourceId, taskDate, mins + "", "0", "", requestid, "", taskDate, null); + if (Util.getIntValue(tiaoxiuId) > 0) { + kqLog.info("生成加班数据成功 doMode2ChangeType1:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins); + } else { + kqLog.info("生成加班数据失败 doMode2ChangeType1:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins); + } + + String uuid = UUID.randomUUID().toString(); + String flow_overtime_sql = "insert into kq_flow_overtime (requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,tiaoxiuId,uuid)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + boolean isUp = rs.executeUpdate(flow_overtime_sql, requestid, resourceId, signDate, fromtime, signEndDate, totime, mins, "", taskDate, "", unit, "1", paidLeaveEnable, "2", tiaoxiuId, uuid); + if (!isUp) { + kqLog.info("doMode2ChangeType1 加班数据记录失败!!!"); + } + logMultiSign(resourceId, taskDate, taskSignTime, "", 0, signInTime4Out, mins, signEndDate, timesource, + uuid, tiaoxiuId); + } else { + kqLog.info("签到签退 生成加班数据为 doMode2ChangeType1:实际加班时长mins:" + mins + ":最小加班时长minimumUnit:" + minimumUnit + ":流程时长:Util.getDoubleValue(flowMins):" + Util.getDoubleValue(flowMins)); + } + + } else { + kqLog.info("签到签退 生成加班数据为 doMode2ChangeType1:taskSignTime:" + taskSignTime + ":signInTime4Out:" + signInTime4Out); + } + } else { + kqLog.info("签到签退 生成加班数据异常 doMode2ChangeType1:taskSignTime:" + taskSignTime + ":signInTime4Out:" + signInTime4Out); + } + + } + + /** + * 打卡计算非工作时长 + * + * @param fromTime + * @param toTime + * @param date + * @param resourceid + * @return + */ + private int calNonWorkDuration(String fromTime, String toTime, String date, String resourceid) { + fromTime = (fromTime.length() > 6 ? fromTime.substring(0, 5) : fromTime); + toTime = (toTime.length() > 6 ? toTime.substring(0, 5) : toTime); + + List restTimeList = KQOvertimeRulesBiz.getRestTimeList(resourceid, date); + KQTimesArrayComInfo arrayComInfo = new KQTimesArrayComInfo(); + int[] initArrays = arrayComInfo.getInitArr(); + int startIndex = 0; + int endIndex = 0; + startIndex = arrayComInfo.getArrayindexByTimes(fromTime); + endIndex = arrayComInfo.getArrayindexByTimes(toTime); + if (startIndex > endIndex) { + return 0; + } + + //先把要计算的时长填充上0 + Arrays.fill(initArrays, startIndex, endIndex, 0); + + //再把休息时间填充上去 + if (!restTimeList.isEmpty()) { + for (int i = 0; i < restTimeList.size(); i++) { + String[] restTimes = restTimeList.get(i); + if (restTimes.length == 2) { + int restStart = arrayComInfo.getArrayindexByTimes(restTimes[0]); + int restEnd = arrayComInfo.getArrayindexByTimes(restTimes[1]); + Arrays.fill(initArrays, restStart, restEnd, 1); + } + } + } + //最后排除掉休息时间还剩多少加班时长就是最终的结果 + int curMins = arrayComInfo.getCnt(initArrays, startIndex, endIndex + 1, 0); + + return curMins; + } + + /** + * 无需审批,根据打卡时间计算加班时长 + * + * @param taskBean + * @param fullFormatter + */ + private void doComputingMode3(KQTaskBean taskBean, + DateTimeFormatter fullFormatter) throws Exception { + String resourceId = taskBean.getResourceId(); + String taskDate = taskBean.getTaskDate(); + int changeType = KQOvertimeRulesBiz.getChangeType(resourceId, taskDate); +// 1-节假日、2-工作日、3-休息日 + if (changeType == 1) { + doMode3ChangeType1(taskBean, fullFormatter); + } + if (changeType == 2) { + doMode3ChangeType2(taskBean, fullFormatter); + } + if (changeType == 3) { + doMode3ChangeType3(taskBean, fullFormatter); + } + } + + /** + * 无需审批,根据打开时间计算加班时长 + * 休息日处理 + * + * @param taskBean + * @param fullFormatter + */ + private void doMode3ChangeType3(KQTaskBean taskBean, + DateTimeFormatter fullFormatter) throws Exception { + String taskDate = taskBean.getTaskDate(); + String resourceId = taskBean.getResourceId(); + String taskSignTime = taskBean.getTaskSignTime(); + String signInTime4Out = taskBean.getSignInTime4Out(); + String signDate = taskBean.getSignDate(); + String signEndDate = taskBean.getSignEndDate(); + String timesource = Util.null2String(taskBean.getTimesource()); + String up_tiaoxiuid = taskBean.getTiaoxiuId(); + boolean isBefore = false; + if ("before".equalsIgnoreCase(timesource)) { + isBefore = true; + } + if (taskSignTime.length() > 0 && signInTime4Out.length() > 0) { + + long mins = calNonWorkDuration(signInTime4Out, taskSignTime, taskDate, resourceId); + if (isBefore && signEndDate.compareTo(signDate) < 0) { + //打卡日期和归属日期不是同一天的话 + String fromDateTime = signEndDate + " " + signInTime4Out; + String toDateTime = signDate + " " + taskSignTime; +// 还需要交换一下开始日期和结束日期 + String tmpDate = signDate; + signDate = signEndDate; + signEndDate = tmpDate; + mins = Duration.between(LocalDateTime.parse(fromDateTime, fullFormatter), LocalDateTime.parse(toDateTime, fullFormatter)).toMinutes(); + } + if (mins > 0) { + RecordSet rs = new RecordSet(); + int minimumUnit = KQOvertimeRulesBiz.getMinimumLen(resourceId, taskDate); + int unit = KQOvertimeRulesBiz.getMinimumUnit(); + int paidLeaveEnable = KQOvertimeRulesBiz.getPaidLeaveEnable(resourceId, taskDate); + paidLeaveEnable = paidLeaveEnable == 1 ? 1 : 0; + if (mins >= minimumUnit) { + if (taskSignTime.length() == 5) { + taskSignTime += ":00"; + } + String tmp_taskSignTime = signEndDate + " " + taskSignTime; + Map mutiMap = checkMultiSign(resourceId, taskDate, tmp_taskSignTime, fullFormatter, timesource); + String hasSign = Util.null2String(mutiMap.get("hasSign")); + Map> sourceMap = (Map>) mutiMap.get("sourceMap"); + String before_checkLastSignTime = ""; + String before_checkLastSignDate = ""; + double before_hasMins = 0.0; + + String after_checkLastSignTime = ""; + String after_checkLastSignDate = ""; + double after_hasMins = 0.0; + if (sourceMap.containsKey("before")) { + Map tmpMap = sourceMap.get("before"); + before_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + before_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + before_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + if (sourceMap.containsKey("after")) { + Map tmpMap = sourceMap.get("after"); + after_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + after_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + after_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + long hasMins = Long.parseLong(Util.null2String(mutiMap.get("hasMins"))); + + String fromtime = ""; + String totime = ""; + if ("1".equalsIgnoreCase(hasSign)) { + String checkLastSignTime = ""; + if (isBefore) { + checkLastSignTime = before_checkLastSignTime; + } else { + checkLastSignTime = after_checkLastSignTime; + } + if (checkLastSignTime.compareTo(signInTime4Out) > 0) { + fromtime = checkLastSignTime; + } else { + fromtime = signInTime4Out; + } + totime = taskSignTime; + if (isBefore) { + mins = (long) (mins - before_hasMins); + } else { + mins = (long) (mins - after_hasMins); + } + } else { + fromtime = signInTime4Out; + totime = taskSignTime; + } + mins = mins < 0 ? 0 : mins; + + String tiaoxiuId = ""; + if (up_tiaoxiuid.length() > 0 && Util.getIntValue(up_tiaoxiuid) > 0) { + boolean is_tiaoxiuId = KQBalanceOfLeaveBiz.updateExtraAmountByDis5(up_tiaoxiuid, Util.getDoubleValue(mins + ""), ""); + tiaoxiuId = up_tiaoxiuid; + } else { + tiaoxiuId = KQBalanceOfLeaveBiz.addExtraAmountByDis5(resourceId, taskDate, mins + "", "0", "", "", "", taskDate, null); + } + if (Util.getIntValue(tiaoxiuId) > 0) { + kqLog.info("生成加班数据成功 doMode3ChangeType3:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins); + } else { + kqLog.info("生成加班数据失败 doMode3ChangeType3:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins); + } + + String uuid = UUID.randomUUID().toString(); + String flow_overtime_sql = "insert into kq_flow_overtime (requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,tiaoxiuId,uuid)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + boolean isUp = rs.executeUpdate(flow_overtime_sql, "", resourceId, signDate, fromtime, signEndDate, totime, mins, "", taskDate, "", unit, "3", paidLeaveEnable, "3", tiaoxiuId, uuid); + if (!isUp) { + kqLog.info("doMode2ChangeType1 加班数据记录失败!!!"); + } + logMultiSign(resourceId, taskDate, taskSignTime, "", 0, signInTime4Out, mins, signEndDate, timesource, + uuid, tiaoxiuId); + + } else { + kqLog.info("签到签退 生成加班数据为 doMode3ChangeType3:实际加班时长mins:" + mins + ":最小加班时长minimumUnit:" + minimumUnit); + } + + } else { + kqLog.info("签到签退 生成加班数据为 doMode3ChangeType3:taskSignTime:" + taskSignTime + ":signInTime4Out:" + signInTime4Out); + } + } else { + kqLog.info("签到签退 生成加班数据异常 doMode3ChangeType3:taskSignTime:" + taskSignTime + ":signInTime4Out:" + signInTime4Out); + } + + } + + + /** + * 无需审批,根据打开时间计算加班时长 + * 工作日处理 + * + * @param taskBean + * @param fullFormatter + */ + private void doMode3ChangeType2(KQTaskBean taskBean, + DateTimeFormatter fullFormatter) throws Exception { + String taskDate = taskBean.getTaskDate(); + String resourceId = taskBean.getResourceId(); + String taskSignTime = taskBean.getTaskSignTime(); + String lastWorkTime = taskBean.getLastWorkTime(); + String signDate = taskBean.getSignDate(); + String signEndDate = taskBean.getSignEndDate(); + String timesource = taskBean.getTimesource(); + String up_tiaoxiuid = taskBean.getTiaoxiuId(); + boolean isBefore = false; + if ("before".equalsIgnoreCase(timesource)) { + isBefore = true; + } + int workMins = taskBean.getWorkmins(); + if (taskSignTime.length() > 0 && lastWorkTime.length() > 0) { + if (lastWorkTime.length() == 5) { + lastWorkTime = lastWorkTime + ":00"; + } + String fromDateTime = signDate + " " + lastWorkTime; + String toDateTime = signEndDate + " " + taskSignTime; + int startTime = KQOvertimeRulesBiz.getStartTime(resourceId, taskDate); + startTime = startTime < 0 ? 0 : startTime; + if (isBefore) { + //上班前就不不需要考虑下班后多久算加班这个逻辑了 + startTime = 0; + } + long mins = Duration.between(LocalDateTime.parse(fromDateTime, fullFormatter).plusMinutes(startTime), LocalDateTime.parse(toDateTime, fullFormatter)).toMinutes(); + if (mins > 0) { + String workingHours = Util.null2String(workMins / 60.0); + int minimumUnit = KQOvertimeRulesBiz.getMinimumLen(resourceId, taskDate); + int unit = KQOvertimeRulesBiz.getMinimumUnit(); + int paidLeaveEnable = KQOvertimeRulesBiz.getPaidLeaveEnable(resourceId, taskDate); + paidLeaveEnable = paidLeaveEnable == 1 ? 1 : 0; + if (mins >= minimumUnit) { + if (taskSignTime.length() == 5) { + taskSignTime += ":00"; + } + RecordSet rs = new RecordSet(); + String tmp_taskSignTime = signEndDate + " " + taskSignTime; + Map mutiMap = checkMultiSign(resourceId, taskDate, tmp_taskSignTime, fullFormatter, timesource); + String hasSign = Util.null2String(mutiMap.get("hasSign")); + Map> sourceMap = (Map>) mutiMap.get("sourceMap"); + String before_checkLastSignTime = ""; + String before_checkLastSignDate = ""; + String before_checkLastSignTimesource = ""; + double before_hasMins = 0.0; + + String after_checkLastSignTime = ""; + String after_checkLastSignDate = ""; + String after_checkLastSignTimesource = ""; + double after_hasMins = 0.0; + if (sourceMap.containsKey("before")) { + Map tmpMap = sourceMap.get("before"); + before_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + before_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + before_checkLastSignTimesource = Util.null2String(tmpMap.get("checkLastSignTimesource")); + before_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + if (sourceMap.containsKey("after")) { + Map tmpMap = sourceMap.get("after"); + after_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + after_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + after_checkLastSignTimesource = Util.null2String(tmpMap.get("checkLastSignTimesource")); + after_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + long hasMins = Long.parseLong(Util.null2String(mutiMap.get("hasMins"))); + boolean isLateoutlatein = checkIsLateoutlatein(resourceId, taskDate); + if (!isLateoutlatein) { + String fromDate = ""; + String fromtime = ""; + String toDate = ""; + String totime = ""; + if ("1".equalsIgnoreCase(hasSign)) { + String checkLastSignTime = ""; + String checkLastSignDate = ""; + String checkLastSignTimesource = ""; + if (isBefore) { + checkLastSignTime = before_checkLastSignTime; + checkLastSignDate = before_checkLastSignDate; + checkLastSignTimesource = before_checkLastSignTimesource; + } else { + checkLastSignTime = after_checkLastSignTime; + checkLastSignDate = after_checkLastSignDate; + checkLastSignTimesource = after_checkLastSignTimesource; + } + if (isBefore) { + fromDate = signDate; + fromtime = lastWorkTime; + if ("before".equalsIgnoreCase(checkLastSignTimesource)) { + toDate = checkLastSignDate; + totime = checkLastSignTime; + } else { + String[] toDateTimes = toDateTime.split(" "); + if (toDateTimes.length == 2) { + toDate = toDateTimes[0]; + totime = toDateTimes[1]; + } + } + mins = (long) (mins - before_hasMins); + } else { + if (checkLastSignDate.length() > 0 && checkLastSignTime.length() > 0) { + fromDate = checkLastSignDate; + fromtime = checkLastSignTime; + } else { + fromDate = signDate; + fromtime = lastWorkTime; + } + toDate = signEndDate; + totime = taskSignTime; + mins = (long) (mins - after_hasMins); + } + } else { + String[] fromDateTimes = fromDateTime.split(" "); + String[] toDateTimes = toDateTime.split(" "); + if (fromDateTimes.length == 2) { + fromDate = fromDateTimes[0]; + fromtime = fromDateTimes[1]; + } + if (toDateTimes.length == 2) { + toDate = toDateTimes[0]; + totime = toDateTimes[1]; + } + } + mins = mins < 0 ? 0 : mins; + + String tiaoxiuId = ""; + if (up_tiaoxiuid.length() > 0 && Util.getIntValue(up_tiaoxiuid) > 0) { + boolean is_tiaoxiuId = KQBalanceOfLeaveBiz.updateExtraAmountByDis5(up_tiaoxiuid, Util.getDoubleValue(mins + ""), ""); + tiaoxiuId = up_tiaoxiuid; + } else { + tiaoxiuId = KQBalanceOfLeaveBiz.addExtraAmountByDis5(resourceId, taskDate, mins + "", "0", "", "", "", taskDate, null); + } + if (Util.getIntValue(tiaoxiuId) > 0) { + kqLog.info("生成加班数据成功 doMode3ChangeType2:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins + ":workingHours:" + workingHours); + } else { + kqLog.info("生成加班数据失败 doMode3ChangeType2:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins + ":workingHours:" + workingHours); + } + + String uuid = UUID.randomUUID().toString(); + String flow_overtime_sql = "insert into kq_flow_overtime (requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,tiaoxiuId,uuid)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + boolean isUp = rs.executeUpdate(flow_overtime_sql, "", resourceId, fromDate, fromtime, toDate, totime, mins, "", taskDate, "", unit, "2", paidLeaveEnable, "3", tiaoxiuId, uuid); + if (!isUp) { + kqLog.info("doMode2ChangeType1 加班数据记录失败!!!"); + } + logMultiSign(resourceId, taskDate, taskSignTime, lastWorkTime, workMins, "", mins, signEndDate, timesource, + uuid, tiaoxiuId); + } + } else { + kqLog.info("签到签退 生成加班数据为 doMode3ChangeType2:实际加班时长mins:" + mins + ":最小加班时长minimumUnit:" + minimumUnit); + } + } else { + kqLog.info("签到签退 生成加班数据为 doMode3ChangeType2:fromDateTime:" + fromDateTime + ":toDateTime:" + toDateTime + ":mins:" + mins); + } + } else { + kqLog.info("签到签退 生成加班数据异常 doMode3ChangeType2:taskSignTime:" + taskSignTime + ":lastWorkTime:" + lastWorkTime); + } + + } + + /** + * 校验多次签退问题 + * + * @param taskSignTime 最新的签退日期时间 + * @param fullFormatter + */ + public Map checkMultiSign(String resourceId, String taskDate, String taskSignTime, DateTimeFormatter fullFormatter, String timesource) { + RecordSet rs = new RecordSet(); + Map mutiMap = new HashMap<>(); + long mins = 0L; + boolean hasSigned = false; + //倒数第二新的签退时间 + String signDate = ""; + String checkLastSignTime = ""; + String checkLastSignTimesource = ""; + Map> sourceMap = new HashMap<>(); + Map minsMap = new HashMap<>(); + Map datetimeMap = new HashMap<>(); + //已经生成了的加班时长 + long hasMins = 0L; + String checkSql = "select * from kq_overtime_signtask where resourceid=? and belongdate=? order by signdate ,signtime "; + rs.executeQuery(checkSql, resourceId, taskDate); + while (rs.next()) { + signDate = rs.getString("signdate"); + checkLastSignTime = rs.getString("signtime"); + checkLastSignTimesource = rs.getString("timesource"); + double tmp_mins = Util.getDoubleValue(rs.getString("mins"), 0.0); + hasMins += tmp_mins; + if (sourceMap.containsKey(checkLastSignTimesource)) { + Map tmp_minsMap = sourceMap.get(checkLastSignTimesource); + String tmp_hasMins = tmp_minsMap.get("hasMins"); + if (checkLastSignTimesource.equalsIgnoreCase("after")) { + tmp_minsMap.put("checkLastSignDate", signDate); + tmp_minsMap.put("checkLastSignTime", checkLastSignTime); + tmp_minsMap.put("checkLastSignTimesource", checkLastSignTimesource); + } else { + //before 上班前的时候,第一条就是最早的打卡时间所以后面不需要更新了 + } + double sourceMins = Util.getDoubleValue(tmp_hasMins, 0.0); + tmp_minsMap.put("hasMins", (tmp_mins + sourceMins) + ""); + } else { + minsMap = new HashMap<>(); + minsMap.put("hasMins", tmp_mins + ""); + minsMap.put("checkLastSignDate", signDate + ""); + minsMap.put("checkLastSignTime", checkLastSignTime + ""); + minsMap.put("checkLastSignTimesource", checkLastSignTimesource + ""); + sourceMap.put(checkLastSignTimesource, minsMap); + } + hasSigned = true; + } + mutiMap.put("hasSign", hasSigned ? "1" : "0"); + mutiMap.put("hasMins", "" + (hasMins <= 0 ? 0 : hasMins)); + mutiMap.put("sourceMap", sourceMap); + return mutiMap; + } + + /** + * 记录下多次签退生成加班数据问题 + * + * @param resourceId + * @param taskDate + * @param taskSignTime + * @param lastWorkTime + * @param workMins + * @param signInTime4Out + * @param mins + * @param signDate + * @param timesource + * @param uuid + * @param tiaoxiuId + */ + private void logMultiSign(String resourceId, String taskDate, String taskSignTime, + String lastWorkTime, int workMins, String signInTime4Out, long mins, String signDate, + String timesource, String uuid, String tiaoxiuId) throws Exception { + RecordSet rs = new RecordSet(); + String logSql = "insert into kq_overtime_signtask(resourceid,belongdate,signtime,lastworktime,workmins,signInTime4Out,mins,signDate,timesource,uuid,tiaoxiuId) values(?,?,?,?,?,?,?,?,?,?,?) "; + boolean isLog = false; + if ("before".equalsIgnoreCase(timesource)) { + isLog = rs.executeUpdate(logSql, resourceId, taskDate, lastWorkTime, taskSignTime, workMins, signInTime4Out, mins, signDate, timesource, uuid, tiaoxiuId); + } else { + isLog = rs.executeUpdate(logSql, resourceId, taskDate, taskSignTime, lastWorkTime, workMins, signInTime4Out, mins, signDate, timesource, uuid, tiaoxiuId); + } + + kqLog.info("记录下多次签退生成加班数据问题 logMultiSign:logSql:" + logSql + ":resourceId:" + resourceId + ":isLog:" + isLog + + ":taskDate:" + taskDate + ":taskSignTime:" + taskSignTime + ":lastWorkTime:" + lastWorkTime + ":workMins:" + workMins + ":signInTime4Out:" + + signInTime4Out + ":mins:" + mins + ":signDate:" + signDate + ":timesource:" + timesource); + + } + + /** + * 无需审批,根据打开时间计算加班时长 + * 节假日处理 + * + * @param taskBean + * @param fullFormatter + */ + private void doMode3ChangeType1(KQTaskBean taskBean, + DateTimeFormatter fullFormatter) throws Exception { + String taskDate = taskBean.getTaskDate(); + String resourceId = taskBean.getResourceId(); + String taskSignTime = taskBean.getTaskSignTime(); + String signInTime4Out = taskBean.getSignInTime4Out(); + String signDate = taskBean.getSignDate(); + String signEndDate = taskBean.getSignEndDate(); + String timesource = Util.null2String(taskBean.getTimesource()); + String up_tiaoxiuid = taskBean.getTiaoxiuId(); + boolean isBefore = false; + if ("before".equalsIgnoreCase(timesource)) { + isBefore = true; + } + if (taskSignTime.length() > 0 && signInTime4Out.length() > 0) { + + long mins = calNonWorkDuration(signInTime4Out, taskSignTime, taskDate, resourceId); + if (isBefore && signEndDate.compareTo(signDate) < 0) { + //打卡日期和归属日期不是同一天的话 + String fromDateTime = signEndDate + " " + signInTime4Out; + String toDateTime = signDate + " " + taskSignTime; +// 还需要交换一下开始日期和结束日期 + String tmpDate = signDate; + signDate = signEndDate; + signEndDate = tmpDate; + mins = Duration.between(LocalDateTime.parse(fromDateTime, fullFormatter), LocalDateTime.parse(toDateTime, fullFormatter)).toMinutes(); + } + if (mins > 0) { + int minimumUnit = KQOvertimeRulesBiz.getMinimumLen(resourceId, taskDate); + int unit = KQOvertimeRulesBiz.getMinimumUnit(); + int paidLeaveEnable = KQOvertimeRulesBiz.getPaidLeaveEnable(resourceId, taskDate); + paidLeaveEnable = paidLeaveEnable == 1 ? 1 : 0; + if (mins >= minimumUnit) { + if (taskSignTime.length() == 5) { + taskSignTime += ":00"; + } + RecordSet rs = new RecordSet(); + String tmp_taskSignTime = signEndDate + " " + taskSignTime; + Map mutiMap = checkMultiSign(resourceId, taskDate, tmp_taskSignTime, fullFormatter, timesource); + String hasSign = Util.null2String(mutiMap.get("hasSign")); + Map> sourceMap = (Map>) mutiMap.get("sourceMap"); + String before_checkLastSignTime = ""; + String before_checkLastSignDate = ""; + double before_hasMins = 0.0; + + String after_checkLastSignTime = ""; + String after_checkLastSignDate = ""; + double after_hasMins = 0.0; + if (sourceMap.containsKey("before")) { + Map tmpMap = sourceMap.get("before"); + before_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + before_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + before_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + if (sourceMap.containsKey("after")) { + Map tmpMap = sourceMap.get("after"); + after_checkLastSignDate = Util.null2String(tmpMap.get("checkLastSignDate")); + after_checkLastSignTime = Util.null2String(tmpMap.get("checkLastSignTime")); + after_hasMins = Util.getDoubleValue(Util.null2String(tmpMap.get("hasMins")), 0.0); + } + long hasMins = Long.parseLong(Util.null2String(mutiMap.get("hasMins"))); + + String fromtime = ""; + String totime = ""; + if ("1".equalsIgnoreCase(hasSign)) { + String checkLastSignTime = ""; + if (isBefore) { + checkLastSignTime = before_checkLastSignTime; + } else { + checkLastSignTime = after_checkLastSignTime; + } + if (checkLastSignTime.compareTo(signInTime4Out) > 0) { + fromtime = checkLastSignTime; + } else { + fromtime = signInTime4Out; + } + totime = taskSignTime; + if (isBefore) { + mins = (long) (mins - before_hasMins); + } else { + mins = (long) (mins - after_hasMins); + } + } else { + fromtime = signInTime4Out; + totime = taskSignTime; + } + mins = mins < 0 ? 0 : mins; + + String tiaoxiuId = ""; + if (up_tiaoxiuid.length() > 0 && Util.getIntValue(up_tiaoxiuid) > 0) { + boolean is_tiaoxiuId = KQBalanceOfLeaveBiz.updateExtraAmountByDis5(up_tiaoxiuid, Util.getDoubleValue(mins + ""), ""); + tiaoxiuId = up_tiaoxiuid; + } else { + tiaoxiuId = KQBalanceOfLeaveBiz.addExtraAmountByDis5(resourceId, taskDate, mins + "", "0", "", "", "", taskDate, null); + } + + if (Util.getIntValue(tiaoxiuId) > 0) { + kqLog.info("生成加班数据成功 doMode3ChangeType1:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins); + } else { + kqLog.info("生成加班数据失败 doMode3ChangeType1:resourceId:" + resourceId + ":taskDate:" + taskDate + ":mins:" + mins); + } + String uuid = UUID.randomUUID().toString(); + String flow_overtime_sql = "insert into kq_flow_overtime (requestid,resourceid,fromdate,fromtime,todate,totime,duration_min,expiringdate,belongdate,workMins,durationrule,changetype,paidLeaveEnable,computingMode,tiaoxiuId,uuid)" + + " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; + boolean isUp = rs.executeUpdate(flow_overtime_sql, "", resourceId, signDate, fromtime, signEndDate, totime, mins, "", taskDate, "", unit, "1", paidLeaveEnable, "3", tiaoxiuId, uuid); + if (!isUp) { + kqLog.info("doMode2ChangeType1 加班数据记录失败!!!"); + } + + logMultiSign(resourceId, taskDate, taskSignTime, "", 0, signInTime4Out, mins, signEndDate, timesource, uuid, tiaoxiuId); + } else { + kqLog.info("签到签退 生成加班数据为 doMode3ChangeType1:实际加班时长mins:" + mins + ":最小加班时长minimumUnit:" + minimumUnit); + } + + } else { + kqLog.info("签到签退 生成加班数据为 doMode3ChangeType1:taskSignTime:" + taskSignTime + ":signInTime4Out:" + signInTime4Out); + } + } else { + kqLog.info("签到签退 生成加班数据异常 doMode3ChangeType1:taskSignTime:" + taskSignTime + ":signInTime4Out:" + signInTime4Out); + } + + } + + /** + * 根据每一天的班次来拆分 + * + * @param splitBean + * @param splitBeans + * @return + */ + public void doSerialSplitList(SplitBean splitBean, List splitBeans) throws Exception { + String resourceid = splitBean.getResourceId(); + String fromDate = splitBean.getFromdatedb(); + String toDate = splitBean.getTodatedb(); + + LocalDate localFromDate = LocalDate.parse(fromDate); + LocalDate localToDate = LocalDate.parse(toDate); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate preFromDate = localFromDate.minusDays(1); + + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + DurationTypeEnum durationTypeEnum = splitBean.getDurationTypeEnum(); + + boolean shouldLog = true; + if (durationTypeEnum == DurationTypeEnum.COMMON_CAL) { + shouldLog = false; + } + if (shouldLog) { + kqLog.info("resourceid::" + resourceid + "::doSerialSplitList:" + (splitBean != null ? JSON.toJSONString(splitBean) : null)); + } + boolean is_flow_humanized = KQSettingsBiz.is_flow_humanized(); + long betweenDays = localToDate.toEpochDay() - preFromDate.toEpochDay(); + for (int i = 0; i <= betweenDays; i++) { + LocalDate curLocalDate = preFromDate.plusDays(i); + String splitDate = curLocalDate.format(dateFormatter); + ShiftInfoBean shiftInfoBean = null; + if (shouldLog) { + shiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, splitDate, false); + } else { + shiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, splitDate, false, false); + } + if (shouldLog) { + kqLog.info("resourceid::" + resourceid + "::splitDate:" + splitDate + ":shiftInfoBean:" + (shiftInfoBean != null ? JSON.toJSONString(shiftInfoBean) : null)); + } + int restShift = 0; + if (shiftInfoBean != null) { + restShift = shiftInfoBean.getRestShift(); + } + + int[] initArrays = kqTimesArrayComInfo.getInitArr(); + boolean isSplit = true; + if (shiftInfoBean != null && 1 != restShift) { + splitBean.setSerialid(Util.null2String(shiftInfoBean.getSerialid())); + if (!shiftInfoBean.isIsfree()) { + isSplit = commonShiftSplit(shiftInfoBean, splitBean, i, kqTimesArrayComInfo, initArrays, localFromDate, localToDate, betweenDays, shouldLog, is_flow_humanized); + if (!isSplit) { + continue; + } + } else { + isSplit = freeShiftSplit(shiftInfoBean, splitBean, i, kqTimesArrayComInfo, initArrays, localFromDate, localToDate, betweenDays); + if (!isSplit) { + continue; + } + } + //根据单位转换时长 + turnDuration(splitBean, false); + } else { + //非工作时长 + String computingMode = splitBean.getComputingMode(); + if ("2".equalsIgnoreCase(computingMode)) { + String filterholidays = splitBean.getFilterholidays(); + boolean is_filterholidays = check_filterholidays(filterholidays, resourceid, splitDate, i); + if (is_filterholidays) { + continue; + } + ShiftInfoBean preShiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, curLocalDate.minusDays(1).format(dateFormatter), false); + isSplit = nonWorkDaySplit(preShiftInfoBean, splitBean, i, kqTimesArrayComInfo, initArrays, localFromDate, localToDate, betweenDays); + if (!isSplit) { + continue; + } + //根据单位转换时长 + turnDuration(splitBean, true); + } else { + if (shouldLog) { + kqLog.info("resourceid::" + resourceid + "::doSerialSplitList splitDate:" + splitDate + ":resourceid:" + resourceid + "是非工作日"); + } + continue; + } + } + + SplitBean newsplitBean = new SplitBean(); + //然后把bean重新赋值下,根据拆分后的时间 + //BeanUtils.copyProperties(splitBean, newsplitBean); + BeanUtil.copyProperties(splitBean,newsplitBean); +// SplitBean newsplitBean = copySplitBean(splitBean); + newsplitBean.setFromDate(splitDate); + newsplitBean.setToDate(splitDate); + newsplitBean.setBelongDate(splitDate); + splitBeans.add(newsplitBean); + } + } + + public SplitBean copySplitBean(SplitBean splitBean) { + SplitBean newsplitBean = new SplitBean(); + if (null == splitBean) { + return newsplitBean; + } + newsplitBean.setRequestId(splitBean.getRequestId()); + newsplitBean.setLeavebackrequestid(splitBean.getLeavebackrequestid()); + newsplitBean.setWorkflowId(splitBean.getWorkflowId()); + newsplitBean.setUsedetail(splitBean.getUsedetail()); + newsplitBean.setDataId(splitBean.getDataId()); +// this.detailId = ""; + newsplitBean.setDetailId(splitBean.getDetailId()); +// this.resourceId = ""; + newsplitBean.setResourceId(splitBean.getResourceId()); +// this.fromDate = ""; + newsplitBean.setFromDate(splitBean.getFromDate()); +// this.fromTime = ""; + newsplitBean.setFromTime(splitBean.getFromTime()); +// this.toDate = ""; + newsplitBean.setToDate(splitBean.getToDate()); +// this.toTime = ""; + newsplitBean.setToTime(splitBean.getToTime()); +// this.newLeaveType = ""; + newsplitBean.setNewLeaveType(splitBean.getNewLeaveType()); +// this.duration = ""; + newsplitBean.setDuration(splitBean.getDuration()); +// this.pub_duration = ""; + newsplitBean.setPub_duration(splitBean.getPub_duration()); +// this.work_duration = ""; + newsplitBean.setWork_duration(splitBean.getWork_duration()); +// this.rest_duration = ""; + newsplitBean.setRest_duration(splitBean.getRest_duration()); +// this.tablenamedb = ""; + newsplitBean.setTablenamedb(splitBean.getTablenamedb()); +// this.fromdatedb = ""; + newsplitBean.setFromdatedb(splitBean.getFromdatedb()); +// this.fromtimedb = ""; + newsplitBean.setFromtimedb(splitBean.getFromtimedb()); +// this.todatedb = ""; + newsplitBean.setTodatedb(splitBean.getTodatedb()); +// this.totimedb = ""; + newsplitBean.setTotimedb(splitBean.getTotimedb()); +// this.durationDB = ""; + newsplitBean.setDurationDB(splitBean.getDurationDB()); +// this.durationrule = ""; + newsplitBean.setDurationrule(splitBean.getDurationrule()); +// this.computingMode = ""; + newsplitBean.setComputingMode(splitBean.getComputingMode()); +// this.vacationInfo = ""; + newsplitBean.setVacationInfo(splitBean.getVacationInfo()); +// this.status = ""; + newsplitBean.setStatus(splitBean.getStatus()); +// this.companion = ""; + newsplitBean.setCompanion(splitBean.getCompanion()); +// this.belongDate = ""; + newsplitBean.setBelongDate(splitBean.getBelongDate()); +// D_Mins = 0; + newsplitBean.setD_Mins(splitBean.getD_Mins()); +// this.serialid = ""; + newsplitBean.setSerialid(splitBean.getSerialid()); +// this.changeType = 0; + newsplitBean.setChangeType(splitBean.getChangeType()); +// this.preChangeType = 0; + newsplitBean.setPreChangeType(splitBean.getPreChangeType()); +// this.subcompanyid = ""; + newsplitBean.setSubcompanyid(splitBean.getSubcompanyid()); +// this.departmentid = ""; + newsplitBean.setDepartmentid(splitBean.getDepartmentid()); +// this.jobtitle = ""; + newsplitBean.setJobtitle(splitBean.getJobtitle()); +// this.durationTypeEnum + newsplitBean.setDurationTypeEnum(splitBean.getDurationTypeEnum()); +// this.workmins = 0; + newsplitBean.setWorkmins(splitBean.getWorkmins()); +// this.oneDayHour = 0.0; + newsplitBean.setOneDayHour(splitBean.getOneDayHour()); +// this.groupid = ""; + newsplitBean.setGroupid(splitBean.getGroupid()); +// this.timeselection = "1"; + newsplitBean.setTimeselection(splitBean.getTimeselection()); +// processChangeSplitBean = new ProcessChangeSplitBean(); + newsplitBean.setProcessChangeSplitBean(splitBean.getProcessChangeSplitBean()); +// this.iscompanion = ""; + newsplitBean.setIscompanion(splitBean.getIscompanion()); +// this.filterholidays = ""; + newsplitBean.setFilterholidays(splitBean.getFilterholidays()); +// this.overtime_type = ""; + newsplitBean.setOvertime_type(splitBean.getOvertime_type()); +// this.duration_type = ""; +// newsplitBean.setDuration_type(splitBean.getDuration_type()); +// this.conversion = ""; + newsplitBean.setConversion(splitBean.getConversion()); +// this.overtimeBalanceTimeBeans = Lists.newArrayList(); + newsplitBean.setOvertimeBalanceTimeBeans(splitBean.getOvertimeBalanceTimeBeans()); + newsplitBean.setRepeatTime(splitBean.getRepeatTime()); + + return newsplitBean; + } + + /** + * 监测按照自然日计算,根据排除休息日和节假日的设置,判断当前自然日是否需要排除计算 + * + * @param filterholidays + * @param resourceid + * @param splitDate + * @param i + */ + public boolean check_filterholidays(String filterholidays, String resourceid, String splitDate, + int i) { + boolean is_filterholidays = false; + if (i == 0) { + return is_filterholidays; + } + if (Util.null2String(filterholidays).length() > 0) { + List filterholidayList = Arrays.asList(filterholidays.split(",")); + if (filterholidayList != null && !filterholidayList.isEmpty()) { + //日期类型:1-节假日、2-工作日、3-休息日(节假日设置的优先级高于考勤组中的设置) + int changeType = KQOvertimeRulesBiz.getChangeType(resourceid, splitDate); + if (filterholidayList.contains("1")) { + //排除节假日 + if (filterholidayList.contains("2")) { + //排除休息日 + if (changeType == 3 || changeType == 1) { + is_filterholidays = true; + } + } else { + if (changeType == 1) { + is_filterholidays = true; + } + } + } else if (filterholidayList.contains("2")) { + //排除休息日 + if (changeType == 3) { + is_filterholidays = true; + } + } else { + //不排除休息日,也不排除节假日 + } + } + } + return is_filterholidays; + } + + /** + * 自由工时的流程数据拆分 + * + * @param shiftInfoBean + * @param splitBean + * @param i + * @param kqTimesArrayComInfo + * @param initArrays + * @param localFromDate + * @param localToDate + * @param betweenDays + * @return + */ + public boolean freeShiftSplit(ShiftInfoBean shiftInfoBean, SplitBean splitBean, int i, KQTimesArrayComInfo kqTimesArrayComInfo, int[] initArrays, LocalDate localFromDate, LocalDate localToDate, + long betweenDays) { + + String fromTime = splitBean.getFromtimedb(); + String toTime = splitBean.getTotimedb(); + int fromtimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(fromTime); + int totimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(toTime); + int flowbegintimeIndex = -1; + int flowendtimeIndex = -1; + + String fromtimedbOri = splitBean.getFromtimedb(); + String totimedbOri = splitBean.getTotimedb(); + String repeatTime = "0"; + DurationTypeEnum durationTypeEnum = splitBean.getDurationTypeEnum(); + if(DurationTypeEnum.LEAVE == durationTypeEnum || DurationTypeEnum.LEAVEBACK == durationTypeEnum){ + repeatTime = splitBean.getRepeatTime(); + } + + boolean isSplit = true; + String freeSignStart = shiftInfoBean.getFreeSignStart(); + String freeSignEnd = shiftInfoBean.getFreeSignEnd(); + if (freeSignStart.length() == 0) { + shiftInfoBean.setD_Mins(0.0); + isSplit = false; + return isSplit; + } + int freeSignStartIndex = kqTimesArrayComInfo.getArrayindexByTimes(freeSignStart); + int freeSignEndIndex = kqTimesArrayComInfo.getArrayindexByTimes(freeSignEnd); + int freeWorkMins = Util.getIntValue(shiftInfoBean.getFreeWorkMins()); + if (i == 0) { + isSplit = false; + return isSplit; + } else { + if (localFromDate.isEqual(localToDate)) { + if (fromtimeIndex > freeSignStartIndex) { + flowbegintimeIndex = fromtimeIndex; + flowendtimeIndex = totimeIndex; + } else { + flowbegintimeIndex = freeSignStartIndex; + flowendtimeIndex = totimeIndex; + } + } else { + if (i == 1) { + if (fromtimeIndex > freeSignStartIndex) { + flowbegintimeIndex = fromtimeIndex; + flowendtimeIndex = 1440; + } else { + flowbegintimeIndex = freeSignStartIndex; + flowendtimeIndex = 1440; + } + } else if (i == betweenDays) { + if (totimeIndex > freeSignStartIndex) { + flowbegintimeIndex = freeSignStartIndex; + flowendtimeIndex = totimeIndex; + } else { + isSplit = false; + return isSplit; + } + } else { + flowbegintimeIndex = freeSignStartIndex; + flowendtimeIndex = freeSignEndIndex; + } + } + } + kqLog.info("resourceid::" + splitBean.getResourceId() + "::自由班制 isSplit之前 i::" + i + "::flowbegintimeIndex:" + flowbegintimeIndex + ":flowendtimeIndex:" + flowendtimeIndex); + + if (isSplit) { + String splitFromTime = kqTimesArrayComInfo.getTimesByArrayindex(flowbegintimeIndex); + String splitToTime = kqTimesArrayComInfo.getTimesByArrayindex(flowendtimeIndex); + if("1".equals(repeatTime)) { + int flowbegintimeIndexO = kqTimesArrayComInfo.getArrayindexByTimes(fromtimedbOri); + int flowendtimeIndexO = kqTimesArrayComInfo.getArrayindexByTimes(totimedbOri); + if(flowbegintimeIndexO > flowbegintimeIndex){ + flowbegintimeIndex = flowbegintimeIndexO; + splitFromTime = kqTimesArrayComInfo.getTimesByArrayindex(flowbegintimeIndex); + } + if(flowendtimeIndexO < flowendtimeIndex){ + flowendtimeIndex = flowendtimeIndexO; + splitToTime = kqTimesArrayComInfo.getTimesByArrayindex(flowendtimeIndex); + } + } + int flowMins = flowendtimeIndex - flowbegintimeIndex; + flowMins = flowMins > freeWorkMins ? freeWorkMins : flowMins; + flowMins = flowMins > 0 ? flowMins : 0; + if (flowMins < 0) { + kqLog.info("resourceid::" + splitBean.getResourceId() + "::自由班制 不记录中间表 i::" + i + "::flowbegintimeIndex:" + flowbegintimeIndex + ":flowendtimeIndex:" + flowendtimeIndex + ":flowMins:" + flowMins); + return false; + } + splitBean.setD_Mins(flowMins); + splitBean.setWorkmins(freeWorkMins); + splitBean.setOneDayHour((freeWorkMins / 60.0)); + splitBean.setFromTime(splitFromTime); + splitBean.setToTime(splitToTime); + } + return isSplit; + } + + /** + * 非工作时长(自然日计算的) + * + * @param preShiftInfoBean + * @param splitBean + * @param i + * @param kqTimesArrayComInfo + * @param initArrays + * @param localFromDate + * @param localToDate + * @param betweenDays + * @return + */ + public boolean nonWorkDaySplit(ShiftInfoBean preShiftInfoBean, SplitBean splitBean, int i, + KQTimesArrayComInfo kqTimesArrayComInfo, int[] initArrays, LocalDate localFromDate, + LocalDate localToDate, long betweenDays) { + + boolean isSplit = true; + if (preShiftInfoBean != null) { + String isAcross = preShiftInfoBean.getIsAcross(); + if ("1".equalsIgnoreCase(isAcross)) { + List workAcrossIndex = preShiftInfoBean.getWorkAcrossIndex(); + if (workAcrossIndex != null && !workAcrossIndex.isEmpty()) { + int[] workIndexs = workAcrossIndex.get(workAcrossIndex.size() - 1); + return nonWorkDayCommonSplit(splitBean, i, kqTimesArrayComInfo, localFromDate, localToDate, betweenDays, workIndexs[1]); + } + } else { + return nonWorkDayCommonSplit(splitBean, i, kqTimesArrayComInfo, localFromDate, localToDate, betweenDays, -1); + } + } else { + return nonWorkDayCommonSplit(splitBean, i, kqTimesArrayComInfo, localFromDate, localToDate, betweenDays, -1); + } + + return isSplit; + } + + /** + * 非工作时长(自然日计算的) + * + * @param splitBean + * @param i + * @param kqTimesArrayComInfo + * @param localFromDate + * @param localToDate + * @param betweenDays + * @param preLastWorkIndex 如果前一天跨天,前一天最晚的下班时间 + * @return + */ + public boolean nonWorkDayCommonSplit(SplitBean splitBean, int i, + KQTimesArrayComInfo kqTimesArrayComInfo, LocalDate localFromDate, + LocalDate localToDate, long betweenDays, int preLastWorkIndex) { + boolean isSplit = true; + + String fromtimedbOri = splitBean.getFromtimedb(); + String totimedbOri = splitBean.getTotimedb(); + String repeatTime = "0"; + DurationTypeEnum durationTypeEnum = splitBean.getDurationTypeEnum(); + if(DurationTypeEnum.LEAVE == durationTypeEnum || DurationTypeEnum.LEAVEBACK == durationTypeEnum){ + repeatTime = splitBean.getRepeatTime(); + } + String fromTime = splitBean.getFromtimedb(); + String toTime = splitBean.getTotimedb(); + int fromtimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(fromTime); + int totimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(toTime); + int flowbegintimeIndex = -1; + int flowendtimeIndex = -1; + + if (i == 0) { + isSplit = false; + return isSplit; + } else { + if (localFromDate.isEqual(localToDate)) { + flowbegintimeIndex = fromtimeIndex; + flowendtimeIndex = totimeIndex; + } else { + if (i == 1) { + flowbegintimeIndex = fromtimeIndex; + flowendtimeIndex = 1440; + } else if (i == betweenDays) { + flowbegintimeIndex = 0; + flowendtimeIndex = totimeIndex; + } else { + flowbegintimeIndex = 0; + flowendtimeIndex = 1440; + } + } + } + if (isSplit) { + String splitFromTime = kqTimesArrayComInfo.getTimesByArrayindex(flowbegintimeIndex); + if (preLastWorkIndex > 0) { + if (preLastWorkIndex > flowbegintimeIndex) { + flowbegintimeIndex = preLastWorkIndex; + } + } + if("1".equals(repeatTime)){ + int flowbegintimeIndexO = kqTimesArrayComInfo.getArrayindexByTimes(fromtimedbOri); + int flowendtimeIndexO = kqTimesArrayComInfo.getArrayindexByTimes(totimedbOri); + if(flowbegintimeIndexO > flowbegintimeIndex){ + flowbegintimeIndex = flowbegintimeIndexO; + } + if(flowendtimeIndexO < flowendtimeIndex){ + flowendtimeIndex = flowendtimeIndexO; + } + } + if ("2".equalsIgnoreCase(splitBean.getDurationrule())) { + if ("2".equalsIgnoreCase(splitBean.getTimeselection())) { + return WorkHalfUnitSplitChain.getSplitDurationBean4NonTime(kqTimesArrayComInfo, splitBean, flowbegintimeIndex, flowendtimeIndex); + } + } else { + splitFromTime = kqTimesArrayComInfo.getTimesByArrayindex(flowbegintimeIndex); + String splitToTime = kqTimesArrayComInfo.getTimesByArrayindex(flowendtimeIndex); + int flowMins = flowendtimeIndex - flowbegintimeIndex; + flowMins = flowMins > 0 ? flowMins : 0; + splitBean.setD_Mins(flowMins); + splitBean.setFromTime(splitFromTime); + splitBean.setToTime(splitToTime); + } + } + return isSplit; + } + + /** + * 固定班制和排班制的数据拆分 + * + * @param shiftInfoBean + * @param splitBean + * @param i + * @param kqTimesArrayComInfo + * @param initArrays + * @param localFromDate + * @param localToDate + * @param betweenDays + * @param shouldLog + * @return + */ + + public boolean commonShiftSplit(ShiftInfoBean shiftInfoBean, SplitBean splitBean, int i, + KQTimesArrayComInfo kqTimesArrayComInfo, int[] initArrays, LocalDate localFromDate, + LocalDate localToDate, long betweenDays, boolean shouldLog) { + return commonShiftSplit(shiftInfoBean, splitBean, i, kqTimesArrayComInfo, initArrays, localFromDate, localToDate, betweenDays, shouldLog, false); + } + + public boolean commonShiftSplit(ShiftInfoBean shiftInfoBean, SplitBean splitBean, int i, + KQTimesArrayComInfo kqTimesArrayComInfo, int[] initArrays, LocalDate localFromDate, + LocalDate localToDate, long betweenDays, boolean shouldLog, boolean is_flow_humanized) { + + boolean isSplit = true; + + String fromTime = splitBean.getFromtimedb(); + String toTime = splitBean.getTotimedb(); + String fromtimedbOri = splitBean.getFromtimedb(); + String totimedbOri = splitBean.getTotimedb(); + String repeatTime = "0"; + DurationTypeEnum durationTypeEnum = splitBean.getDurationTypeEnum(); + if(DurationTypeEnum.LEAVE == durationTypeEnum || DurationTypeEnum.LEAVEBACK == durationTypeEnum){ + repeatTime = splitBean.getRepeatTime(); + } + + int fromtimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(fromTime); + int totimeIndex = kqTimesArrayComInfo.getArrayindexByTimes(toTime); + int flowbegintimeIndex = -1; + int flowendtimeIndex = -1; + + String isAcross = shiftInfoBean.getIsAcross(); + List real_allLongWorkTime = Lists.newArrayList(); + List allLongWorkTime = shiftInfoBean.getAllLongWorkTime(); + CollectionUtils.addAll(real_allLongWorkTime, new Object[allLongWorkTime.size()]); + Collections.copy(real_allLongWorkTime, allLongWorkTime); + + List real_workLongTimeIndex = Lists.newArrayList(); + List workLongTimeIndex = shiftInfoBean.getWorkLongTimeIndex(); + + //list带数组,这里要深拷贝 + for (int[] tmp : workLongTimeIndex) { + int[] real_tmp = new int[tmp.length]; + System.arraycopy(tmp, 0, real_tmp, 0, tmp.length); + real_workLongTimeIndex.add(real_tmp); + } + List restLongTimeIndex = shiftInfoBean.getRestLongTimeIndex(); + if (real_allLongWorkTime == null || real_allLongWorkTime.isEmpty()) { + isSplit = false; + return isSplit; + } + + if (real_workLongTimeIndex.size() == 1) { + KQShiftRuleInfoBiz kqShiftRuleInfoBiz = new KQShiftRuleInfoBiz(); + kqShiftRuleInfoBiz.rest_workLongTimeIndex(shiftInfoBean, splitBean, real_workLongTimeIndex, kqTimesArrayComInfo, real_allLongWorkTime, is_flow_humanized); + } + + //如果不跨天 + if (!isAcross.equalsIgnoreCase("1")) { + //如果是请假开始日期的前一天 + if (i == 0) { + isSplit = false; + return isSplit; + } else { + int firstTime = kqTimesArrayComInfo.getArrayindexByTimes(real_allLongWorkTime.get(0)); + int lastTime = kqTimesArrayComInfo.getArrayindexByTimes(real_allLongWorkTime.get(real_allLongWorkTime.size() - 1)); + + if (localFromDate.isEqual(localToDate)) { + flowbegintimeIndex = fromtimeIndex; + flowendtimeIndex = totimeIndex; + } else { + if (i == 1) { + flowbegintimeIndex = fromtimeIndex; + flowendtimeIndex = lastTime; + } else if (i == betweenDays) { + flowbegintimeIndex = firstTime; + flowendtimeIndex = totimeIndex; + } else { + flowbegintimeIndex = firstTime; + flowendtimeIndex = lastTime; + } + } + //工作时段里填充上1 + for (int j = 0; real_workLongTimeIndex != null && j < real_workLongTimeIndex.size(); j++) { + int[] longtimeIndexs = real_workLongTimeIndex.get(j); + Arrays.fill(initArrays, longtimeIndexs[0], longtimeIndexs[1], 1); + } + for (int j = 0; restLongTimeIndex != null && j < restLongTimeIndex.size(); j++) { + int[] resttimeIndexs = restLongTimeIndex.get(j); + Arrays.fill(initArrays, resttimeIndexs[0], resttimeIndexs[1], -1); + } + } + + + } else { + int firstTime = kqTimesArrayComInfo.getArrayindexByTimes(real_allLongWorkTime.get(0)); + //lasttime一定是跨天的 + int lastTime = kqTimesArrayComInfo.getArrayindexByTimes(real_allLongWorkTime.get(real_allLongWorkTime.size() - 1)); + if (i == 0) { + int fromtimeIndex48 = kqTimesArrayComInfo.turn24to48TimeIndex(fromtimeIndex); + int totimeIndex48 = kqTimesArrayComInfo.turn24to48TimeIndex(totimeIndex); + if (fromtimeIndex48 < lastTime) { + flowbegintimeIndex = fromtimeIndex48; + if (localFromDate.isEqual(localToDate)) { + if (totimeIndex48 < lastTime) { + flowendtimeIndex = totimeIndex48; + } else { + flowendtimeIndex = lastTime; + } + } else { + if (betweenDays == 2) { + //流程上开始日期和结束日期就相差一天 + if ((totimeIndex48 + 1440) < lastTime) { + flowendtimeIndex = totimeIndex48; + } else { + flowendtimeIndex = lastTime; + } + } else { + //流程上开始日期和结束日期相差超过1天 + flowendtimeIndex = lastTime; + } + + } + } else { + isSplit = false; + return isSplit; + } + } else { + if (localFromDate.isEqual(localToDate)) { + flowbegintimeIndex = fromtimeIndex; + flowendtimeIndex = totimeIndex; + } else { + if (i == 1) { + flowbegintimeIndex = fromtimeIndex; + if ((i + 1) == (betweenDays)) { + int totimeIndex48 = kqTimesArrayComInfo.turn24to48TimeIndex(totimeIndex); + if (totimeIndex48 < lastTime) { + flowendtimeIndex = totimeIndex48; + } else { + flowendtimeIndex = lastTime; + } + } else { + flowendtimeIndex = lastTime; + } + } else if (i == (betweenDays - 1)) { + flowbegintimeIndex = firstTime; + int totimeIndex48 = kqTimesArrayComInfo.turn24to48TimeIndex(totimeIndex); + if (totimeIndex48 < lastTime) { + flowendtimeIndex = totimeIndex48; + } else { + flowendtimeIndex = lastTime; + } + } else if (i == betweenDays) { + flowbegintimeIndex = firstTime; + flowendtimeIndex = totimeIndex; + if (firstTime > totimeIndex) { + isSplit = false; + return isSplit; + } + } else { + flowbegintimeIndex = firstTime; + flowendtimeIndex = lastTime; + if (firstTime > lastTime) { + isSplit = false; + return isSplit; + } + } + } + } + //工作时段里填充上1 + for (int j = 0; j < real_workLongTimeIndex.size(); j++) { + int[] longtimeIndexs = real_workLongTimeIndex.get(j); + Arrays.fill(initArrays, longtimeIndexs[0], longtimeIndexs[1], 1); + + } + for (int j = 0; j < restLongTimeIndex.size(); j++) { + int[] resttimeIndexs = restLongTimeIndex.get(j); + Arrays.fill(initArrays, resttimeIndexs[0], resttimeIndexs[1], -1); + } + } + if (isSplit) { + + if ("2".equalsIgnoreCase(splitBean.getDurationrule())) { + if ("2".equalsIgnoreCase(splitBean.getTimeselection())) { + return WorkHalfUnitSplitChain.getSplitDurationBean4Time(initArrays, shiftInfoBean, kqTimesArrayComInfo, splitBean, flowbegintimeIndex, flowendtimeIndex); + } + } else { + String splitFromTime = kqTimesArrayComInfo.getTimesByArrayindex(flowbegintimeIndex); + String splitToTime = kqTimesArrayComInfo.getTimesByArrayindex(flowendtimeIndex); + int flowMins = kqTimesArrayComInfo.getCnt(initArrays, flowbegintimeIndex, flowendtimeIndex, 1); + if("1".equals(repeatTime)){ + flowMins = 0; + int flowbegintimeIndexO = kqTimesArrayComInfo.getArrayindexByTimes(fromtimedbOri); + int flowendtimeIndexO = kqTimesArrayComInfo.getArrayindexByTimes(totimedbOri); + if(flowbegintimeIndexO < flowbegintimeIndex){ + flowbegintimeIndexO = flowbegintimeIndex; + } + if(flowendtimeIndexO > flowendtimeIndex){ + flowendtimeIndexO = flowendtimeIndex; + } + int flowMinsO = kqTimesArrayComInfo.getCnt(initArrays, flowbegintimeIndexO, flowendtimeIndexO, 1); + if(flowMinsO > 0){ + splitFromTime = fromtimedbOri; + splitToTime = totimedbOri; + flowMins += flowMinsO; + } + //还有跨天的情况 + int flowbegintimeIndexN = kqTimesArrayComInfo.getArrayindexByTimes(kqTimesArrayComInfo.turn24to48Time(fromtimedbOri)); + int flowendtimeIndexN = kqTimesArrayComInfo.getArrayindexByTimes(kqTimesArrayComInfo.turn24to48Time(totimedbOri)); + if(flowbegintimeIndexN < flowbegintimeIndex){ + flowbegintimeIndexN = flowbegintimeIndex; + } + if(flowendtimeIndexN > flowendtimeIndex){ + flowendtimeIndexN = flowendtimeIndex; + } + int flowMinsN = kqTimesArrayComInfo.getCnt(initArrays, flowbegintimeIndexN, flowendtimeIndexN, 1); + if(flowMinsN > 0){ + splitFromTime = kqTimesArrayComInfo.turn24to48Time(fromtimedbOri); + splitToTime = kqTimesArrayComInfo.turn24to48Time(totimedbOri); + flowMins += flowMinsN; + } + } + if (shouldLog) { + kqLog.info("resourceid:" + splitBean.getResourceId() + ":::i::" + i + "::flowbegintimeIndex:" + flowbegintimeIndex + ":flowendtimeIndex:" + flowendtimeIndex + ":flowMins:" + flowMins); + } + flowMins = flowMins > 0 ? flowMins : 0; + if (flowMins < 0) { + if (shouldLog) { + kqLog.info("resourceid:" + splitBean.getResourceId() + ":::不记录中间表 i::" + i + "::flowbegintimeIndex:" + flowbegintimeIndex + ":flowendtimeIndex:" + flowendtimeIndex + ":flowMins:" + flowMins); + } + return false; + } + splitBean.setD_Mins(flowMins); + splitBean.setWorkmins(shiftInfoBean.getWorkmins()); + splitBean.setFromTime(splitFromTime); + splitBean.setToTime(splitToTime); + splitBean.setConvertAttendDay(shiftInfoBean.getConvertAttendDay()); + } + + } + return isSplit; + } + + /** + * 根据单位来转换时长 + * + * @param splitBean + * @param isComputingMode2 是否按照自然日计算 + */ + private void turnDuration(SplitBean splitBean, boolean isComputingMode2) { + String durationrule = splitBean.getDurationrule(); + + //计算规则 1-按天请假 2-按半天请假 3-按小时请假 4-按整天请假 5半小时 6整小时 + //按照天和小时的可以在这里计算,半天的和整天的单独处理 + if ("1".equalsIgnoreCase(durationrule)) { + durationrule1(splitBean, isComputingMode2); + } else if ("3".equalsIgnoreCase(durationrule)) { + durationrule3(splitBean, isComputingMode2); + } else if ("5".equalsIgnoreCase(durationrule)) { + String conversion = splitBean.getConversion(); + if (conversion.length() > 0 && Util.getIntValue(conversion) > 0) { + double conversionMins = 0.0; + int halfHourInt = 30; + KQOverTimeRuleCalBiz kqOverTimeRuleCalBiz = new KQOverTimeRuleCalBiz(); + conversionMins = kqOverTimeRuleCalBiz.getConversionMins(halfHourInt, splitBean.getD_Mins(), Util.getIntValue(conversion)); + splitBean.setD_Mins(conversionMins); + } + durationrule3(splitBean, isComputingMode2); + } else if ("6".equalsIgnoreCase(durationrule)) { + String conversion = splitBean.getConversion(); + if (conversion.length() > 0 && Util.getIntValue(conversion) > 0) { + double conversionMins = 0.0; + int wholeHourInt = 60; + KQOverTimeRuleCalBiz kqOverTimeRuleCalBiz = new KQOverTimeRuleCalBiz(); + conversionMins = kqOverTimeRuleCalBiz.getConversionMins(wholeHourInt, splitBean.getD_Mins(), Util.getIntValue(conversion)); + splitBean.setD_Mins(conversionMins); + } + durationrule3(splitBean, isComputingMode2); + } + + } + + /** + * 按天请假 + * + * @param splitBean + * @param isComputingMode2 是否按照自然日计算 + * @return + */ + private void durationrule1(SplitBean splitBean, boolean isComputingMode2) { + String computingMode = splitBean.getComputingMode(); + double d_Mins = splitBean.getD_Mins(); + double curDays = 0.0; + if (isComputingMode2) { + double oneDayHour = splitBean.getOneDayHour(); + if (oneDayHour > 0) { + double oneDayMins = oneDayHour * 60.0; + splitBean.setWorkmins(((int) oneDayMins)); + if (d_Mins > oneDayMins) { + d_Mins = oneDayMins; + splitBean.setD_Mins(d_Mins); + } + curDays = (d_Mins) / (oneDayMins); + curDays = curDays > 0 ? curDays : 0.0; + } + } else { + int workmins = splitBean.getWorkmins(); + String convertAttendDay = Util.null2s(splitBean.getConvertAttendDay(),"1.0"); + double convertAttendDayD = Util.getDoubleValue(convertAttendDay); + if (workmins > 0) { + curDays = (d_Mins / (workmins * 1.0))*convertAttendDayD; + curDays = curDays > 0 ? curDays : 0.0; + } + } + + splitBean.setDuration(KQDurationCalculatorUtil.getDurationRound5("" + (curDays))); + } + + /** + * 按小时请假 + * + * @param splitBean + * @param isComputingMode2 + * @return + */ + private double durationrule3(SplitBean splitBean, boolean isComputingMode2) { + double D_Mins = splitBean.getD_Mins(); + double hours = 0.0; + if (isComputingMode2) { + double oneDayHour = splitBean.getOneDayHour(); + if (oneDayHour > 0) { + double oneDayMins = oneDayHour * 60.0; + splitBean.setWorkmins(((int) oneDayMins)); + if (D_Mins > oneDayMins) { + D_Mins = oneDayMins; + splitBean.setD_Mins(D_Mins); + } + } + } + hours = D_Mins / 60.0; + hours = hours > 0 ? hours : 0.0; + splitBean.setDuration(KQDurationCalculatorUtil.getDurationRound("" + (hours))); + return hours; + } + + + /** + * 根据传入的日期和时间拆分成每一天一条的集合 + * + * @param fromDate + * @param toDate + * @param fromTime + * @param toTime + * @return + */ + public static List> getSplitList(String fromDate, String toDate, String fromTime, String toTime) { + List> splitLists = new ArrayList<>(); + Map splitMap = new HashMap<>(); + + LocalDate localFromDate = LocalDate.parse(fromDate); + LocalDate localToDate = LocalDate.parse(toDate); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + //进入到这里表示是多天 + if (localFromDate.isBefore(localToDate)) { + long betweenDays = localToDate.toEpochDay() - localFromDate.toEpochDay(); + for (int i = 0; i <= betweenDays; i++) { + splitMap = new HashMap<>(); + LocalDate curLocalDate = localFromDate.plusDays(i); + + splitMap.put("splitDate", curLocalDate.format(dateFormatter)); + if (i == 0) { + splitMap.put("fromTime", fromTime); + splitMap.put("toTime", "23:59"); + } else if (i == betweenDays) { + splitMap.put("fromTime", "00:00"); + splitMap.put("toTime", toTime); + } else { + splitMap.put("fromTime", "00:00"); + splitMap.put("toTime", "23:59"); + } + splitLists.add(splitMap); + } + } else if (localFromDate.isEqual(localToDate)) { + //同一天 + splitMap.put("splitDate", localFromDate.format(dateFormatter)); + splitMap.put("fromTime", fromTime); + splitMap.put("toTime", toTime); + splitLists.add(splitMap); + } + return splitLists; + } + + /** + * 根据传入的日期和时间拆分成每一天一条的集合 + * + * @param fromDate + * @param toDate + * @param fromTime + * @param toTime + * @return + */ + public static List> getSplitListRepeat(String fromDate, String toDate, String fromTime, String toTime) { + List> splitLists = new ArrayList<>(); + Map splitMap = new HashMap<>(); + + LocalDate localFromDate = LocalDate.parse(fromDate); + LocalDate localToDate = LocalDate.parse(toDate); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + long betweenDays = localToDate.toEpochDay() - localFromDate.toEpochDay(); + for (int i = 0; i <= betweenDays; i++) { + splitMap = new HashMap<>(); + LocalDate curLocalDate = localFromDate.plusDays(i); + splitMap.put("splitDate", curLocalDate.format(dateFormatter)); + splitMap.put("fromTime", fromTime); + splitMap.put("toTime", toTime); + splitLists.add(splitMap); + } + return splitLists; + } + + /** + * 根据传入的日期和时间拆分成半天规则的集合 + * + * @param fromDate + * @param toDate + * @param fromTime + * @param toTime + * @return + */ + public static List> getSplitHalfDayList(String fromDate, String toDate, String fromTime, String toTime) { + List> splitLists = new ArrayList<>(); + Map splitMap = new HashMap<>(); + + LocalDate localFromDate = LocalDate.parse(fromDate); + LocalDate localToDate = LocalDate.parse(toDate); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + //进入到这里表示是多天 + if (localFromDate.isBefore(localToDate)) { + long betweenDays = localToDate.toEpochDay() - localFromDate.toEpochDay(); + for (int i = 0; i <= betweenDays; i++) { + splitMap = new HashMap<>(); + LocalDate curLocalDate = localFromDate.plusDays(i); + splitMap.put("splitDate", curLocalDate.format(dateFormatter)); + if (i == 0) { + int foreOrAfter = SplitSelectSet.foreOrAfter(fromTime, SplitSelectSet.afternoon_end); + splitMap.put("foreOrAfter", "" + foreOrAfter); + } else if (i == betweenDays) { + int foreOrAfter = SplitSelectSet.foreOrAfter(SplitSelectSet.forenoon_start, toTime); + splitMap.put("foreOrAfter", "" + foreOrAfter); + } else { + splitMap.put("foreOrAfter", "" + SplitSelectSet.fore_after_index); + } + splitLists.add(splitMap); + } + } else if (localFromDate.isEqual(localToDate)) { + //同一天 + splitMap.put("splitDate", localFromDate.format(dateFormatter)); + int foreOrAfter = SplitSelectSet.foreOrAfter(fromTime, toTime); + splitMap.put("foreOrAfter", "" + foreOrAfter); + splitLists.add(splitMap); + } + return splitLists; + } + + /** + * 根据传入的日期分成集合 + * + * @param fromDate + * @param toDate + * @return + */ + public static List> getSplitDayList(String fromDate, String toDate) { + List> splitLists = new ArrayList<>(); + Map splitMap = new HashMap<>(); + + LocalDate localFromDate = LocalDate.parse(fromDate); + LocalDate localToDate = LocalDate.parse(toDate); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + long betweenDays = localToDate.toEpochDay() - localFromDate.toEpochDay(); + for (int i = 0; i <= betweenDays; i++) { + splitMap = new HashMap<>(); + LocalDate curLocalDate = localFromDate.plusDays(i); + splitMap.put("splitDate", curLocalDate.format(dateFormatter)); + splitLists.add(splitMap); + } + return splitLists; + } + + /** + * 对于工作日加班判断是否是开启了晚走晚到的规则,开启了的话,不试做加班 + * + * @return + */ + public boolean checkIsLateoutlatein(String resourceId, String taskDate) { + boolean isLateoutlatein = false; + KQWorkTime kqWorkTime = new KQWorkTime(); + Map serialInfo = kqWorkTime.getSerialInfo(resourceId, taskDate, false); + if (serialInfo != null && serialInfo.size() > 0) { + boolean isRest = kqWorkTime.isNonWork(serialInfo); + if(isRest){ + return isLateoutlatein; + } + String serialid = Util.null2String(serialInfo.get(taskDate)); + if (serialid.length() > 0) { + KQShiftPersonalizedRuleCominfo ruleCominfo = new KQShiftPersonalizedRuleCominfo(); + KQShiftPersonalizedRuleDetailComInfo ruleDetailComInfo = new KQShiftPersonalizedRuleDetailComInfo(); + String personalizedruleid = ruleCominfo.getID(serialid); + Map ruleDetailMap = ruleDetailComInfo.getPersonalizedRuleDetail(personalizedruleid); + if (ruleDetailMap != null && !ruleDetailMap.isEmpty()) { + List workSectionList = (List) ruleDetailMap.get("lateoutlatein"); + if (workSectionList != null && !workSectionList.isEmpty()) { +// workSectionList里存的enable都是一致的,取一个就行 + Map sectionMap = (Map) workSectionList.get(0); + if (sectionMap != null && !sectionMap.isEmpty()) { + String enable = Util.null2String(sectionMap.get("enable")); + if ("1".equalsIgnoreCase(enable)) { + isLateoutlatein = true; + kqLog.info("resourceid:" + resourceId + ":taskDate:" + taskDate + ":::开启了晚走晚到规则,不计算加班 checkIsLateoutlatein:resourceId:" + resourceId + ":taskDate:" + taskDate + ":serialid:" + serialid); + return isLateoutlatein; + } + } + } + } + } + } + + return isLateoutlatein; + } + + /** + * 推送 补打卡,外勤,考勤同步数据,触发加班规则生成加班数据处理 + * + * @param fromDate + * @param toDate + * @param resourceids 支持多个人的 + */ + public static void pushOverTimeTasksAll(String fromDate, String toDate, String resourceids) { + + kqLog.info("pushOverTimeTasksAll 参数为:resourceids:" + resourceids + ":fromDate:" + fromDate + ":toDate:" + toDate); + if (resourceids.length() == 0 || fromDate.length() == 0 || toDate.length() == 0) { + return; + } + List tasks = new ArrayList<>(); + String[] resourceid_arr = resourceids.split(","); + for (int i = 0; i < resourceid_arr.length; i++) { + pushOverTimeTasks(fromDate, toDate, resourceid_arr[i], tasks); + } + if (!tasks.isEmpty()) { + KQQueue.writeTasks(tasks); + } + + } + + /** + * 推送 补打卡,外勤,考勤同步数据,触发加班规则生成加班数据处理 + * + * @param fromDate + * @param toDate + * @param resourceid + * @param tasks + */ + public static void pushOverTimeTasks(String fromDate, String toDate, String resourceid, List tasks) { + + try { + if (true) { + KQTaskBean kqTaskBean = new KQTaskBean(); + kqTaskBean.setResourceId(resourceid); + kqTaskBean.setOvertime_fromdate(fromDate); + kqTaskBean.setOvertime_todate(toDate); + tasks.add(kqTaskBean); + } else { + pushOverTimeTasks_old(fromDate, toDate, resourceid, tasks); + } + } catch (Exception e) { + baseBean.writeLog(e); + } + } + + public static void pushOverTimeTasks_old(String fromDate, String toDate, String resourceid, List tasks) { + +// kqLog.info("批量加班推送 pushOverTimeTasks:fromDate:"+fromDate+"::toDate:"+toDate+"::resourceid:"+resourceid); + + LocalDate localFromDate = LocalDate.parse(fromDate); + LocalDate localToDate = LocalDate.parse(toDate); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + long betweenDays = localToDate.toEpochDay() - localFromDate.toEpochDay(); + for (int i = 0; i <= betweenDays; i++) { + LocalDate curLocalDate = localFromDate.plusDays(i); + LocalDate preCurLocalDate = curLocalDate.minusDays(1); + LocalDate nextCurLocalDate = curLocalDate.plusDays(1); + String splitDate = curLocalDate.format(dateFormatter); + String pre_splitDate = preCurLocalDate.format(dateFormatter); + String next_splitDate = nextCurLocalDate.format(dateFormatter); + Map pre_todayLineMap = KQDurationCalculatorUtil.getWorkButton(resourceid, pre_splitDate, false); + Map todayLineMap = KQDurationCalculatorUtil.getWorkButton(resourceid, splitDate, false); + //因为现在是上班前都归属前一天,所以这里存一下上班前的开始时间 + Map workTimeStartMap = new HashMap<>(); + //如果昨天是工作日,昨天的上班时间作为今天的允许加班开始时间(因为下班后加班都属于前一天的) + String pre_workTime = ""; + if (pre_todayLineMap.get("signTime") != null) { + pre_workTime = getEndWorktime(pre_todayLineMap, splitDate, workTimeStartMap, resourceid, pre_splitDate); + } else { + workTimeStartMap.put("pre_isrest", "1"); + } + //如果今天是非工作日,明天是工作日,明天的上班时间作为今天的允许加班结束时间 + String next_workTime = ""; + Map next_todayLineMap = KQDurationCalculatorUtil.getWorkButton(resourceid, next_splitDate, false); + + if (next_todayLineMap.get("signTime") != null) { + next_workTime = getStartWorktime(next_todayLineMap, splitDate, workTimeStartMap); + } else { + workTimeStartMap.put("next_isrest", "1"); + } + boolean isTodayWorkDay = todayLineMap.get("signTime") != null; + + kqLog.info("pushOverTimeTasks splitDate:" + splitDate + ":isTodayWorkDay:" + isTodayWorkDay + ":pre_workTime:" + pre_workTime + ":next_workTime:" + next_workTime); + //如果当前日期是工作日 + if (isTodayWorkDay) { + List> todaySignTime = (List>) todayLineMap.get("signTime"); + if (todaySignTime != null && !todaySignTime.isEmpty()) { + overTime4Work(splitDate, pre_splitDate, resourceid, tasks, todayLineMap, todaySignTime, workTimeStartMap); + } else { + overTime4NonWork(splitDate, pre_workTime, resourceid, tasks, next_workTime, workTimeStartMap, pre_splitDate); + } + } else { + overTime4NonWork(splitDate, pre_workTime, resourceid, tasks, next_workTime, workTimeStartMap, pre_splitDate); + } + } +// kqLog.info("批量加班推送 数据为:"+(JSON.toJSONString(tasks))); + + } + + /** + * 获取最晚允许下班时间 + * + * @param pre_todayLineMap + * @param splitDate + * @param workTimeStartMap + * @param resourceid + * @param pre_splitDate + * @return + */ + private static String getEndWorktime(Map pre_todayLineMap, String splitDate, + Map workTimeStartMap, String resourceid, String pre_splitDate) { + String pre_workTime = ""; + List> pre_todaySignTime = (List>) pre_todayLineMap.get("signTime"); + if (pre_todaySignTime != null && !pre_todaySignTime.isEmpty()) { + Map pre_todaySignMap = pre_todaySignTime.get(pre_todaySignTime.size() - 1); + String endtime = pre_todaySignMap.get("endtime"); + String endtime_across = pre_todaySignMap.get("endtime_across"); + if ("1".equalsIgnoreCase(endtime_across)) { + pre_workTime = splitDate + " " + endtime + ":59"; + } + Map first_SignMap = pre_todaySignTime.get(0); + String workbengintime = first_SignMap.get("workbengintime"); + workTimeStartMap.put("pre_workbengintime", workbengintime); + if (pre_todaySignTime.size() == 1) { + boolean is_flow_humanized = KQSettingsBiz.is_flow_humanized(); + if (is_flow_humanized) { + ShiftInfoBean shiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, pre_splitDate, false); + Map shifRuleMap = Maps.newHashMap(); + KQShiftRuleInfoBiz.getShiftRuleInfo(shiftInfoBean, resourceid, shifRuleMap); + if (!shifRuleMap.isEmpty()) { + if (shifRuleMap.containsKey("shift_beginworktime")) { + String shift_beginworktime = Util.null2String(shifRuleMap.get("shift_beginworktime")); + if (shift_beginworktime.length() > 0) { + workTimeStartMap.put("pre_workbengintime", shift_beginworktime); + } + } + if (shifRuleMap.containsKey("shift_endworktime")) { + String shift_endworktime = Util.null2String(shifRuleMap.get("shift_endworktime")); + if (shift_endworktime.length() > 0) { + pre_workTime = shift_endworktime; + } + } + } + } + } + } else { + workTimeStartMap.put("pre_isrest", "1"); + } + return pre_workTime; + } + + /** + * 获取最早允许上班时间 + * + * @param next_todayLineMap + * @param splitDate + * @return + */ + private static String getStartWorktime(Map next_todayLineMap, String splitDate, + Map workTimeStartMap) { + String next_workTime = ""; + List> next_todaySignTime = (List>) next_todayLineMap.get("signTime"); + if (next_todaySignTime != null && !next_todaySignTime.isEmpty()) { + Map next_todaySignMap = next_todaySignTime.get(0); + String bengintime = next_todaySignMap.get("bengintime"); + String workbengintime = next_todaySignMap.get("workbengintime"); + String bengintime_pre_across = next_todaySignMap.get("bengintime_pre_across"); + if ("1".equalsIgnoreCase(bengintime_pre_across)) { + next_workTime = splitDate + " " + bengintime + ":00"; + } + workTimeStartMap.put("next_workbengintime", workbengintime); + } else { + workTimeStartMap.put("next_isrest", "1"); + } + return next_workTime; + } + + public static void overTime4Work(String splitDate, String pre_splitDate, String resourceid, + List tasks, Map todayLineMap, + List> todaySignTime, + Map workTimeStartMap) { + + //现在标准是默认取最后一个班次作为加班 + Map todaySignMap = Maps.newHashMap(); + if (todaySignTime.size() == 1) { + todaySignMap = todaySignTime.get(0); + overTime4WorkSign(todaySignMap, splitDate, pre_splitDate, resourceid, tasks, todayLineMap, workTimeStartMap, ""); + } else if (todaySignTime.size() > 1) { + for (int i = 0; i < 2; i++) { + if (i == 0) { + todaySignMap = todaySignTime.get(0); + overTime4WorkSign(todaySignMap, splitDate, pre_splitDate, resourceid, tasks, todayLineMap, workTimeStartMap, "before"); + } else if (i == 1) { + todaySignMap = todaySignTime.get(todaySignTime.size() - 1); + overTime4WorkSign(todaySignMap, splitDate, pre_splitDate, resourceid, tasks, todayLineMap, workTimeStartMap, "after"); + } + } + } + } + + public static void overTime4WorkSign( + Map todaySignMap, String splitDate, String pre_splitDate, + String resourceid, List tasks, + Map todayLineMap, + Map workTimeStartMap, String signsource) { + RecordSet rs = new RecordSet(); + KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + DateTimeFormatter fullFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + DateTimeFormatter datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + + List allWorkTime = (List) todayLineMap.get("allWorkTime"); + String firstWorkTime = ""; + String lastWorkTime = ""; + if (allWorkTime != null && !allWorkTime.isEmpty()) { + firstWorkTime = allWorkTime.get(0); + lastWorkTime = allWorkTime.get(allWorkTime.size() - 1); + } + String yesterday = LocalDate.parse(splitDate).minusDays(1).format(dateFormatter); + String nextday = LocalDate.parse(splitDate).plusDays(1).format(dateFormatter); + + String workbengintime = Util.null2s(todaySignMap.get("workbengintime"), ""); + String bengintime = Util.null2s(todaySignMap.get("bengintime"), ""); + //上班开始时间是否跨天到后一天 + String bengintime_across = Util.null2s(todaySignMap.get("bengintime_across"), ""); + //上班打卡开始时间是否跨天到前一天 + String bengintime_pre_across = Util.null2s(todaySignMap.get("bengintime_pre_across"), ""); + String bengintime_end = Util.null2s(todaySignMap.get("bengintime_end"), ""); + String bengintime_end_across = Util.null2s(todaySignMap.get("bengintime_end_across"), ""); + + String endtime = Util.null2s(todaySignMap.get("endtime"), ""); + String endtime_across = Util.null2s(todaySignMap.get("endtime_across"), ""); + String endtime_start = Util.null2s(todaySignMap.get("endtime_start"), ""); + String endtime_start_across = Util.null2s(todaySignMap.get("endtime_start_across"), ""); + + String workendtime_across = Util.null2s(todaySignMap.get("workendtime_across"), ""); + boolean isEndTimeAcross = false; + if ("1".equalsIgnoreCase(workendtime_across)) { + isEndTimeAcross = true; + } + + String signInDateTime = splitDate + " " + bengintime + ":00"; + if ("1".equalsIgnoreCase(bengintime_pre_across)) { + signInDateTime = yesterday + " " + bengintime + ":00"; + } + if ("1".equalsIgnoreCase(bengintime_across)) { + signInDateTime = nextday + " " + bengintime + ":00"; + } + String signInEndDateTime = ""; + if (bengintime_end.length() > 0) { + signInEndDateTime = splitDate + " " + bengintime_end + ":00"; + if ("1".equalsIgnoreCase(bengintime_end_across)) { + signInEndDateTime = nextday + " " + bengintime_end + ":00"; + } + } +// if(pre_workTime.length() > 0){ +// signInDateTime = splitDate + " " +pre_workTime+":00"; +// } + String signOutDateTime = splitDate + " " + endtime + ":59"; + if ("1".equalsIgnoreCase(endtime_across)) { + signOutDateTime = nextday + " " + endtime + ":59"; + } + String signOutBeginDateTime = ""; + if (endtime_start.length() > 0) { + signOutBeginDateTime = splitDate + " " + endtime_start + ":59"; + if ("1".equalsIgnoreCase(endtime_start_across)) { + signOutBeginDateTime = nextday + " " + endtime_start + ":59"; + } + } + String sign_signSectionTime = ""; + String sign_signSectionEndTime = ""; + String sign_signSectionBeginTime = ""; + String sign_offSignSectionTime = ""; + if (signInEndDateTime.length() == 0 && signOutBeginDateTime.length() == 0) { + //如果没设置上班后,下班前打卡 + sign_signSectionTime = signInDateTime; + sign_offSignSectionTime = signOutDateTime; + } else { + if (signInEndDateTime.length() > 0) { + if (signOutBeginDateTime.length() > 0) { + //如果上班后,下班前打卡范围都做了控制 + sign_signSectionTime = signInDateTime; + sign_signSectionEndTime = signInEndDateTime; + sign_signSectionBeginTime = signOutBeginDateTime; + sign_offSignSectionTime = signOutDateTime; + + } else { + LocalDateTime onLocalDateEndTime = LocalDateTime.parse(signInEndDateTime, fullFormatter); + //如果只是上班后打卡范围做了控制 + LocalDateTime tmp = LocalDateTime.parse(onLocalDateEndTime.plusMinutes(1).format(datetimeFormatter) + ":00", fullFormatter); + String tmp_datetime = tmp.format(fullFormatter); + sign_signSectionTime = signInDateTime; + sign_signSectionEndTime = signInEndDateTime; + sign_signSectionBeginTime = tmp_datetime; + sign_offSignSectionTime = signOutDateTime; + + } + } else if (signOutBeginDateTime.length() > 0) { + //如果只是下班前打卡范围做了控制 + LocalDateTime offLocalDateBeginTime = LocalDateTime.parse(signOutBeginDateTime, fullFormatter); + LocalDateTime tmp = LocalDateTime.parse(offLocalDateBeginTime.minusMinutes(1).format(datetimeFormatter) + ":59", fullFormatter); + String tmp_datetime = tmp.format(fullFormatter); + sign_signSectionTime = signInDateTime; + sign_signSectionEndTime = tmp_datetime; + sign_signSectionBeginTime = signOutBeginDateTime; + sign_offSignSectionTime = signOutDateTime; + } + } + + KQScheduleSignBiz kqScheduleSignBiz = new KQScheduleSignBiz.KQScheduleSignParamBuilder().resourceidParam(resourceid) + .signSectionTimeParam(sign_signSectionTime).signSectionEndTimeParam(sign_signSectionEndTime) + .signSectionBeginTimeParam(sign_signSectionBeginTime).offSignSectionTimeParam(sign_offSignSectionTime).build(); + Map signMap = kqScheduleSignBiz.getScheduleSignInfoWithCardRange(); + if (signMap != null && !signMap.isEmpty()) { + KQHrmScheduleSign signInTimeBean = signMap.get("signin"); + KQHrmScheduleSign signOutTimeBean = signMap.get("signout"); + if (allWorkTime.size() == 2) { + boolean is_flow_humanized = KQSettingsBiz.is_flow_humanized(); + if (is_flow_humanized) { + //一天一次打卡的情况下需要考虑个性化设置 + if (todayLineMap.containsKey("shiftRuleMap")) { + Map shiftRuleMap = (Map) todayLineMap.get("shiftRuleMap"); + if (shiftRuleMap != null && !shiftRuleMap.isEmpty() && shiftRuleMap.containsKey("ruleDetail")) {//处理人性化设置其他规则 + Map ruleDetail = (Map) shiftRuleMap.get("ruleDetail"); + if (ruleDetail != null && !ruleDetail.isEmpty()) { + Map shifRuleMap = KQShiftRuleInfoBiz.do4ShiftRule(ruleDetail, signInTimeBean, signOutTimeBean, allWorkTime, splitDate, nextday, resourceid); + if (!shifRuleMap.isEmpty()) { + if (shifRuleMap.containsKey("shift_beginworktime")) { + String shift_beginworktime = Util.null2String(shifRuleMap.get("shift_beginworktime")); + firstWorkTime = shift_beginworktime; + } + if (shifRuleMap.containsKey("shift_endworktime")) { + String shift_endworktime = Util.null2String(shifRuleMap.get("shift_endworktime")); + if (shift_endworktime.length() > 0) { + lastWorkTime = shift_endworktime; + int lastWorkTime_index = kqTimesArrayComInfo.getArrayindexByTimes(lastWorkTime); + if (lastWorkTime_index >= 1440) { + isEndTimeAcross = true; + lastWorkTime = kqTimesArrayComInfo.turn48to24Time(lastWorkTime); + } else { + isEndTimeAcross = false; + } + + } + } + } + } + } + } + } + } + if (signsource.length() > 0) { + if ("before".equalsIgnoreCase(signsource)) { + signOutTimeBean = null; + } + if ("after".equalsIgnoreCase(signsource)) { + signInTimeBean = null; + } + } + if (signInTimeBean != null) { + String signdate = Util.null2String(signInTimeBean.getSigndate()); + String signtime = Util.null2String(signInTimeBean.getSigntime()); + String pre_bengintime = Util.null2String(workTimeStartMap.get("pre_workbengintime")); + if (pre_bengintime.length() > 0) { + //当前是工作日,前一天是工作日的情况 + pre_bengintime = pre_bengintime + ":00"; + String tmp_pre_bengintime = splitDate + " " + pre_bengintime; + String tmp_workbengintime = splitDate + " " + workbengintime + ":00"; + if (tmp_pre_bengintime.compareTo(tmp_workbengintime) > 0) { + pre_bengintime = workbengintime + ":00"; + } + if (firstWorkTime.length() > 0) { + String tmp_firstWorkTime = splitDate + " " + firstWorkTime + ":00"; + if (tmp_pre_bengintime.compareTo(tmp_firstWorkTime) > 0) { + tmp_pre_bengintime = tmp_firstWorkTime; + pre_bengintime = firstWorkTime + ":00"; + } + } + String tmp_signtime = signdate + " " + signtime; + if (tmp_pre_bengintime.compareTo(tmp_signtime) > 0) { + if (signtime.length() > 0) { + KQTaskBean kqTaskBean = new KQTaskBean(); + kqTaskBean.setResourceId(resourceid); + kqTaskBean.setTaskDate(pre_splitDate); + kqTaskBean.setLastWorkTime(signtime); + kqTaskBean.setTaskSignTime(pre_bengintime); + kqTaskBean.setSignDate(signdate); + kqTaskBean.setSignEndDate(splitDate); + kqTaskBean.setTimesource("before"); + if (!tasks.contains(kqTaskBean)) { + tasks.add(kqTaskBean); + } + } else { + kqLog.info("overTime4Work::signtime is null:" + signtime); + } + } + } else { + //当前是工作日,前一天是非工作日的情况 + String pre_isrest = Util.null2String(workTimeStartMap.get("pre_isrest")); + if ("1".equalsIgnoreCase(pre_isrest)) { + if (firstWorkTime.length() > 0) { + String tmp_firstWorkTime = splitDate + " " + firstWorkTime + ":00"; + String tmp_signtime = signdate + " " + signtime; + if (tmp_firstWorkTime.compareTo(tmp_signtime) > 0) { + KQTaskBean kqTaskBean = new KQTaskBean(); + kqTaskBean.setResourceId(resourceid); + kqTaskBean.setTaskDate(pre_splitDate); + kqTaskBean.setSignDate(splitDate); + kqTaskBean.setSignEndDate(signdate); + kqTaskBean.setSignInTime4Out(signtime); + kqTaskBean.setTaskSignTime(firstWorkTime + ":00"); + kqTaskBean.setTimesource("before"); + if (!tasks.contains(kqTaskBean)) { + tasks.add(kqTaskBean); + } + } + } + } + } + } + if (signOutTimeBean != null) { + String signdate = Util.null2String(signOutTimeBean.getSigndate()); + String signtime = Util.null2String(signOutTimeBean.getSigntime()); + + if (lastWorkTime.length() > 0 && signtime.length() > 0) { + if (signtime.length() == 5) { + signtime += ":00"; + } + if (lastWorkTime.length() == 5) { + lastWorkTime += ":00"; + } + String tmpsigndatetime = signdate + " " + signtime; + String tmpworkdatetime = splitDate + " " + lastWorkTime; + if (isEndTimeAcross) { + tmpworkdatetime = nextday + " " + lastWorkTime; + } + if (tmpsigndatetime.compareTo(tmpworkdatetime) > 0) { + KQTaskBean kqTaskBean = new KQTaskBean(); + kqTaskBean.setResourceId(resourceid); + kqTaskBean.setTaskDate(splitDate); + kqTaskBean.setLastWorkTime(lastWorkTime); + kqTaskBean.setTaskSignTime(signtime); + if (isEndTimeAcross) { + kqTaskBean.setSignDate(nextday); + } else { + kqTaskBean.setSignDate(splitDate); + } + kqTaskBean.setSignEndDate(signdate); + kqTaskBean.setTimesource("after"); + if (!tasks.contains(kqTaskBean)) { + tasks.add(kqTaskBean); + } + } + } else { + kqLog.info("overTime4Work:lastWorkTime is null :" + lastWorkTime + ":signtime is null:" + signtime); + } + } + } + } + + /** + * 针对非工作日推送加班数据 + * + * @param splitDate + * @param pre_workTime 前一天是工作日,前一天工作日最后下班时间跨天了会影响到今天开始打卡时间 + * @param resourceid + * @param tasks + * @param next_workTime 后一天是工作日,后一天的最早上班时间跨天了,会影响到今天的结束打卡时间 + * @param workTimeStartMap + * @param pre_splitDate + */ + public static void overTime4NonWork(String splitDate, String pre_workTime, String resourceid, + List tasks, String next_workTime, + Map workTimeStartMap, String pre_splitDate) { + + String signInTime4Out = ""; + String signTime = ""; + String bengintime = "00:00"; + String endtime = "23:59"; + String signInDateTime = splitDate + " " + bengintime + ":00"; + if (pre_workTime.length() > 0) { + signInDateTime = pre_workTime; + } + String signOutDateTime = splitDate + " " + endtime + ":59"; + if (next_workTime.length() > 0) { + signOutDateTime = next_workTime; + } + String signDateTimeSql = ""; + String buildSql = KQSignUtil.buildSignSql(signInDateTime, signOutDateTime); + if (buildSql.length() > 0) { + signDateTimeSql += buildSql; + } + KQScheduleSignBiz kqScheduleSignBiz = new KQScheduleSignBiz.KQScheduleSignParamBuilder().resourceidParam(resourceid). + signDateTimeSqlParam(signDateTimeSql).signDateParam(splitDate).build(); + Map signMap = kqScheduleSignBiz.getScheduleSignInfo(); + if (signMap != null && !signMap.isEmpty()) { + KQHrmScheduleSign signInTimeBean = signMap.get("signin"); + KQHrmScheduleSign signOutTimeBean = signMap.get("signout"); + if (signInTimeBean != null) { + signInTime4Out = Util.null2String(signInTimeBean.getSigntime()); + } + if (signOutTimeBean != null) { + signTime = Util.null2String(signOutTimeBean.getSigntime()); + } + } + + String pre_bengintime = Util.null2String(workTimeStartMap.get("pre_workbengintime")); + if (pre_bengintime.length() > 0) { + pre_bengintime = pre_bengintime + ":00"; + if (pre_bengintime.compareTo(signInTime4Out) > 0) { + //非工作日加班的话,签退数据都需要去搞一遍调休 + if (pre_bengintime.length() > 0 && signInTime4Out.length() > 0) { + KQTaskBean kqTaskBean = new KQTaskBean(); + kqTaskBean.setResourceId(resourceid); + kqTaskBean.setTaskDate(pre_splitDate); + kqTaskBean.setLastWorkTime(signInTime4Out); + kqTaskBean.setTaskSignTime(pre_bengintime); + kqTaskBean.setSignDate(splitDate); + kqTaskBean.setSignEndDate(splitDate); + kqTaskBean.setTimesource("before"); + if (!tasks.contains(kqTaskBean)) { + tasks.add(kqTaskBean); + } + } else { + kqLog.info("overTime4NonWork:pre_bengintime is null :" + pre_bengintime + ":signInTime4Out is null:" + signInTime4Out); + } + if (pre_bengintime.length() > 0 && signTime.length() > 0) { + //TODO pre_bengintime signTime 需要比较一下大小 + if (signTime.compareTo(pre_bengintime) > -1) { + KQTaskBean kqTaskBean = new KQTaskBean(); + kqTaskBean.setResourceId(resourceid); + kqTaskBean.setTaskDate(splitDate); + kqTaskBean.setSignDate(splitDate); + kqTaskBean.setSignEndDate(splitDate); + //对于非工作时段,签到就是他的最后一次下班时间 + kqTaskBean.setSignInTime4Out(pre_bengintime); + kqTaskBean.setTaskSignTime(signTime); + kqTaskBean.setTimesource("after"); + if (!tasks.contains(kqTaskBean)) { + tasks.add(kqTaskBean); + } + } + } else { + kqLog.info("overTime4NonWork:pre_bengintime is null :" + pre_bengintime + ":signTime is null:" + signTime); + } + + } else { + //非工作日加班的话,签退数据都需要去搞一遍调休 + if (signInTime4Out.length() > 0 && signTime.length() > 0) { + KQTaskBean kqTaskBean = new KQTaskBean(); + kqTaskBean.setResourceId(resourceid); + kqTaskBean.setTaskDate(splitDate); + kqTaskBean.setSignDate(splitDate); + kqTaskBean.setSignEndDate(splitDate); + //对于非工作时段,签到就是他的最后一次下班时间 + kqTaskBean.setSignInTime4Out(signInTime4Out); + kqTaskBean.setTimesource("after"); + kqTaskBean.setTaskSignTime(signTime); + if (!tasks.contains(kqTaskBean)) { + tasks.add(kqTaskBean); + } + } else { + kqLog.info("overTime4NonWork:signInTime4Out is null :" + signInTime4Out + ":signTime is null:" + signTime); + } + } + } else { + //非工作日加班的话,签退数据都需要去搞一遍调休 + if (signInTime4Out.length() > 0 && signTime.length() > 0) { + KQTaskBean kqTaskBean = new KQTaskBean(); + kqTaskBean.setResourceId(resourceid); + kqTaskBean.setTaskDate(splitDate); + kqTaskBean.setSignDate(splitDate); + kqTaskBean.setSignEndDate(splitDate); + //对于非工作时段,签到就是他的最后一次下班时间 + kqTaskBean.setSignInTime4Out(signInTime4Out); + kqTaskBean.setTaskSignTime(signTime); + kqTaskBean.setTimesource("after"); + if (!tasks.contains(kqTaskBean)) { + tasks.add(kqTaskBean); + } + } else { + kqLog.info("overTime4NonWork:signInTime4Out is null :" + signInTime4Out + ":signTime is null:" + signTime); + } + } + + } + +}