|
|
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<SplitBean> 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<String,Integer> changeTypeMap = Maps.newHashMap();
|
|
|
Map<String, KQOvertimeRulesDetailEntity> overRulesDetailMap = Maps.newHashMap();
|
|
|
Map<String,List<String[]>> restTimeMap = Maps.newHashMap();
|
|
|
Map<String,Integer> 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<int[]> workLongTimeIndex = next_shiftInfoBean.getWorkLongTimeIndex();
|
|
|
List<int[]> 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<int[]> workLongTimeIndex = cur_shiftInfoBean.getWorkLongTimeIndex();
|
|
|
List<int[]> 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<String> timepointList = null;
|
|
|
List<OvertimeBalanceTimeBean> 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<String,List<String>> 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<int[]> workLongTimeIndex,
|
|
|
List<int[]> 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<String, KQOvertimeRulesDetailEntity> 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<int[]> workLongTimeIndex = pre_shiftInfoBean.getWorkLongTimeIndex();
|
|
|
List<int[]> 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<int[]> workLongTimeIndex = next_shiftInfoBean.getWorkLongTimeIndex();
|
|
|
List<int[]> 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<String, KQOvertimeRulesDetailEntity> 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<String, List<String[]>> restTimeMap, String changeType_key, KQTimesArrayComInfo kqTimesArrayComInfo, boolean shouldAcross, int[] initArrays) {
|
|
|
|
|
|
if(restTimeMap.containsKey(changeType_key)){
|
|
|
List<String[]> 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<String, List<String[]>> restTimeMap, String changeType_key) {
|
|
|
if(restTimeMap.containsKey(changeType_key)) {
|
|
|
List<String[]> 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<int[]> workLongTimeIndex = cur_shiftInfoBean.getWorkLongTimeIndex();
|
|
|
List<int[]> 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<int[]> 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<String, KQOvertimeRulesDetailEntity> 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));
|
|
|
}
|
|
|
}
|
|
|
}
|