package com.engine.kq.biz; import com.engine.kq.biz.chain.shiftinfo.ShiftInfoBean; import com.engine.kq.entity.KQOvertimeRulesDetailEntity; import com.engine.kq.log.KQLog; import com.engine.kq.util.KQDurationCalculatorUtil; import com.engine.kq.wfset.bean.OvertimeBalanceTimeBean; import com.engine.kq.wfset.bean.SplitBean; import com.engine.kq.wfset.util.KQFlowUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import java.io.PrintWriter; import java.io.StringWriter; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.List; import java.util.Map; import org.springframework.beans.BeanUtils; import weaver.general.Util; /** * 加班流程 非工作时长计算 重新搞一把 * 现在是根据归属来拆分流程 */ public class KQOverTimeFlowBiz { private KQLog kqLog = new KQLog(); /** * 之前的加班拆分是根据每一天进行拆分的,但是我们是有个默认归属的,就是上班前是属于前一天的,再加上这次标准改造,加了临界点, * 加班的拆分改造一下,改成和请假拆分一样,根据归属区间来拆分 * 未设置加班归属的逻辑是 * 工作日A-工作日B ,从工作日A的上班时间往后加24小时,都算工作日A的加班区间 * 工作日A-非工作日,从工作日A的上班时间往后加24小时,都算工作日A的加班区间 * 非工作日-工作日A,从非工作日的0点到工作日A的上班前,都属于非工作日的区间 * * 计算加班逻辑很特殊, * 需要知道昨日,今日和明日的类型,是工作日还是非工作日 * @param splitBean * @param splitBeans */ public void getSplitDurationBean_new(SplitBean splitBean,List splitBeans) { try{ long a = System.currentTimeMillis(); double oneDayHour = KQFlowUtil.getOneDayHour(splitBean.getDurationTypeEnum(),""); int workmins = (int)(oneDayHour * 60); String resourceid = splitBean.getResourceId(); String fromDate = splitBean.getFromdatedb(); String toDate = splitBean.getTodatedb(); String overtime_type = splitBean.getOvertime_type(); 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(); KQOvertimeRulesBiz kqOvertimeRulesBiz = new KQOvertimeRulesBiz(); KQOverTimeRuleCalBiz kqOverTimeRuleCalBiz = new KQOverTimeRuleCalBiz(); Map changeTypeMap = Maps.newHashMap(); Map overRulesDetailMap = Maps.newHashMap(); Map> restTimeMap = Maps.newHashMap(); Map computingModeMap = Maps.newHashMap(); kqOverTimeRuleCalBiz.getOverTimeDataMap(resourceid, fromDate, toDate, dateFormatter,changeTypeMap,overRulesDetailMap,restTimeMap,computingModeMap); if(overRulesDetailMap.isEmpty()){ return; } String fromTime = splitBean.getFromtimedb(); String toTime = splitBean.getTotimedb(); long betweenDays = localToDate.toEpochDay() - preFromDate.toEpochDay(); //默认是从加班开始日期的前一天开始计算 需要特殊处理的就三个情况,i=0的时候,i=1的时候就是加班流程开始日期那一天,i=最后一天就是加班流程结束日期那一天 for (int i = 0; i <= betweenDays; i++) { SplitBean overSplitBean = new SplitBean(); //然后把bean重新赋值下,根据拆分后的时间 BeanUtils.copyProperties(splitBean, overSplitBean); //从加班流程开始的前一天开始算归属 LocalDate curLocalDate = preFromDate.plusDays(i); String splitDate = curLocalDate.format(dateFormatter); String preSplitDate = LocalDate.parse(splitDate).minusDays(1).format(dateFormatter); LocalDate nextLocalDate = curLocalDate.plusDays(1); String nextSplitDate = nextLocalDate.format(dateFormatter); String change_key = splitDate+"_"+resourceid; String pre_change_key = preSplitDate+"_"+resourceid; String next_change_key = nextSplitDate+"_"+resourceid; int changeType = Util.getIntValue(""+changeTypeMap.get(change_key),-1); int preChangeType = Util.getIntValue(""+changeTypeMap.get(pre_change_key),-1); int next_changeType = Util.getIntValue(""+changeTypeMap.get(next_change_key),-1); boolean shouldAcross = false; String changeType_key = splitDate+"_"+changeType; String preChangeType_key = preSplitDate+"_"+preChangeType; String nextChangeType_key = nextSplitDate+"_"+next_changeType; if(!computingModeMap.containsKey(changeType_key)){ continue; } int computingMode = computingModeMap.get(changeType_key); if(computingMode == 3){ //如果是纯打卡为主的不生成加班 continue; } int[] initArrays = kqTimesArrayComInfo.getInitArr(); //当前日期的加班分割点 分割点都是次日的 String overtime_cut_point = ""; int before_startTime = 0; int startTime = 0; int curMins = 0 ; //排除休息类型 int restTimeType = -1; String next_beginwork_time = ""; String cur_beginwork_time = ""; String serialid = ""; //需要知道明日的类型:如果今天是工作日的话,那么今天的加班临界点可能和明日的上班时间冲突,需要知道明日的上班时间进行比较, // 如果今天是休息日,那么明天如果是工作日的话,默认规则下,明天的上班前都是属于今天的加班区间 if(next_changeType == 2){ ShiftInfoBean next_shiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, nextSplitDate, false); if(next_shiftInfoBean != null){ List workLongTimeIndex = next_shiftInfoBean.getWorkLongTimeIndex(); List real_workLongTimeIndex = Lists.newArrayList(); get_real_workLongTimeIndex(workLongTimeIndex,real_workLongTimeIndex,next_shiftInfoBean,kqTimesArrayComInfo,splitBean); if(real_workLongTimeIndex != null && !real_workLongTimeIndex.isEmpty()){ next_beginwork_time = kqTimesArrayComInfo.getTimesByArrayindex(real_workLongTimeIndex.get(0)[0]); } } } if(changeType == 2){ ShiftInfoBean cur_shiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, splitDate, false); if(cur_shiftInfoBean != null){ List workLongTimeIndex = cur_shiftInfoBean.getWorkLongTimeIndex(); List real_workLongTimeIndex = Lists.newArrayList(); get_real_workLongTimeIndex(workLongTimeIndex,real_workLongTimeIndex,cur_shiftInfoBean,kqTimesArrayComInfo,splitBean); if(real_workLongTimeIndex != null && !real_workLongTimeIndex.isEmpty()){ cur_beginwork_time = kqTimesArrayComInfo.getTimesByArrayindex(real_workLongTimeIndex.get(0)[0]); } } } boolean needSplitByTime = false; // 按照加班时长转调休的 时长设置 List timepointList = null; List overtimeBalanceTimeBeans = Lists.newArrayList(); KQOvertimeRulesDetailEntity curKqOvertimeRulesDetailEntity = overRulesDetailMap.get(changeType_key); if(curKqOvertimeRulesDetailEntity != null){ int has_cut_point = curKqOvertimeRulesDetailEntity.getHas_cut_point(); before_startTime = curKqOvertimeRulesDetailEntity.getBefore_startTime(); int overtimeEnable = curKqOvertimeRulesDetailEntity.getOvertimeEnable(); if(overtimeEnable != 1){ continue; } if(has_cut_point != 1){ before_startTime = -1; } startTime = curKqOvertimeRulesDetailEntity.getStartTime(); restTimeType = curKqOvertimeRulesDetailEntity.getRestTimeType(); int paidLeaveEnable = kqOverTimeRuleCalBiz.getPaidLeaveEnable(curKqOvertimeRulesDetailEntity,overtime_type); needSplitByTime = kqOverTimeRuleCalBiz.getNeedSplitByTime(curKqOvertimeRulesDetailEntity,paidLeaveEnable); if(needSplitByTime){ int ruleDetailid = curKqOvertimeRulesDetailEntity.getId(); Map> balanceTimethDetailMap = kqOvertimeRulesBiz.getBalanceTimeDetailMap(ruleDetailid); if(balanceTimethDetailMap != null && !balanceTimethDetailMap.isEmpty()){ timepointList = balanceTimethDetailMap.get("timepointList"); } } if(has_cut_point == 0){ if(changeType == 2){ overtime_cut_point = cur_beginwork_time; }else { if(next_beginwork_time.length() > 0){ overtime_cut_point = next_beginwork_time; } } }else{ overtime_cut_point = curKqOvertimeRulesDetailEntity.getCut_point(); if(next_beginwork_time.length() > 0){ int next_beginwork_time_index = kqTimesArrayComInfo.getArrayindexByTimes(next_beginwork_time); int overtime_cut_point_index = kqTimesArrayComInfo.getArrayindexByTimes(overtime_cut_point); if(overtime_cut_point_index > next_beginwork_time_index){ overtime_cut_point = next_beginwork_time; } } } if(overtime_cut_point.length() == 0){ overtime_cut_point = "00:00"; } }else{ continue; } int fromTime_index = 0; int toTime_index = 0; if(i == 0){ //i=0就是加班开始日期的前一天,只有当加班临界点超过了加班流程开始时间的话,i=0才会有可能计算出时长 if(overtime_cut_point.compareTo(fromTime) > 0){ fromTime_index = kqTimesArrayComInfo.getArrayindexByTimes(kqTimesArrayComInfo.turn24to48Time(fromTime)); toTime_index = kqTimesArrayComInfo.getArrayindexByTimes(kqTimesArrayComInfo.turn24to48Time(overtime_cut_point)); if(fromDate.equalsIgnoreCase(toDate)){ //如果开始日期和结束日期是同一天,还需要比较流程的结束时间和归属点的大小 int oriTotime_index = kqTimesArrayComInfo.getArrayindexByTimes(kqTimesArrayComInfo.turn24to48Time(toTime)); if(toTime_index > oriTotime_index){ toTime_index = oriTotime_index; } } Arrays.fill(initArrays, fromTime_index, toTime_index, 0); // 1-节假日、2-工作日、3-休息日 if(changeType == 1){ handle_changeType_1(initArrays,overRulesDetailMap,nextChangeType_key,next_changeType,next_beginwork_time); }else if(changeType == 2){ boolean isok = handle_changeType_2(initArrays, resourceid, splitDate, before_startTime, startTime, fromTime_index,kqTimesArrayComInfo,splitBean, toTime_index); serialid = splitBean.getSerialid(); if(!isok){ continue; } }else if(changeType == 3){ handle_changeType_3(initArrays,overRulesDetailMap,nextChangeType_key,next_changeType,next_beginwork_time); } if(restTimeType == 1){ //如果排除设置的休息时间 handle_resttime(restTimeMap,changeType_key,kqTimesArrayComInfo,shouldAcross,initArrays); } curMins = kqTimesArrayComInfo.getCnt(initArrays, fromTime_index,toTime_index,0); if(restTimeType == 2){ //如果排除休息时间是扣除时长 curMins = handle_restlength(curMins,restTimeMap,changeType_key); } }else{ continue; } }else{ //除了i=0的情况,其他的每一天都是要获取一下昨日的临界点的 String pre_overtime_cut_point = get_pre_overtime_cut_point(overRulesDetailMap,preChangeType_key,resourceid,preSplitDate,splitDate,preChangeType,kqTimesArrayComInfo,splitBean,changeType); if(changeType == 2){ //如果今天是工作日,昨日的打卡归属会受到今日的上班前开始加班分钟数的影响 int cur_beginwork_time_index = kqTimesArrayComInfo.getArrayindexByTimes(cur_beginwork_time); if(before_startTime > -1){ int pre_overtime_cut_point_index = kqTimesArrayComInfo.getArrayindexByTimes(pre_overtime_cut_point); int before_cur_beginwork_time_index = cur_beginwork_time_index - before_startTime; } } //计算区间加班开始日期和加班结束日期这两天都是要特殊处理的 fromTime_index = kqTimesArrayComInfo.getArrayindexByTimes(pre_overtime_cut_point); if(i == 1){ if(fromTime.compareTo(pre_overtime_cut_point) > 0){ fromTime_index = kqTimesArrayComInfo.getArrayindexByTimes(fromTime); } } if(i == betweenDays){ toTime_index = kqTimesArrayComInfo.getArrayindexByTimes(toTime); }else{ toTime_index = kqTimesArrayComInfo.turn24to48TimeIndex(kqTimesArrayComInfo.getArrayindexByTimes(overtime_cut_point)); if(next_beginwork_time.length() > 0){ int overtime_cut_point_index = kqTimesArrayComInfo.getArrayindexByTimes(overtime_cut_point); int next_beginwork_time_index = kqTimesArrayComInfo.getArrayindexByTimes(next_beginwork_time); //如果临界点都已经超过第二天上班的开始时间了,要相应的缩短成第二天上班时间 if(overtime_cut_point_index > next_beginwork_time_index){ toTime_index = kqTimesArrayComInfo.turn24to48TimeIndex(next_beginwork_time_index); } } if(i == betweenDays-1){ int ori_totime_index = kqTimesArrayComInfo.turn48to24TimeIndex(toTime_index); int last_toTime_index = kqTimesArrayComInfo.getArrayindexByTimes(toTime); if(ori_totime_index > last_toTime_index){ toTime_index = kqTimesArrayComInfo.turn24to48TimeIndex(last_toTime_index); } } } System.out.println(i+":betweenDays:"+betweenDays+":fromTime_index:"+fromTime_index+":toTime_index:"+toTime_index+":changeType:"+changeType); if(fromTime_index > toTime_index){ continue; } Arrays.fill(initArrays, fromTime_index, toTime_index, 0); if(changeType == 1){ handle_changeType_1(initArrays, overRulesDetailMap, nextChangeType_key, next_changeType, next_beginwork_time); }else if(changeType == 2){ serialid = splitBean.getSerialid(); boolean isok = handle_changeType_2(initArrays, resourceid, splitDate, before_startTime, startTime, fromTime_index, kqTimesArrayComInfo, splitBean, toTime_index); if(!isok){ continue; } }else if(changeType == 3){ handle_changeType_3(initArrays, overRulesDetailMap, nextChangeType_key, next_changeType, overtime_cut_point); } if(restTimeType == 1) { //如果排除设置的休息时间 handle_resttime(restTimeMap, changeType_key, kqTimesArrayComInfo, shouldAcross,initArrays); } curMins = kqTimesArrayComInfo.getCnt(initArrays, fromTime_index,toTime_index,0); if(restTimeType == 2){ //如果排除休息时间是扣除时长 curMins = handle_restlength(curMins,restTimeMap,changeType_key); } } int minimumUnit = curKqOvertimeRulesDetailEntity.getMinimumLen(); if(curMins < minimumUnit){ continue; } if(needSplitByTime){ kqOverTimeRuleCalBiz.get_overtimeBalanceTimeBeans(timepointList,overtimeBalanceTimeBeans,kqTimesArrayComInfo,initArrays,toTime_index,fromTime_index,0); if(overtimeBalanceTimeBeans != null && !overtimeBalanceTimeBeans.isEmpty()){ String bean_cross_fromtime = kqTimesArrayComInfo.getTimesByArrayindex(fromTime_index); String bean_cross_totime = kqTimesArrayComInfo.getTimesByArrayindex(toTime_index); for(int timeIndex = 0 ; timeIndex < overtimeBalanceTimeBeans.size() ;timeIndex++) { OvertimeBalanceTimeBean overtimeBalanceTimeBean = overtimeBalanceTimeBeans.get(timeIndex); String timePointStart = overtimeBalanceTimeBean.getTimepoint_start(); String timePointEnd = overtimeBalanceTimeBean.getTimepoint_end(); boolean isNeedTX = overtimeBalanceTimeBean.isNeedTX(); int timePointStart_index = kqTimesArrayComInfo.getArrayindexByTimes(timePointStart); int timePointEnd_index = kqTimesArrayComInfo.getArrayindexByTimes(timePointEnd); if(timePointStart_index > fromTime_index){ bean_cross_fromtime = kqTimesArrayComInfo.getTimesByArrayindex(timePointStart_index); }else{ bean_cross_fromtime = kqTimesArrayComInfo.getTimesByArrayindex(fromTime_index); } if(timePointEnd_index < toTime_index){ bean_cross_totime = kqTimesArrayComInfo.getTimesByArrayindex(timePointEnd_index); }else{ bean_cross_totime = kqTimesArrayComInfo.getTimesByArrayindex(toTime_index); } int timepoint_mins = overtimeBalanceTimeBean.getTimepoint_mins(); if(isNeedTX){ if(timepoint_mins > 0){ overSplitBean = new SplitBean(); //然后把bean重新赋值下,根据拆分后的时间 BeanUtils.copyProperties(splitBean, overSplitBean); overSplitBean.setChangeType(changeType); overSplitBean.setPreChangeType(preChangeType); overSplitBean.setOneDayHour(oneDayHour); overSplitBean.setWorkmins(workmins); overSplitBean.setComputingMode(computingMode+""); overSplitBean.setChangeType(changeType); overSplitBean.setFromDate(splitDate); overSplitBean.setFromTime(bean_cross_fromtime); overSplitBean.setToDate(splitDate); overSplitBean.setToTime(bean_cross_totime); overSplitBean.setBelongDate(splitDate); overSplitBean.setD_Mins(timepoint_mins); overSplitBean.setOvertimeBalanceTimeBeans(overtimeBalanceTimeBeans); overSplitBean.setSerialid(serialid); getDurationByRule(overSplitBean); splitBeans.add(overSplitBean); } } } } }else{ curMins = (int) kqOverTimeRuleCalBiz.getD_MinsByUnit(curMins); overSplitBean.setChangeType(changeType); overSplitBean.setPreChangeType(preChangeType); overSplitBean.setOneDayHour(oneDayHour); overSplitBean.setWorkmins(workmins); overSplitBean.setComputingMode(computingMode+""); overSplitBean.setChangeType(changeType); overSplitBean.setFromDate(splitDate); overSplitBean.setFromTime(kqTimesArrayComInfo.getTimesByArrayindex(fromTime_index)); overSplitBean.setToDate(splitDate); overSplitBean.setToTime(kqTimesArrayComInfo.getTimesByArrayindex(toTime_index)); overSplitBean.setBelongDate(splitDate); overSplitBean.setD_Mins(curMins); overSplitBean.setOvertimeBalanceTimeBeans(overtimeBalanceTimeBeans); overSplitBean.setSerialid(serialid); getDurationByRule(overSplitBean); splitBeans.add(overSplitBean); } } long b = System.currentTimeMillis(); System.out.println("::"+(b-a)); }catch (Exception e){ StringWriter errorsWriter = new StringWriter(); e.printStackTrace(new PrintWriter(errorsWriter)); kqLog.info(errorsWriter.toString()); } } /** * 被个性化设置处理下 得到实际的上下班时间 * @param workLongTimeIndex * @param real_workLongTimeIndex * @param shiftInfoBean * @param kqTimesArrayComInfo * @param splitBean */ public void get_real_workLongTimeIndex(List workLongTimeIndex, List real_workLongTimeIndex, ShiftInfoBean shiftInfoBean, KQTimesArrayComInfo kqTimesArrayComInfo, SplitBean splitBean) { //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); } if(real_workLongTimeIndex.size() == 1){ //个性化设置只支持一次打卡的 KQShiftRuleInfoBiz kqShiftRuleInfoBiz = new KQShiftRuleInfoBiz(); kqShiftRuleInfoBiz.rest_workLongTimeIndex(shiftInfoBean,splitBean,real_workLongTimeIndex,kqTimesArrayComInfo,null); } } /** * 获取一下昨日的临界点 * @param overRulesDetailMap * @param preChangeType_key * @param resourceid * @param preSplitDate * @param splitDate * @param preChangeType * @param kqTimesArrayComInfo * @param splitBean * @param changeType * @return */ private String get_pre_overtime_cut_point( Map overRulesDetailMap, String preChangeType_key, String resourceid, String preSplitDate, String splitDate, int preChangeType, KQTimesArrayComInfo kqTimesArrayComInfo, SplitBean splitBean, int changeType) { String pre_overtime_cut_point = ""; KQOvertimeRulesDetailEntity preKqOvertimeRulesDetailEntity = overRulesDetailMap.get(preChangeType_key); if(preKqOvertimeRulesDetailEntity != null){ int has_cut_point = preKqOvertimeRulesDetailEntity.getHas_cut_point(); if(has_cut_point == 0){ if(preChangeType == 2){ ShiftInfoBean pre_shiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, preSplitDate, false); if(pre_shiftInfoBean != null){ List workLongTimeIndex = pre_shiftInfoBean.getWorkLongTimeIndex(); List real_workLongTimeIndex = Lists.newArrayList(); get_real_workLongTimeIndex(workLongTimeIndex,real_workLongTimeIndex,pre_shiftInfoBean,kqTimesArrayComInfo,splitBean); if(real_workLongTimeIndex != null && !real_workLongTimeIndex.isEmpty()){ pre_overtime_cut_point = kqTimesArrayComInfo.getTimesByArrayindex(real_workLongTimeIndex.get(0)[0]); } } }else { String next_beginwork_time = ""; if(changeType == 2){ ShiftInfoBean next_shiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, splitDate, false); if(next_shiftInfoBean != null){ List workLongTimeIndex = next_shiftInfoBean.getWorkLongTimeIndex(); List real_workLongTimeIndex = Lists.newArrayList(); get_real_workLongTimeIndex(workLongTimeIndex,real_workLongTimeIndex,next_shiftInfoBean,kqTimesArrayComInfo,splitBean); if(real_workLongTimeIndex != null && !real_workLongTimeIndex.isEmpty()){ next_beginwork_time = kqTimesArrayComInfo.getTimesByArrayindex(real_workLongTimeIndex.get(0)[0]); } } } if(next_beginwork_time.length() > 0){ pre_overtime_cut_point = next_beginwork_time; } } }else{ pre_overtime_cut_point = preKqOvertimeRulesDetailEntity.getCut_point(); } if(pre_overtime_cut_point.length() == 0){ pre_overtime_cut_point = "00:00"; } } return pre_overtime_cut_point; } /** * 处理节假日的加班 * @param initArrays * @param overRulesDetailMap * @param nextChangeType_key * @param next_changeType * @param next_beginwork_time */ public void handle_changeType_1(int[] initArrays, Map overRulesDetailMap, String nextChangeType_key, int next_changeType, String next_beginwork_time){ KQOvertimeRulesDetailEntity nextKqOvertimeRulesDetailEntity = overRulesDetailMap.get(nextChangeType_key); // if(nextKqOvertimeRulesDetailEntity != null){ // if(next_changeType == 2){ // //如果明日是工作日 工作日如果设置了上班前分钟,会导致加班归属被设置的分钟数给切断,上班前某些部分属于今天不属于昨日 // int overtimeEnable = nextKqOvertimeRulesDetailEntity.getOvertimeEnable(); // if(overtimeEnable == 1){ // KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); // int before_startTime = nextKqOvertimeRulesDetailEntity.getBefore_startTime(); // int has_cut_point = nextKqOvertimeRulesDetailEntity.getHas_cut_point(); // if(has_cut_point != 1){ // before_startTime = -1; // } // int next_beginwork_time_index = kqTimesArrayComInfo.getArrayindexByTimes(next_beginwork_time); // if(before_startTime > -1){ // int before_next_beginwork_time_index = next_beginwork_time_index - before_startTime; // if(before_next_beginwork_time_index > 0 && before_next_beginwork_time_index < next_beginwork_time_index){ // before_next_beginwork_time_index = kqTimesArrayComInfo.turn24to48TimeIndex(before_next_beginwork_time_index); // next_beginwork_time_index = kqTimesArrayComInfo.turn24to48TimeIndex(next_beginwork_time_index); // Arrays.fill(initArrays, before_next_beginwork_time_index,next_beginwork_time_index,-1); // } // } // } // } // } } /** * 排除休息时间 现在工作日,节假日和休息日都可以设置排除休息时间 * @param restTimeMap * @param changeType_key * @param kqTimesArrayComInfo * @param shouldAcross * @param initArrays */ public void handle_resttime(Map> restTimeMap, String changeType_key, KQTimesArrayComInfo kqTimesArrayComInfo, boolean shouldAcross, int[] initArrays) { if(restTimeMap.containsKey(changeType_key)){ List restTimeList = restTimeMap.get(changeType_key); //再把休息时间填充上去 if(!restTimeList.isEmpty()){ for(int k =0 ; k < restTimeList.size() ; k++){ String[] restTimes = restTimeList.get(k); if(restTimes.length == 2){ int restStart = kqTimesArrayComInfo.getArrayindexByTimes(restTimes[0]); int restEnd = kqTimesArrayComInfo.getArrayindexByTimes(restTimes[1]); if(shouldAcross && restEnd == 1439){ //针对跨天的休息时段单独处理排除掉23:59-00:00的时间 restEnd = 1440; } Arrays.fill(initArrays, restStart, restEnd, 1); } } } } } /** * 排除休息时长 根据加班时长排除指定时长 * @param curMins * @param restTimeMap * @param changeType_key * @return */ public int handle_restlength(int curMins, Map> restTimeMap, String changeType_key) { if(restTimeMap.containsKey(changeType_key)) { List restTimeList = restTimeMap.get(changeType_key); //再把休息时间填充上去 if (!restTimeList.isEmpty()) { for(int k = restTimeList.size()-1 ; k >= 0 ; k--) { String[] restTimes = restTimeList.get(k); if (restTimes.length == 2) { //overlength 是满多少小时 cutlength是减去多少小时 double overlength = Util.getDoubleValue(restTimes[0],-1); double cutlength = Util.getDoubleValue(restTimes[1],-1); if(overlength > 0 && cutlength > 0){ double min_overlength = overlength * 60; double min_cutlength = cutlength * 60; if(curMins >= min_overlength){ curMins = (int) (curMins-min_cutlength); break; } } } } } } return curMins; } /** * 处理工作日的加班 * @param initArrays * @param resourceid * @param splitDate * @param before_startTime * @param startTime * @param fromTime_index * @param kqTimesArrayComInfo * @param splitBean * @param toTime_index * @return */ public boolean handle_changeType_2(int[] initArrays, String resourceid, String splitDate, int before_startTime, int startTime, int fromTime_index, KQTimesArrayComInfo kqTimesArrayComInfo, SplitBean splitBean, int toTime_index){ boolean isok = true; ShiftInfoBean cur_shiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, splitDate, false); if(cur_shiftInfoBean != null){ splitBean.setSerialid(cur_shiftInfoBean.getSerialid()); List workLongTimeIndex = cur_shiftInfoBean.getWorkLongTimeIndex(); List real_workLongTimeIndex = Lists.newArrayList(); get_real_workLongTimeIndex(workLongTimeIndex,real_workLongTimeIndex,cur_shiftInfoBean,kqTimesArrayComInfo,splitBean); if(real_workLongTimeIndex != null && !real_workLongTimeIndex.isEmpty()){ int all_firstworktime = 0; int all_lastworktime = 0; boolean need_middle_time = false; for(int k = 0 ; k < real_workLongTimeIndex.size() ; k++){ int workLongTimeStartIndex = real_workLongTimeIndex.get(k)[0]; int workLongTimeEndIndex = real_workLongTimeIndex.get(k)[1]; if(k == 0){ if(before_startTime > -1){ int before_workLongTimeStartIndex = workLongTimeStartIndex-before_startTime; if(before_workLongTimeStartIndex > 0){ //从前一天的加班归属点到今天的上班前开始加班点,这段时间属于两不靠。需要排除 if(fromTime_index < before_workLongTimeStartIndex){ Arrays.fill(initArrays, fromTime_index,before_workLongTimeStartIndex,-1); } } } all_firstworktime = workLongTimeStartIndex; } if(k == real_workLongTimeIndex.size()-1){ if(startTime > -1){ int after_workLongTimeEndIndex = workLongTimeEndIndex+startTime; if(workLongTimeEndIndex < after_workLongTimeEndIndex){ Arrays.fill(initArrays, workLongTimeEndIndex,after_workLongTimeEndIndex,-1); } } all_lastworktime = workLongTimeEndIndex; } if(!need_middle_time){ //目前标准加班,一天多次打卡的话是不算中间时间的,只算上班前和下班后的加班 }else{ //这个里面是可以算一天多次打卡的话是中间时间的 Arrays.fill(initArrays, workLongTimeStartIndex,workLongTimeEndIndex,1); } } if(!need_middle_time){ Arrays.fill(initArrays, all_firstworktime,all_lastworktime,1); } List restLongTimeIndex = cur_shiftInfoBean.getRestLongTimeIndex(); if(restLongTimeIndex != null && !restLongTimeIndex.isEmpty()){ for (int k = 0; k < restLongTimeIndex.size(); k++) { //休息时段填充2 Arrays.fill(initArrays, restLongTimeIndex.get(k)[0], restLongTimeIndex.get(k)[1], 2); } } }else { System.out.println("error"); isok = false; } }else { System.out.println("error"); isok = false; } return isok; } /** * 处理休息日的加班 * @param restTimeMap * @param initArrays * @param overRulesDetailMap * @param nextChangeType_key * @param next_changeType * @param next_beginwork_time */ public void handle_changeType_3(int[] initArrays, Map overRulesDetailMap, String nextChangeType_key, int next_changeType, String next_beginwork_time){ KQOvertimeRulesDetailEntity nextKqOvertimeRulesDetailEntity = overRulesDetailMap.get(nextChangeType_key); // if(nextKqOvertimeRulesDetailEntity != null){ // if(next_changeType == 2){ // //如果明日是工作日 工作日如果设置了上班前分钟,会导致加班归属被设置的分钟数给切断,上班前某些部分属于今天不属于昨日 // int overtimeEnable = nextKqOvertimeRulesDetailEntity.getOvertimeEnable(); // if(overtimeEnable == 1){ // KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo(); // int before_startTime = nextKqOvertimeRulesDetailEntity.getBefore_startTime(); // int has_cut_point = nextKqOvertimeRulesDetailEntity.getHas_cut_point(); // if(has_cut_point != 1){ // before_startTime = -1; // } // int next_beginwork_time_index = kqTimesArrayComInfo.getArrayindexByTimes(next_beginwork_time); // if(before_startTime > -1){ // int before_next_beginwork_time_index = next_beginwork_time_index - before_startTime; // if(before_next_beginwork_time_index > 0 && before_next_beginwork_time_index < next_beginwork_time_index){ // before_next_beginwork_time_index = kqTimesArrayComInfo.turn24to48TimeIndex(before_next_beginwork_time_index); // next_beginwork_time_index = kqTimesArrayComInfo.turn24to48TimeIndex(next_beginwork_time_index); // Arrays.fill(initArrays, before_next_beginwork_time_index,next_beginwork_time_index,-1); // } // } // } // } // } } public void getDurationByRule(SplitBean splitBean) { double D_Mins = splitBean.getD_Mins(); int workmins = splitBean.getWorkmins(); String durationrule = splitBean.getDurationrule(); if("3".equalsIgnoreCase(durationrule) || "5".equalsIgnoreCase(durationrule) || "6".equalsIgnoreCase(durationrule)){ double d_hour = D_Mins/60.0; splitBean.setDuration(KQDurationCalculatorUtil.getDurationRound5(""+d_hour)); }else if("1".equalsIgnoreCase(durationrule)){ double d_day = D_Mins/workmins; splitBean.setDuration(KQDurationCalculatorUtil.getDurationRound5(""+d_day)); } } }