2024-07-31 16:04:24 +08:00
package com.engine.kq.biz ;
import cn.hutool.core.convert.Convert ;
import com.alibaba.fastjson.JSON ;
import com.alibaba.fastjson.JSONObject ;
import com.engine.jc.kq.AbnormalOvertimeRemind ;
2025-02-06 10:57:38 +08:00
import com.engine.kq.bean.KQRepeatBean ;
2024-07-31 16:04:24 +08:00
import com.engine.kq.biz.chain.shiftinfo.ShiftInfoBean ;
import com.engine.kq.entity.KQShiftRuleEntity ;
import com.engine.kq.entity.TimeScopeEntity ;
import com.engine.kq.entity.WorkTimeEntity ;
import com.engine.kq.enums.FlowReportTypeEnum ;
2025-02-06 10:57:38 +08:00
import com.engine.kq.jucailin.genid.IdGenerator ;
2024-07-31 16:04:24 +08:00
import com.engine.kq.log.KQLog ;
2025-02-06 10:57:38 +08:00
import com.engine.kq.util.KQLockAttendaUtil ;
2024-07-31 16:04:24 +08:00
import com.google.common.collect.Lists ;
import com.google.common.collect.Maps ;
import com.googlecode.aviator.AviatorEvaluator ;
import com.googlecode.aviator.Expression ;
2025-02-06 10:57:38 +08:00
import org.apache.commons.collections.CollectionUtils ;
2024-07-31 16:04:24 +08:00
import org.apache.commons.lang3.StringUtils ;
import weaver.common.DateUtil ;
import weaver.conn.BatchRecordSet ;
import weaver.conn.RecordSet ;
2025-02-06 10:57:38 +08:00
import weaver.file.Prop ;
2024-07-31 16:04:24 +08:00
import weaver.general.BaseBean ;
import weaver.general.InitServer ;
import weaver.general.Util ;
2025-02-06 10:57:38 +08:00
import java.io.PrintWriter ;
import java.io.StringWriter ;
import java.sql.Timestamp ;
2024-07-31 16:04:24 +08:00
import java.util.* ;
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
/ * *
* 考勤数据格式化
* /
public class KQFormatData extends BaseBean {
private String today = DateUtil . getCurrentDate ( ) ;
private KQLog kqLog = new KQLog ( ) ;
private boolean writeLog = false ;
private LinkedHashMap < String , Object > logInfo = new LinkedHashMap < > ( ) ;
2025-02-06 10:57:38 +08:00
private static final String LOCK_DEGREE = Util . null2String ( Prop . getPropValue ( " kqLockAttenda " , " LOCK_DEGREE " ) ) ;
public Map < String , Object > formatKqDateByLock ( String userId , String kqDate , int formatType ) {
Map < String , Object > resultMap = new HashMap < > ( ) ;
//-1: 其他; 11:右键重新计算考勤数据; 12: 考勤自动和手动同步;13:钉钉同步或者导入; 14:云桥考勤同步 15: 考勤导入;16:排班更新
//17:考勤流程;18testkq.jsp直接触发的;19:考勤设置升级;20: 计划任务执行。
//①在途的考勤流程可以正常提交归档报表能统计,管理员干预归档的流程报表能统计。
//②关账不影响考勤导入打卡数据,正常的打卡数据进入报表,导入、同步。
//③其他操作报表更新控制不生效,比如重新计算考勤,自动计算考勤。
// if (LOCK_DEGREE.equals("0")&&new KQLockAttendaUtil().checkLockStatus(userId, kqDate)) {
// kqLog.info("锁定程度强控:人员考勤数据已被锁定,"+"userId:"+userId+":kqDate:"+kqDate+";formatType="+formatType);
// if(formatType==12||formatType==13||formatType==14||formatType==15||formatType==17){
// return formatKqDate(userId, kqDate);
// }
// return resultMap;
// }
//最新确认逻辑:弱控只控制流程在锁定范围内不能提交,其他都可以重新计算考勤报表。
return formatKqDate ( userId , kqDate ) ;
}
2024-07-31 16:04:24 +08:00
/ * * *
* 该方法不允许直接调用
* @param userId
* @param kqDate
* @return
* /
public Map < String , Object > formatKqDate ( String userId , String kqDate ) {
2025-02-06 10:57:38 +08:00
//考勤报表增加锁定功能:弱控
//1、考勤流程控制, 请假、出差、公出、补卡、加班、销假、考勤变更新建的流程不能提交, 在途的流程可以正常提交归档报表能统计, 管理员干预归档的流程报表能统计。
//2、关账不影响考勤导入打卡数据, 正常的打卡数据进入报表。
//3、强控就是前2点锁定日期后也不能进入报表了
2024-07-31 16:04:24 +08:00
List < List < Object > > lsParam = new ArrayList < > ( ) ;
2025-02-06 10:57:38 +08:00
boolean isKqReportHalfOpen = " 1 " . equals ( new KQSettingsComInfo ( ) . getMain_val ( " kq_report_half " ) ) ;
2024-07-31 16:04:24 +08:00
//非工作日处理
List < Object > nonlsParam = null ;
Map < String , Object > resultMap = new HashMap < > ( ) ;
BatchRecordSet bRs = new BatchRecordSet ( ) ;
KQGroupComInfo kqGroupComInfo = new KQGroupComInfo ( ) ;
RecordSet rs = new RecordSet ( ) ;
String sql = " " ;
try {
kqLog . info ( " formatKqDate in userId= " + userId + " kqDate== " + kqDate ) ;
if ( DateUtil . timeInterval ( kqDate , today ) < 0 ) { //今天之后的无需处理
kqLog . info ( " 今天之后的无需处理的数据: resourceid== " + userId + " kqdate== " + kqDate + " today== " + today ) ;
return resultMap ;
}
2025-02-06 10:57:38 +08:00
// 强控
if ( LOCK_DEGREE . equals ( " 1 " ) & & new KQLockAttendaUtil ( ) . checkLockStatus ( userId , kqDate ) ) {
kqLog . info ( " 锁定程度强控:人员考勤数据已被锁定, " + " userId: " + userId + " :kqDate: " + kqDate ) ;
return resultMap ;
}
2024-07-31 16:04:24 +08:00
String uuid = UUID . randomUUID ( ) . toString ( ) ;
KQFormatFreeData kqFormatFreeData = new KQFormatFreeData ( ) ;
KQWorkTime kqWorkTime = new KQWorkTime ( ) ;
kqWorkTime . setIsFormat ( true ) ;
String kqDateNext = DateUtil . addDate ( kqDate , 1 ) ;
KQFlowDataBiz kqFlowDataBiz = new KQFlowDataBiz . FlowDataParamBuilder ( ) . resourceidParam ( userId ) . fromDateParam ( kqDate ) . toDateParam ( kqDateNext ) . build ( ) ;
Map < String , Object > workFlowInfo = new HashMap < > ( ) ; //userid|date--工作流程
kqFlowDataBiz . getAllFlowData ( workFlowInfo , false ) ;
WorkTimeEntity workTime = kqWorkTime . getWorkTime ( userId , kqDate ) ;
kqLog . info ( " userId: " + userId + " :kqDate: " + kqDate + " :formatKqDate workTime= " + JSONObject . toJSONString ( workTime ) + " ::uuid:: " + uuid ) ;
kqLog . info ( " userId: " + userId + " :kqDate: " + kqDate + " :formatKqDate workFlowInfo= " + JSONObject . toJSONString ( workFlowInfo ) + " ::uuid:: " + uuid ) ;
if ( this . writeLog ) {
logInfo . put ( " userId " , userId ) ;
logInfo . put ( " kqDate " , kqDate ) ;
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 16253 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , workTime ) ;
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 126871 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , workFlowInfo ) ;
}
new KQFormatBiz ( ) . delFormatData ( userId , kqDate ) ;
String excludecount = Util . null2String ( kqGroupComInfo . getExcludecount ( workTime . getGroupId ( ) ) ) ; //是否参与考勤报表统计
if ( workTime . getIsExclude ( ) ) { //无需考勤人员没有异常状态
if ( ! excludecount . equals ( " 1 " ) ) {
kqLog . info ( " 无需考勤人员没有异常状态 workTime.getIsExclude()= " + workTime . getIsExclude ( ) + " excludecount== " + excludecount ) ;
return resultMap ;
}
}
if ( Util . null2String ( workTime . getGroupId ( ) ) . length ( ) = = 0 ) {
//没有考勤组不需格式化
return resultMap ;
}
2025-02-06 10:57:38 +08:00
if ( workTime = = null | | ( workTime ! = null & & workTime . getWorkMins ( ) = = 0 & & workTime . getNonWorkShift ( ) ! = 1 ) ) {
2024-07-31 16:04:24 +08:00
kqLog . info ( " workTime == null || workTime.getWorkMins() == 0 插入空记录 " ) ;
nonlsParam = new ArrayList < > ( ) ;
formatNonWork ( userId , kqDate , nonlsParam , workTime , workFlowInfo ) ;
if ( ! nonlsParam . isEmpty ( ) ) {
2025-02-06 10:57:38 +08:00
sql = " insert into kq_format_detail(resourceid,kqdate,groupid,serialnumber,signindate,signintime,signinid,signoutdate,signouttime,signoutid,leaveMins,leaveinfo,evectionMins,outMins,day_type,create_time,update_time,id,flowinfo)values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) " ;
2024-07-31 16:04:24 +08:00
rs . executeUpdate ( sql , nonlsParam ) ;
2025-02-06 10:57:38 +08:00
Long id = IdGenerator . generate ( ) ;
String baseField = " " ;
if ( " mysql " . equalsIgnoreCase ( rs . getDBType ( ) ) ) {
baseField = " sysdate(),sysdate(), " + id ;
} else if ( " oracle " . equalsIgnoreCase ( rs . getDBType ( ) ) ) {
baseField = " SYSDATE,SYSDATE, " + id ;
} else if ( " postgresql " . equalsIgnoreCase ( rs . getDBType ( ) ) ) {
baseField = " now(),now(), " + id ;
} else {
baseField = " GETDATE(),GETDATE(), " + id ;
}
2024-07-31 16:04:24 +08:00
sql = " insert into kq_format_total(resourceid,kqdate,subcompanyid,departmentid,jobtitle,groupid,serialid,workdays, " +
" workmins,attendancedays,attendancemins,signdays,signmins,belate,belatemins,gravebelate,gravebelatemins,leaveeearly,leaveearlymins, " +
2025-02-06 10:57:38 +08:00
" graveleaveearly,graveleaveearlymins,absenteeism,absenteeismmins,forgotcheck, forgotcheckMins,leaveMins,evectionMins,outMins,create_time,update_time,id) " +
2024-07-31 16:04:24 +08:00
" select a.resourceid,kqdate,b.subcompanyid1,b.departmentid,b.jobtitle,groupid,serialid, " +
" case when sum(workmins)>0 then 1 end as workdays, sum(workmins) as workmins, " +
" 0 as attendancedays, sum(attendanceMins) as attendanceMins, " +
" 0 as signdays, sum(signmins) as signmins, " +
" sum(case when belatemins> 0 then 1 else 0 end) as belate,sum(belatemins) as belatemins, " +
" sum(case when graveBeLateMins> 0 then 1 else 0 end) as graveBeLate,sum(graveBeLateMins) as graveBeLateMins, " +
" sum(case when leaveearlymins> 0 then 1 else 0 end) as leaveearly,sum(leaveearlymins) as leaveearlymins, " +
2025-02-06 10:57:38 +08:00
" sum(case when graveLeaveEarlyMins> 0 then 1 else 0 end) as graveLeaveEarly,sum(graveLeaveEarlyMins) as graveLeaveEarlyMins, " ;
// if(isKqReportHalfOpen) {
// sql+=" sum((on_absenteeismmins+off_absenteeismmins)) as absenteeism,sum(absenteeismmins) as absenteeismmins,";
// } else {
sql + = " sum(case when absenteeismmins> 0 then 1 else 0 end) as absenteeism,sum(absenteeismmins) as absenteeismmins, " ;
// }
sql + = " sum(case when forgotcheckmins> 0 then 1 else 0 end) as forgotcheck,sum(forgotcheckmins) as forgotcheckmins, " +
" sum(leaveMins) as leaveMins, sum(evectionMins) as evectionMins, sum(outMins) as outMins, " + baseField +
2024-07-31 16:04:24 +08:00
" from kq_format_detail a, hrmresource b " +
" where a.resourceid = b.id and resourceid =? and kqdate=? " +
" group by resourceid,kqdate,b.subcompanyid1,b.departmentid,b.jobtitle,groupid,serialid,workmins " ;
rs . executeUpdate ( sql , userId , kqDate ) ;
}
} else {
Map < String , Object > definedFieldInfo = new KQFormatBiz ( ) . getDefinedField ( ) ;
String definedField = " " ;
String definedParam = " " ;
String definedParamSum = " " ;
2025-02-06 10:57:38 +08:00
String convertAttendDay = workTime ! = null ? Util . null2s ( workTime . getConvertAttendDay ( ) , " 1.0 " ) : " 1.0 " ;
2024-07-31 16:04:24 +08:00
if ( workTime . getKQType ( ) . equals ( " 3 " ) ) { //自由工时
lsParam . addAll ( kqFormatFreeData . format ( userId , kqDate , workFlowInfo ) ) ;
} else {
definedField = Util . null2String ( definedFieldInfo . get ( " definedField " ) ) ;
definedParam = Util . null2String ( definedFieldInfo . get ( " definedParam " ) ) ;
definedParamSum = Util . null2String ( definedFieldInfo . get ( " definedParamSum " ) ) ;
lsParam . addAll ( format ( userId , kqDate , workTime , workFlowInfo , uuid ) ) ;
}
if ( lsParam . size ( ) > 0 ) {
2025-02-06 10:57:38 +08:00
if ( rs . getDBType ( ) . equals ( " postgresql " ) ) {
sql = " insert into kq_format_detail( " +
" resourceid,kqdate,groupid,serialid,serialnumber,workbegindate,workbegintime,workenddate,workendtime,workmins, " +
" signindate,signintime,signinid,signoutdate,signouttime,signoutid,signMins, " +
" attendanceMins,belatemins,graveBeLateMins,leaveearlymins,graveLeaveEarlyMins,absenteeismmins,forgotcheckMins, " +
" leaveMins,leaveinfo,evectionMins,outMins,forgotbeginworkcheckmins,otherinfo " + ( definedField . length ( ) > 0 ? " , " + definedField + " " : " " ) + " ,day_type,create_time,update_time,id,flowinfo,on_absenteeismmins,off_absenteeismmins) " +
" values(?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,? " + ( definedField . length ( ) > 0 ? " , " + definedParam + " " : " " ) + " ,?,?::timestamp,?::timestamp,?,?,?,?) " ;
} else {
sql = " insert into kq_format_detail( " +
" resourceid,kqdate,groupid,serialid,serialnumber,workbegindate,workbegintime,workenddate,workendtime,workmins, " +
" signindate,signintime,signinid,signoutdate,signouttime,signoutid,signMins, " +
" attendanceMins,belatemins,graveBeLateMins,leaveearlymins,graveLeaveEarlyMins,absenteeismmins,forgotcheckMins, " +
" leaveMins,leaveinfo,evectionMins,outMins,forgotbeginworkcheckmins,otherinfo " + ( definedField . length ( ) > 0 ? " , " + definedField + " " : " " ) + " ,day_type,create_time,update_time,id,flowinfo,on_absenteeismmins,off_absenteeismmins) " +
" values(?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,? " + ( definedField . length ( ) > 0 ? " , " + definedParam + " " : " " ) + " ,?,?,?,?,?,?,?) " ;
}
2024-07-31 16:04:24 +08:00
for ( int i = 0 ; i < lsParam . size ( ) ; i + + ) {
List < Object > param = lsParam . get ( i ) ;
boolean isok = rs . executeUpdate ( sql , param ) ;
kqLog . info ( " 插入记录:userId: " + userId + " :kqDate: " + kqDate + " :param: " + JSON . toJSONString ( param ) + " :isok: " + isok + " ::uuid:: " + uuid ) ;
}
2025-02-06 10:57:38 +08:00
String attendancedaysF = " (cast(sum(attendanceMins)AS decimal(10, 2))* " + Util . getDoubleValue ( convertAttendDay ) + " )/sum(workmins) as attendancedays, sum(attendanceMins) as attendanceMins, " ;
String workF = " case when sum(workmins)>0 then " + convertAttendDay + " end as workdays, sum(workmins) as workmins, " ;
String belateminsF = " sum(case when belatemins> 0 then 1 else 0 end) as belate,sum(belatemins) as belatemins, " ;
String graveBeLateMinsF = " sum(case when graveBeLateMins> 0 then 1 else 0 end) as graveBeLate,sum(graveBeLateMins) as graveBeLateMins, " ;
String leaveearlyminsF = " sum(case when leaveearlymins> 0 then 1 else 0 end) as leaveearly,sum(leaveearlymins) as leaveearlymins, " ;
String graveLeaveEarlyMinsF = " sum(case when graveLeaveEarlyMins> 0 then 1 else 0 end) as graveLeaveEarly,sum(graveLeaveEarlyMins) as graveLeaveEarlyMins, " ;
String absenteeismminsF = " sum(case when absenteeismmins> 0 then 1 else 0 end) as absenteeism,sum(absenteeismmins) as absenteeismmins, " ;
String forgotcheckminsF = " sum(case when forgotcheckmins> 0 then 1 else 0 end) as forgotcheck,sum(forgotcheckmins) as forgotcheckmins, " ;
String forgotbeginworkcheckminsF = " sum(case when forgotbeginworkcheckmins> 0 then 1 else 0 end) as forgotbeginworkcheck,sum(forgotbeginworkcheckmins) as forgotbeginworkcheckmins " ;
String signF = " cast(sum(signmins)AS decimal(10, 2))/sum(workmins) as signdays, sum(signmins) as signmins, " ;
String onoffAbsenteeismminsF = " sum(case when on_absenteeismmins> 0 then 1 else 0 end) as on_absenteeismmins,sum(case when off_absenteeismmins> 0 then 1 else 0 end) as off_absenteeismmins " ;
if ( 1 = = workTime . getNonWorkShift ( ) ) {
attendancedaysF = " 0 as attendancedays, 0 as attendanceMins, " ;
workF = " 0 as workdays, 0 as workmins, " ;
belateminsF = " 0 as belate,0 as belatemins, " ;
graveBeLateMinsF = " 0 as graveBeLate,0 as graveBeLateMins, " ;
leaveearlyminsF = " 0 as leaveearly,0 as leaveearlymins, " ;
graveLeaveEarlyMinsF = " 0 as graveLeaveEarly,0 as graveLeaveEarlyMins, " ;
absenteeismminsF = " 0 as absenteeism,0 as absenteeismmins, " ;
forgotcheckminsF = " 0 as forgotcheck,0 as forgotcheckmins, " ;
forgotbeginworkcheckminsF = " 0 as forgotbeginworkcheck,0 as forgotbeginworkcheckmins " ;
signF = " 0 as signdays, 0 as signmins, " ;
onoffAbsenteeismminsF = " 0 as on_absenteeismmins, 0 as off_absenteeismmins " ;
}
Long id = IdGenerator . generate ( ) ;
String baseField = " " ;
if ( " mysql " . equalsIgnoreCase ( rs . getDBType ( ) ) ) {
baseField = " now(),now(), " + id ;
} else if ( " oracle " . equalsIgnoreCase ( rs . getDBType ( ) ) ) {
baseField = " sysdate,sysdate, " + id ;
} else if ( " postgresql " . equalsIgnoreCase ( rs . getDBType ( ) ) ) {
baseField = " now(),now(), " + id ;
} else {
baseField = " getdate(),getdate(), " + id ;
}
2024-07-31 16:04:24 +08:00
sql = " insert into kq_format_total(resourceid,kqdate,subcompanyid,departmentid,jobtitle,groupid,serialid,workdays,workmins, " +
" attendancedays,attendancemins,signdays,signmins,belate,belatemins,gravebelate,gravebelatemins,leaveeearly,leaveearlymins,graveleaveearly, " +
" graveleaveearlymins,absenteeism,absenteeismmins,forgotcheck,forgotcheckmins, " +
2025-02-06 10:57:38 +08:00
" leaveMins,evectionMins,outMins,forgotbeginworkcheck,forgotbeginworkcheckmins " + ( definedField . length ( ) > 0 ? " , " + definedField + " " : " " ) + " ,create_time,update_time,id,on_absenteeismmins,off_absenteeismmins) " +
2024-07-31 16:04:24 +08:00
" select a.resourceid,kqdate,b.subcompanyid1,b.departmentid,b.jobtitle,groupid,serialid, " +
2025-02-06 10:57:38 +08:00
workF +
attendancedaysF +
signF +
belateminsF +
graveBeLateMinsF +
leaveearlyminsF +
graveLeaveEarlyMinsF +
absenteeismminsF +
forgotcheckminsF +
" sum(leaveMins) as leaveMins, " +
2024-07-31 16:04:24 +08:00
" sum(evectionMins) as evectionMins,sum(outMins) as outMins, " +
2025-02-06 10:57:38 +08:00
forgotbeginworkcheckminsF +
( definedField . length ( ) > 0 ? " , " + definedParamSum + " " : " " ) + " , " + baseField + " , " + onoffAbsenteeismminsF +
2024-07-31 16:04:24 +08:00
" from kq_format_detail a, hrmresource b " +
" where a.resourceid = b.id and resourceid = ? and kqdate=? " +
" group by resourceid,kqdate,b.subcompanyid1,b.departmentid,b.jobtitle,groupid,serialid " ;
rs . executeUpdate ( sql , userId , kqDate ) ;
2025-02-06 10:57:38 +08:00
}
2024-07-31 16:04:24 +08:00
}
// 晶测考勤二开 判断加班异常
AbnormalOvertimeRemind . remind ( Convert . toInt ( userId , 0 ) , kqDate ) ;
} catch ( Exception e ) {
2025-02-06 10:57:38 +08:00
kqLog . info ( " 考勤重算报错:KQFormatData.Exception: " ) ;
StringWriter errorsWriter = new StringWriter ( ) ;
e . printStackTrace ( new PrintWriter ( errorsWriter ) ) ;
kqLog . info ( errorsWriter . toString ( ) ) ;
2024-07-31 16:04:24 +08:00
}
return resultMap ;
}
public List < List < Object > > format ( String userId , String kqDate , WorkTimeEntity workTime ,
Map < String , Object > workFlowInfo , String uuid ) {
List < List < Object > > lsParam = new ArrayList < > ( ) ;
List < Object > params = null ;
2025-02-06 10:57:38 +08:00
HashMap < String , Integer > middleMap = new HashMap < > ( ) ;
2024-07-31 16:04:24 +08:00
try {
2025-02-06 10:57:38 +08:00
KQRepeatLengthContext . clear ( ) ;
KQRepeatLengthContext . removeRepeatBeanLink ( ) ;
KQRepeatLengthContext . removeRepeatBeanLinkRange ( ) ;
Timestamp date = new Timestamp ( System . currentTimeMillis ( ) ) ;
2024-07-31 16:04:24 +08:00
KQSettingsComInfo kqSettingsComInfo = new KQSettingsComInfo ( ) ;
String nosign_is_absent = Util . null2String ( kqSettingsComInfo . getMain_val ( " nosign_is_absent " ) , " 1 " ) ;
2025-02-06 10:57:38 +08:00
//默认不开启半天的特殊规则, 如果开启, 那么只要是半天的单位, 并且申请考勤流程半天, 那么实际出勤就是0.5天, 不考虑迟到和早退。当天旷工的情况需要考虑, 即如果另外半天是旷工, 那么实际出勤自然也是0
String is_half = Util . null2String ( kqSettingsComInfo . getMain_val ( " is_half " ) , " 0 " ) ;
String early_one_mins = Util . null2String ( kqSettingsComInfo . getMain_val ( " early_one_mins " ) , " 0 " ) ;
2024-07-31 16:04:24 +08:00
KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo ( ) ;
KQFormatShiftRule kqFormatShiftRule = new KQFormatShiftRule ( ) ;
String preDate = DateUtil . addDate ( kqDate , - 1 ) ; //上一天日期
String nextDate = DateUtil . addDate ( kqDate , 1 ) ; //下一天日期
String dateKey = userId + " | " + kqDate ;
String nextDateKey = userId + " | " + nextDate ;
ArrayList < String > hostIps = InitServer . getRealIp ( ) ;
boolean oneSign = false ;
List < TimeScopeEntity > lsSignTime = new ArrayList < > ( ) ;
List < TimeScopeEntity > lsWorkTime = new ArrayList < > ( ) ;
List < TimeScopeEntity > lsRestTime = new ArrayList < > ( ) ;
List < Object > workFlow = null ;
2025-02-06 10:57:38 +08:00
int restShift = 0 ;
int signoutOnlyoff = 0 ;
2024-07-31 16:04:24 +08:00
if ( workTime ! = null ) {
lsSignTime = workTime . getSignTime ( ) ; //允许打卡时间
lsWorkTime = workTime . getWorkTime ( ) ; //工作时间
lsRestTime = workTime . getRestTime ( ) ; //休息时段时间
oneSign = lsWorkTime ! = null & & lsWorkTime . size ( ) = = 1 ;
2025-02-06 10:57:38 +08:00
restShift = workTime . getNonWorkShift ( ) ;
signoutOnlyoff = workTime . getSignoutOnlyoff ( ) ;
}
kqLog . info ( " format in >>>>>userId " + userId + " kqDate== " + kqDate + " :restShift: " + restShift + " :signoutOnlyoff: " + signoutOnlyoff + " :hostIps: " + hostIps + " :uuid:: " + uuid ) ;
if ( this . writeLog ) {
logInfo . put ( " signoutOnlyoff " , signoutOnlyoff ) ;
}
//哺乳假 请假时长
int repeatLeaveMins = 0 ;
//所有的请假时长
int allLeaveMins = 0 ;
String repeatKey = userId + " _ " + kqDate ;
String keyRepeat = userId + " | " + kqDate + " |repeat " ;
if ( workFlowInfo . get ( keyRepeat ) ! = null ) {
List < Object > workFlowRepeat = ( List < Object > ) workFlowInfo . get ( keyRepeat ) ;
repeatLeaveMins = handleRepeatWorkFlowInfo ( workFlowRepeat , repeatKey ) ;
2024-07-31 16:04:24 +08:00
}
int [ ] dayMins = new int [ 2880 ] ; //一天所有分钟数
Arrays . fill ( dayMins , - 1 ) ;
2025-02-06 10:57:38 +08:00
//处理半天班次冲销问题
int [ ] dayMinsNew = new int [ 2880 ] ; //一天所有分钟数
Arrays . fill ( dayMinsNew , - 1 ) ;
int workMins4leave = 0 ;
int middleMins = 0 ; //班次的半天时长
int middleMins_final = 0 ; //班次的半天时长
int shiftNums = lsWorkTime = = null ? 0 : lsWorkTime . size ( ) ;
2024-07-31 16:04:24 +08:00
// 一天4次打卡单独做判断, 如果是上午下班打卡和下午上班打卡时间重叠, 那么上午的下班卡取最早的, 下午的上班卡取最晚的。用shiftCount是否等于-1判断, -1就走标准不重叠。2就表示重叠走新的逻辑
int shiftCount = lsWorkTime = = null ? 0 : lsWorkTime . size ( ) ;
int shiftI = 0 ;
String signEndDateTimeZero = " " ;
for ( int i = 0 ; lsWorkTime ! = null & & i < lsWorkTime . size ( ) ; i + + ) {
shiftI = i ;
TimeScopeEntity signTimeScope = lsSignTime . get ( i ) ;
TimeScopeEntity workTimeScope = lsWorkTime . get ( i ) ;
String signBeginDateTime = signTimeScope . getBeginTimeAcross ( ) ? nextDate : kqDate ;
if ( signTimeScope . isBeginTimePreAcross ( ) ) {
signBeginDateTime = preDate ;
}
signBeginDateTime + = " " + kqTimesArrayComInfo . turn48to24Time ( signTimeScope . getBeginTime ( ) ) + " :00 " ;
String signEndDateTime = signTimeScope . getEndTimeAcross ( ) ? nextDate : kqDate ;
signEndDateTime + = " " + kqTimesArrayComInfo . turn48to24Time ( signTimeScope . getEndTime ( ) ) + " :59 " ;
if ( shiftCount = = 2 & & shiftI = = 0 ) {
signEndDateTimeZero = signEndDateTime ;
}
if ( shiftCount = = 2 & & shiftI = = 1 ) {
shiftCount = signBeginDateTime . compareTo ( signEndDateTimeZero ) < = 0 ? shiftCount : - 1 ;
}
2025-02-06 10:57:38 +08:00
String workBeginTime = Util . null2String ( workTimeScope . getBeginTime ( ) ) ;
String ori_workBeginTime = workBeginTime ;
int workBeginIdx = kqTimesArrayComInfo . getArrayindexByTimes ( workBeginTime ) ;
boolean workBenginTimeAcross = workTimeScope . getBeginTimeAcross ( ) ;
String workEndTime = Util . null2String ( workTimeScope . getEndTime ( ) ) ;
String ori_workEndTime = workEndTime ;
int workEndIdx = kqTimesArrayComInfo . getArrayindexByTimes ( workEndTime ) ;
boolean workEndTimeAcross = workTimeScope . getEndTimeAcross ( ) ;
int workMins = workTimeScope . getWorkMins ( ) ;
String workBeginDate = workBenginTimeAcross ? nextDate : kqDate ;
String workEndDate = workEndTimeAcross ? nextDate : kqDate ;
if ( lsRestTime ! = null & & ! lsRestTime . isEmpty ( ) ) {
for ( int k = 0 ; k < lsRestTime . size ( ) ; k + + ) {
TimeScopeEntity restTimeScope = lsRestTime . get ( k ) ;
if ( restTimeScope ! = null ) {
String restBeginTime = Util . null2String ( restTimeScope . getBeginTime ( ) ) ;
String restEndTime = Util . null2String ( restTimeScope . getEndTime ( ) ) ;
int beginIdx = kqTimesArrayComInfo . getArrayindexByTimes ( restBeginTime ) ;
int endIdx = kqTimesArrayComInfo . getArrayindexByTimes ( restEndTime ) ;
if ( endIdx > beginIdx ) {
Arrays . fill ( dayMinsNew , beginIdx , endIdx , - 11 ) ; //休息时间
}
}
}
int all_rest_cnt = kqTimesArrayComInfo . getCnt ( dayMinsNew , workBeginIdx , workEndIdx , - 11 ) ;
if ( all_rest_cnt > = 0 ) {
workMins = workMins - ( all_rest_cnt ) ;
}
}
workMins4leave + = workMins ;
}
middleMins = workMins4leave > 0 ? workMins4leave / 2 : 0 ;
middleMins_final = middleMins ;
int split_time_index = middleMins_final ; // 半天时间index, 用于考勤汇总报表区分上下午
if ( oneSign ) {
List < int [ ] > halfWorkIndex = workTime . getHalfWorkIndex ( ) ;
if ( halfWorkIndex ! = null & & ! halfWorkIndex . isEmpty ( ) ) {
int [ ] halfWorkIndexs = halfWorkIndex . get ( 0 ) ;
split_time_index = halfWorkIndexs [ 1 ] ; //半天的时间
}
2024-07-31 16:04:24 +08:00
}
2025-02-06 10:57:38 +08:00
2024-07-31 16:04:24 +08:00
for ( int i = 0 ; lsWorkTime ! = null & & i < lsWorkTime . size ( ) ; i + + ) {
shiftI = i ;
params = new ArrayList < > ( ) ;
TimeScopeEntity signTimeScope = lsSignTime . get ( i ) ;
TimeScopeEntity workTimeScope = lsWorkTime . get ( i ) ;
//TimeScopeEntity restTimeScope = lsRestTime.isEmpty()?null:lsRestTime.get(i);
String workBeginTime = Util . null2String ( workTimeScope . getBeginTime ( ) ) ;
String ori_workBeginTime = workBeginTime ;
int workBeginIdx = kqTimesArrayComInfo . getArrayindexByTimes ( workBeginTime ) ;
boolean workBenginTimeAcross = workTimeScope . getBeginTimeAcross ( ) ;
String workEndTime = Util . null2String ( workTimeScope . getEndTime ( ) ) ;
String ori_workEndTime = workEndTime ;
int workEndIdx = kqTimesArrayComInfo . getArrayindexByTimes ( workEndTime ) ;
boolean workEndTimeAcross = workTimeScope . getEndTimeAcross ( ) ;
int workMins = workTimeScope . getWorkMins ( ) ;
String workBeginDate = workBenginTimeAcross ? nextDate : kqDate ;
String workEndDate = workEndTimeAcross ? nextDate : kqDate ;
Arrays . fill ( dayMins , workBeginIdx , workEndIdx , 1 ) ; //工作时段标识 1
int beginIdx = 0 ;
int endIdx = 0 ;
int checkIn = 0 ;
int checkOut = 0 ;
String signInId = " " ;
String signInDate = " " ;
String signInTime = " " ;
String signOutId = " " ;
String signOutDate = " " ;
String signOutTime = " " ;
int earlyInMins = 0 ; //早到分钟数
int lateOutMins = 0 ; //晚走分钟数
int signMins = 0 ; //签到签退时长
int tmpAttendanceMins = 0 ; //出勤分钟数(流程抵扣来的)
int attendanceMins = 0 ;
int beLateMins = 0 ;
int graveBeLateMins = 0 ;
int leaveEarlyMins = 0 ;
int graveLeaveEarlyMins = 0 ;
int absenteeismMins = 0 ;
2025-02-06 10:57:38 +08:00
int on_absenteeismMins = 0 ;
int off_absenteeismMins = 0 ;
2024-07-31 16:04:24 +08:00
int leaveMins = 0 ; //请假时长
Map < String , Object > leaveInfo = new HashMap < > ( ) ; //请假信息
Map < String , Object > otherinfo = new HashMap < > ( ) ; //存一些用得到的信息
2025-02-06 10:57:38 +08:00
Map < String , Object > flowinfo = new HashMap < > ( ) ; //流程信息
2024-07-31 16:04:24 +08:00
int evectionMins = 0 ; //出差时长
int outMins = 0 ; //公出时长
int otherMins = 0 ; //异常流程时长
int forgotCheckMins = 0 ;
int forgotBeginWorkCheckMins = 0 ; //上班漏签
int signInTimeIndx = - 1 ;
int flowSignInTimeIndx = - 1 ;
int signInTimeOutdx = - 1 ;
//用来计算实际打卡时长用的
int signInTimeIndx4Sign = - 1 ;
int signInTimeOutdx4Sign = - 1 ;
String signBeginDateTime = signTimeScope . getBeginTimeAcross ( ) ? nextDate : kqDate ;
if ( signTimeScope . isBeginTimePreAcross ( ) ) {
signBeginDateTime = preDate ;
}
signBeginDateTime + = " " + kqTimesArrayComInfo . turn48to24Time ( signTimeScope . getBeginTime ( ) ) + " :00 " ;
String signEndDateTime = signTimeScope . getEndTimeAcross ( ) ? nextDate : kqDate ;
signEndDateTime + = " " + kqTimesArrayComInfo . turn48to24Time ( signTimeScope . getEndTime ( ) ) + " :59 " ;
String workBeginDateTime = workTimeScope . getBeginTimeAcross ( ) ? nextDate : kqDate ;
workBeginDateTime + = " " + kqTimesArrayComInfo . turn48to24Time ( workTimeScope . getBeginTime ( ) ) + " :00 " ;
String workEndDateTime = workTimeScope . getEndTimeAcross ( ) ? nextDate : kqDate ;
workEndDateTime + = " " + kqTimesArrayComInfo . turn48to24Time ( workTimeScope . getEndTime ( ) ) + " :00 " ;
kqLog . info ( " signBeginDateTime " + signBeginDateTime + " ::userId " + userId + " kqDate== " + kqDate + " :hostIps: " + hostIps + " :uuid:: " + uuid ) ;
kqLog . info ( " signEndDateTime " + signEndDateTime + " ::userId " + userId + " kqDate== " + kqDate + " :hostIps: " + hostIps + " :uuid:: " + uuid ) ;
kqLog . info ( " workBeginDateTime " + workBeginDateTime + " ::userId " + userId + " kqDate== " + kqDate + " :hostIps: " + hostIps + " :uuid:: " + uuid ) ;
kqLog . info ( " workEndDateTime " + workEndDateTime + " ::userId " + userId + " kqDate== " + kqDate + " :hostIps: " + hostIps + " :uuid:: " + uuid ) ;
Map < String , String > shifRuleMap = Maps . newHashMap ( ) ;
2025-02-06 10:57:38 +08:00
if ( 1 ! = restShift ) {
if ( oneSign ) {
//个性化设置只支持一天一次上下班
ShiftInfoBean shiftInfoBean = new ShiftInfoBean ( ) ;
shiftInfoBean . setSplitDate ( kqDate ) ;
shiftInfoBean . setShiftRuleMap ( workTime . getShiftRuleInfo ( ) ) ;
shiftInfoBean . setSignTime ( lsSignTime ) ;
shiftInfoBean . setWorkTime ( lsWorkTime ) ;
shiftInfoBean . setSignoutOnlyoff ( signoutOnlyoff ) ;
List < String > logList = Lists . newArrayList ( ) ;
KQShiftRuleInfoBiz . getShiftRuleInfo ( shiftInfoBean , userId , shifRuleMap , logList ) ;
if ( ! shifRuleMap . isEmpty ( ) ) {
if ( ! logList . isEmpty ( ) ) {
otherinfo . put ( " logList " , logList ) ;
2024-07-31 16:04:24 +08:00
}
2025-02-06 10:57:38 +08:00
otherinfo . put ( " shiftRule " , shifRuleMap ) ;
if ( shifRuleMap . containsKey ( " shift_beginworktime " ) ) {
String shift_beginworktime = Util . null2String ( shifRuleMap . get ( " shift_beginworktime " ) ) ;
if ( shift_beginworktime . length ( ) > 0 ) {
workBeginTime = Util . null2String ( shift_beginworktime ) ;
workBeginIdx = kqTimesArrayComInfo . getArrayindexByTimes ( workBeginTime ) ;
workTimeScope . setBeginTime ( workBeginTime ) ;
workTimeScope . setBeginTimeAcross ( workBeginIdx > = 1440 ? true : false ) ;
}
}
if ( this . writeLog ) {
logInfo . put ( " before.workEndIdx " , workEndIdx ) ;
}
if ( shifRuleMap . containsKey ( " shift_endworktime " ) ) {
String shift_endworktime = Util . null2String ( shifRuleMap . get ( " shift_endworktime " ) ) ;
if ( shift_endworktime . length ( ) > 0 ) {
workEndTime = Util . null2String ( shift_endworktime ) ;
workEndIdx = kqTimesArrayComInfo . getArrayindexByTimes ( workEndTime ) ;
workTimeScope . setEndTime ( workEndTime ) ;
workTimeScope . setEndTimeAcross ( workEndIdx > = 1440 ? true : false ) ;
}
2024-07-31 16:04:24 +08:00
}
}
2025-02-06 10:57:38 +08:00
kqLog . info ( " 个性化之后 signBeginDateTime " + signBeginDateTime ) ;
kqLog . info ( " 个性化之后 signEndDateTime " + signEndDateTime ) ;
kqLog . info ( " 个性化之后 workBeginDateTime " + workBeginDateTime ) ;
kqLog . info ( " 个性化之后 workEndDateTime " + workEndDateTime ) ;
2024-07-31 16:04:24 +08:00
}
2025-02-06 10:57:38 +08:00
}
if ( this . writeLog ) {
logInfo . put ( " after.workEndIdx " , workEndIdx ) ;
2024-07-31 16:04:24 +08:00
}
2025-02-06 10:57:38 +08:00
List < Object > lsCheckInfo = new KQFormatSignData ( ) . getSignInfo ( userId , signTimeScope , workTimeScope , kqDate , preDate , nextDate , kqTimesArrayComInfo , hostIps , uuid , shiftCount , shiftI , signoutOnlyoff ) ;
2024-07-31 16:04:24 +08:00
kqLog . info ( " lsCheckInfo " + JSONObject . toJSONString ( lsCheckInfo ) + " ::userId " + userId + " kqDate== " + kqDate + " :hostIps: " + hostIps + " :uuid:: " + uuid ) ;
if ( this . writeLog ) {
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 10005297 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , signBeginDateTime ) ;
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 10005298 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , signEndDateTime ) ;
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 1940 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , workBeginDateTime ) ;
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 10005299 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , workEndDateTime ) ;
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 10005300 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , lsCheckInfo ) ;
}
for ( int j = 0 ; lsCheckInfo ! = null & & j < lsCheckInfo . size ( ) ; j + + ) {
Map < String , Object > checkInfo = ( Map < String , Object > ) lsCheckInfo . get ( j ) ;
String signStatus = Util . null2String ( checkInfo . get ( " signStatus " ) ) ;
String signId = Util . null2String ( checkInfo . get ( " signId " ) ) ;
String signDate = Util . null2String ( checkInfo . get ( " signDate " ) ) ;
String signTime = Util . null2String ( checkInfo . get ( " signTime " ) ) ;
String deduct_signintime = Util . null2String ( checkInfo . get ( " deduct_signintime " ) ) ;
String deduct_signofftime = Util . null2String ( checkInfo . get ( " deduct_signofftime " ) ) ;
String flow_signInTime = " " ;
String flow_signOutTime = " " ;
if ( kqDate . compareTo ( signDate ) < 0 ) endIdx + = 1440 ;
if ( signTime . length ( ) > 8 ) {
signTime = signTime . substring ( 0 , 8 ) ;
}
if ( checkInfo . get ( " signType " ) . equals ( " 1 " ) ) { //签到
checkIn + + ;
//如果流程抵扣存在,打卡时长也存在,那么相互比较得到出勤时长和打卡时长 暂不这样处理,还是按照漏签的逻辑来处理
if ( signTime . length ( ) > 0 ) {
signInTimeIndx4Sign = kqTimesArrayComInfo . getArrayindexByTimes ( signTime ) ;
}
signInId = signId ;
signInDate = signDate ;
signInTime = signTime ;
signInTimeIndx = kqTimesArrayComInfo . getArrayindexByTimes ( signInTime ) ;
2025-02-06 10:57:38 +08:00
if ( this . writeLog ) {
logInfo . put ( j + " >>>signInTime " , signInTime ) ;
logInfo . put ( j + " >>>signInTimeIndx " , signInTimeIndx ) ;
logInfo . put ( j + " >>>kqDate " , kqDate + " | " + signDate ) ;
}
2024-07-31 16:04:24 +08:00
if ( deduct_signintime . length ( ) > 0 ) {
if ( signTime . length ( ) > 0 ) {
if ( deduct_signintime . compareTo ( signTime ) < 0 ) {
flow_signInTime = deduct_signintime ;
}
} else {
flow_signInTime = deduct_signintime ;
}
}
if ( flow_signInTime . length ( ) > 0 ) {
flowSignInTimeIndx = kqTimesArrayComInfo . getArrayindexByTimes ( flow_signInTime ) ;
}
if ( kqDate . compareTo ( signDate ) < 0 ) {
signInTimeIndx + = 1440 ;
flowSignInTimeIndx + = 1440 ;
} else if ( kqDate . compareTo ( signDate ) > 0 ) {
signInTimeIndx - = 1440 ;
signInTimeIndx = signInTimeIndx < 0 ? 0 : signInTimeIndx ;
flowSignInTimeIndx - = 1440 ;
flowSignInTimeIndx = flowSignInTimeIndx < 0 ? 0 : flowSignInTimeIndx ;
}
} else if ( checkInfo . get ( " signType " ) . equals ( " 2 " ) ) { //签退
checkOut + + ;
//如果流程抵扣存在,打卡时长也存在,那么相互比较得到出勤时长和打卡时长 暂不这样处理,还是按照漏签的逻辑来处理
if ( signTime . length ( ) > 0 ) {
signInTimeOutdx4Sign = kqTimesArrayComInfo . getArrayindexByTimes ( signTime ) ;
}
signOutId = signId ;
signOutDate = signDate ;
signOutTime = signTime ;
signInTimeOutdx = kqTimesArrayComInfo . getArrayindexByTimes ( signOutTime ) ;
if ( deduct_signofftime . length ( ) > 0 ) {
if ( signTime . length ( ) > 0 ) {
if ( deduct_signofftime . compareTo ( signTime ) > 0 ) {
flow_signOutTime = deduct_signofftime ;
}
} else {
flow_signOutTime = deduct_signofftime ;
}
}
if ( flow_signOutTime . length ( ) > 0 ) {
signInTimeOutdx = kqTimesArrayComInfo . getArrayindexByTimes ( flow_signOutTime ) ;
}
if ( kqDate . compareTo ( signDate ) < 0 ) {
signInTimeOutdx + = 1440 ;
} else if ( kqDate . compareTo ( signDate ) > 0 ) {
signInTimeOutdx - = 1440 ;
signInTimeOutdx = signInTimeOutdx < 0 ? 0 : signInTimeOutdx ;
}
if ( oneSign ) {
if ( signInTimeOutdx > workEndIdx ) {
lateOutMins = signInTimeOutdx - workEndIdx ;
}
}
}
if ( checkInfo . get ( " signType " ) . equals ( " 1 " ) ) { //签到
if ( signTime . length ( ) > 0 ) {
String signMinTime = signTime . substring ( 0 , 5 ) + " :00 " ;
endIdx = kqTimesArrayComInfo . getArrayindexByTimes ( signTime ) ;
if ( signTime . compareTo ( signMinTime ) > 0 ) {
//如果签到时间是带秒的且是迟到,那么签到时间多一秒和多一分钟是一样的
endIdx + = 1 ;
signInTimeIndx = signInTimeIndx + 1 ; //如果是带秒的打卡数据不应该影响流程抵扣的数据的下标
}
if ( kqDate . compareTo ( signDate ) < 0 ) {
endIdx + = 1440 ;
} else if ( kqDate . compareTo ( signDate ) > 0 ) {
endIdx - = 1440 ;
endIdx = endIdx < 0 ? 0 : endIdx ;
}
if ( endIdx > workBeginIdx ) {
if ( flow_signInTime . length ( ) > 0 ) {
if ( flowSignInTimeIndx > workBeginIdx ) {
//增加一个判断,流程抵扣打卡如果开启了并且有抵扣上班打卡,那么也就不是迟到了
Arrays . fill ( dayMins , workBeginIdx , endIdx , 2 ) ; //迟到时段标识 2
}
} else {
Arrays . fill ( dayMins , workBeginIdx , endIdx , 2 ) ; //迟到时段标识 2
}
}
}
} else if ( checkInfo . get ( " signType " ) . equals ( " 2 " ) ) { //签退
if ( signTime . length ( ) > 0 ) {
beginIdx = kqTimesArrayComInfo . getArrayindexByTimes ( signTime ) ;
2025-02-06 10:57:38 +08:00
if ( this . writeLog ) {
logInfo . put ( j + " .signTime " , signDate + " | " + signTime ) ;
logInfo . put ( j + " .beginIdx " , beginIdx ) ;
logInfo . put ( j + " .workEndIdx " , workEndIdx ) ;
}
2024-07-31 16:04:24 +08:00
if ( StringUtils . isNotBlank ( signDate ) & & signDate . compareTo ( kqDate ) > 0 ) {
beginIdx + = 1440 ;
} else if ( kqDate . compareTo ( signDate ) > 0 ) {
beginIdx - = 1440 ;
beginIdx = beginIdx < 0 ? 0 : beginIdx ;
}
if ( workEndIdx > beginIdx ) {
if ( flow_signOutTime . length ( ) > 0 ) {
if ( workEndIdx > signInTimeOutdx ) {
//增加一个判断,流程抵扣打卡如果开启了并且有抵扣下班打卡,那么也就不是早退了
Arrays . fill ( dayMins , beginIdx , workEndIdx , 3 ) ; //早退时段标识 3
}
} else {
Arrays . fill ( dayMins , beginIdx , workEndIdx , 3 ) ; //早退时段标识 3
}
}
}
}
}
//打卡时长=签退时间-签到时间(有签到签退才计算)
if ( checkIn = = 1 & & checkOut = = 1 ) {
if ( signInTimeIndx4Sign > - 1 & & signInTimeOutdx4Sign > - 1 ) {
if ( DateUtil . dayDiff ( signInDate , signOutDate ) = = 0 ) { //同一天签到和签退
signMins = signInTimeOutdx4Sign - signInTimeIndx4Sign ;
} else if ( DateUtil . dayDiff ( signInDate , signOutDate ) = = 1 ) { //第一天签到,第二天签退
if ( signInTimeOutdx4Sign < signInTimeIndx4Sign ) {
signMins = 1440 + signInTimeOutdx4Sign - signInTimeIndx4Sign ;
} else {
signMins = 1440 + signInTimeOutdx4Sign - signInTimeIndx4Sign ;
}
}
} else {
signMins = 0 ;
}
if ( signMins < 0 ) {
signMins = 0 ;
}
}
if ( checkIn = = 0 & & checkOut = = 0 ) { //旷工(无签到无签退)
if ( workEndIdx > workBeginIdx ) {
Arrays . fill ( dayMins , workBeginIdx , workEndIdx , 4 ) ; //旷工时段标识 4
}
}
if ( checkOut = = 0 & & checkIn > 0 ) { //漏签(有签到无签退)
if ( signInTimeIndx > - 1 ) {
if ( workEndIdx > signInTimeIndx ) {
//漏签就是从本次时段内的打卡到下班点
//上班漏签应该是从签到到签到结束时间,不过这里可以不用管,只是一个次数
Arrays . fill ( dayMins , signInTimeIndx , workEndIdx , 6 ) ; //上班漏签时段标识 6
} else {
//签到晚于本次时段结束时间,也算漏签
forgotCheckMins + + ;
}
} else if ( flowSignInTimeIndx > - 1 ) {
if ( workEndIdx > flowSignInTimeIndx ) {
//漏签就是从本次时段内的打卡到下班点
//上班漏签应该是从签到到签到结束时间,不过这里可以不用管,只是一个次数
Arrays . fill ( dayMins , flowSignInTimeIndx , workEndIdx , 6 ) ; //上班漏签时段标识 6
} else {
//签到晚于本次时段结束时间,也算漏签
forgotCheckMins + + ;
}
}
}
if ( checkIn = = 0 & & checkOut > 0 ) { //漏签(有签退无签到)
if ( signInTimeOutdx > 0 ) {
if ( workBeginIdx < signInTimeOutdx ) {
//下班漏签应该是从签退到签退开始时间,不过这里可以不用管,只是一个次数
Arrays . fill ( dayMins , workBeginIdx , signInTimeOutdx , 66 ) ; //下班漏签时段标识 66, 66呼应前面的漏签的6
} else {
//这种数据理论上不会存在,也记下吧
forgotBeginWorkCheckMins + + ;
}
}
}
if ( workFlowInfo . get ( dateKey ) ! = null ) {
workFlow = ( List < Object > ) workFlowInfo . get ( dateKey ) ;
}
2025-02-06 10:57:38 +08:00
boolean isHandle1 = false ;
boolean isHandle2 = false ;
List < Object > flowList = Lists . newArrayList ( ) ;
2024-07-31 16:04:24 +08:00
for ( int j = 0 ; workFlow ! = null & & j < workFlow . size ( ) ; j + + ) {
Map < String , Object > data = ( Map < String , Object > ) workFlow . get ( j ) ;
String flowType = Util . null2String ( data . get ( " flowtype " ) ) ;
String newLeaveType = Util . null2String ( data . get ( " newleavetype " ) ) ;
String signtype = Util . null2String ( data . get ( " signtype " ) ) ;
2025-02-06 10:57:38 +08:00
String durationrule = Util . null2String ( data . get ( " durationrule " ) ) ;
String ishalf = Util . null2String ( data . get ( " ishalf " ) ) ;
double duration = Util . getDoubleValue ( Util . null2String ( data . get ( " duration " ) ) ) ;
if ( flowType . equalsIgnoreCase ( FlowReportTypeEnum . LEAVE . getFlowType ( ) ) ) {
duration = Util . getDoubleValue ( Util . null2String ( data . get ( newLeaveType ) ) ) ;
}
2024-07-31 16:04:24 +08:00
String serial = Util . null2String ( data . get ( " serial " ) ) ;
String requestId = Util . null2String ( data . get ( " requestId " ) ) ;
2025-02-06 10:57:38 +08:00
String begintime = Util . null2String ( data . get ( " begintime " ) ) ;
String endtime = Util . null2String ( data . get ( " endtime " ) ) ;
beginIdx = kqTimesArrayComInfo . getArrayindexByTimes ( begintime ) ;
endIdx = kqTimesArrayComInfo . getArrayindexByTimes ( endtime ) ;
String leavetypeKey = repeatKey + " _ " + newLeaveType ;
List < KQRepeatBean > kqRepeatBeans = KQRepeatLengthContext . getKQRepeatBean ( leavetypeKey ) ;
if ( CollectionUtils . isNotEmpty ( kqRepeatBeans ) ) {
Long allCnt = 0L ;
for ( int k = 0 ; k < kqRepeatBeans . size ( ) ; k + + ) {
KQRepeatBean kqRepeatBean = kqRepeatBeans . get ( k ) ;
Long repeatLate = kqRepeatBean . getRepeatLate ( ) ;
Long repeatEarly = kqRepeatBean . getRepeatEarly ( ) ;
allCnt + = ( ( repeatLate ! = null & & repeatLate > 0 ) ? repeatLate : 0L ) + ( ( repeatEarly ! = null & & repeatEarly > 0 ) ? repeatEarly : 0L ) ;
}
if ( leaveInfo . get ( newLeaveType ) = = null ) {
leaveInfo . put ( newLeaveType , allCnt . intValue ( ) ) ;
} else {
Integer val = ( Integer ) leaveInfo . get ( newLeaveType ) ;
leaveInfo . put ( newLeaveType , val + allCnt ) ;
}
continue ;
}
2024-07-31 16:04:24 +08:00
if ( beginIdx > = endIdx ) {
continue ;
}
2025-02-06 10:57:38 +08:00
Map < String , String > flowMap = Maps . newHashMap ( ) ;
flowMap . put ( " newLeaveType " , newLeaveType ) ;
flowMap . put ( " begintime " , begintime ) ;
flowMap . put ( " endtime " , endtime ) ;
List < Map < String , String > > flowMapList = Lists . newArrayList ( ) ;
if ( flowinfo . containsKey ( flowType ) ) {
List < Map < String , String > > tmpFlowMapList = ( List < Map < String , String > > ) flowinfo . get ( flowType ) ;
tmpFlowMapList . add ( flowMap ) ;
} else {
flowMapList . add ( flowMap ) ;
flowinfo . put ( flowType , flowMapList ) ;
}
int middleIdx = ( workBeginIdx + workEndIdx ) / 2 ; //工作时段标识 1
2024-07-31 16:04:24 +08:00
if ( flowType . equals ( FlowReportTypeEnum . EVECTION . getFlowType ( ) ) ) {
2025-02-06 10:57:38 +08:00
if ( " 2 " . equals ( durationrule ) & & " true " . equals ( ishalf ) ) {
isHandle2 = true ;
}
2024-07-31 16:04:24 +08:00
Arrays . fill ( dayMins , beginIdx , endIdx , 7 ) ; //出差抵扣时段标识 7
} else if ( flowType . equals ( FlowReportTypeEnum . OUT . getFlowType ( ) ) ) {
2025-02-06 10:57:38 +08:00
if ( " 2 " . equals ( durationrule ) & & " true " . equals ( ishalf ) ) {
isHandle2 = true ;
}
2024-07-31 16:04:24 +08:00
Arrays . fill ( dayMins , beginIdx , endIdx , 8 ) ; //公出抵扣时段标识 8
} else if ( flowType . equalsIgnoreCase ( FlowReportTypeEnum . LEAVE . getFlowType ( ) ) ) {
2025-02-06 10:57:38 +08:00
if ( " 2 " . equals ( durationrule ) & & " true " . equals ( ishalf ) ) {
isHandle1 = true ;
}
2024-07-31 16:04:24 +08:00
if ( endIdx > beginIdx ) {
Arrays . fill ( dayMins , beginIdx , endIdx , 5 ) ; //流程抵扣时段标识 5
int tmpBeginIdx = beginIdx ;
int tmpEndIdx = endIdx ;
Integer val = 0 ;
if ( beginIdx > = workEndIdx ) {
continue ;
}
if ( endIdx < = workBeginIdx ) {
continue ;
}
if ( leaveInfo . get ( newLeaveType ) = = null ) {
leaveInfo . put ( newLeaveType , val ) ;
} else {
val = ( Integer ) leaveInfo . get ( newLeaveType ) ;
}
if ( beginIdx < workBeginIdx ) tmpBeginIdx = workBeginIdx ;
if ( endIdx > workEndIdx ) tmpEndIdx = endIdx ;
if ( tmpEndIdx > tmpBeginIdx ) {
leaveInfo . put ( newLeaveType , val + ( tmpEndIdx - tmpBeginIdx ) ) ;
}
}
} else {
if ( endIdx > beginIdx ) {
Arrays . fill ( dayMins , beginIdx , endIdx , 99 ) ; //异常流程抵扣时段标识99
}
}
}
if ( lsRestTime ! = null & & ! lsRestTime . isEmpty ( ) ) {
for ( int k = 0 ; k < lsRestTime . size ( ) ; k + + ) {
TimeScopeEntity restTimeScope = lsRestTime . get ( k ) ;
if ( restTimeScope ! = null ) {
String restBeginTime = Util . null2String ( restTimeScope . getBeginTime ( ) ) ;
String restEndTime = Util . null2String ( restTimeScope . getEndTime ( ) ) ;
beginIdx = kqTimesArrayComInfo . getArrayindexByTimes ( restBeginTime ) ;
endIdx = kqTimesArrayComInfo . getArrayindexByTimes ( restEndTime ) ;
if ( endIdx > beginIdx ) {
Arrays . fill ( dayMins , beginIdx , endIdx , - 11 ) ; //休息时间
}
}
}
int all_rest_cnt = kqTimesArrayComInfo . getCnt ( dayMins , workBeginIdx , workEndIdx , - 11 ) ;
if ( all_rest_cnt > = 0 ) {
workMins = workMins - ( all_rest_cnt ) ;
}
}
for ( int j = workBeginIdx ; j < workEndIdx ; j + + ) {
switch ( dayMins [ j ] ) {
case 1 :
tmpAttendanceMins + + ;
break ;
case 2 :
beLateMins + + ;
break ;
case 3 :
leaveEarlyMins + + ;
break ;
case 4 :
2025-02-06 10:57:38 +08:00
if ( j < split_time_index ) {
on_absenteeismMins + + ;
} else {
off_absenteeismMins + + ;
}
2024-07-31 16:04:24 +08:00
absenteeismMins + + ;
break ;
case 5 :
leaveMins + + ;
break ;
case 6 :
forgotCheckMins + + ;
break ;
case 7 :
evectionMins + + ;
break ;
case 8 :
outMins + + ;
break ;
case 66 :
forgotBeginWorkCheckMins + + ;
break ;
case 99 :
otherMins + + ;
break ;
default :
break ;
}
}
if ( forgotCheckMins = = 1 & & beLateMins = = 0 & & tmpAttendanceMins = = 0 ) { //forgotCheckMins==1表示下班后漏签, 不是迟到, 流程已完全抵扣异常
forgotCheckMins = 0 ;
}
2025-02-06 10:57:38 +08:00
List < KQRepeatBean > attendRepeatBeans = KQRepeatLengthContext . getKQRepeatBean ( repeatKey ) ;
if ( beLateMins > 0 ) {
beLateMins = ( int ) handleRepeatLength ( attendRepeatBeans , beLateMins , " late " ) ;
}
if ( leaveEarlyMins > 0 ) {
leaveEarlyMins = ( int ) handleRepeatLength ( attendRepeatBeans , leaveEarlyMins , " early " ) ;
}
boolean isAmAbsent = false ;
boolean isPmAbsent = false ;
if ( on_absenteeismMins > 0 ) {
//如果没有个性化的旷工,那就是全天旷工
isAmAbsent = true ;
}
if ( off_absenteeismMins > 0 ) {
isPmAbsent = true ;
}
2024-07-31 16:04:24 +08:00
KQShiftRuleEntity kqShiftRuleEntity = new KQShiftRuleEntity ( ) ;
kqShiftRuleEntity . setUserId ( userId ) ;
kqShiftRuleEntity . setKqDate ( kqDate ) ;
kqShiftRuleEntity . setBelatemins ( beLateMins ) ;
kqShiftRuleEntity . setLeaveearlymins ( leaveEarlyMins ) ;
kqShiftRuleEntity . setAbsenteeismmins ( absenteeismMins ) ;
kqShiftRuleEntity . setForgotcheckmins ( forgotCheckMins ) ;
kqShiftRuleEntity . setForgotBeginWorkCheckMins ( forgotBeginWorkCheckMins ) ;
kqShiftRuleEntity . setEarlyInMins ( earlyInMins ) ;
kqShiftRuleEntity . setLateOutMins ( lateOutMins ) ;
2025-02-06 10:57:38 +08:00
kqShiftRuleEntity . setAMAbsent ( isAmAbsent ) ;
kqShiftRuleEntity . setPMAbsent ( isPmAbsent ) ;
kqShiftRuleEntity . setNosign_is_absent ( nosign_is_absent ) ;
kqShiftRuleEntity . setSignInTime ( signInTime ) ;
kqShiftRuleEntity . setSignOutTime ( signOutTime ) ;
kqShiftRuleEntity . setEarly_one_mins ( early_one_mins ) ;
2024-07-31 16:04:24 +08:00
kqLog . info ( " 人性化规则处理前数据 " + JSONObject . toJSONString ( kqShiftRuleEntity ) ) ;
if ( this . writeLog ) {
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 10005301 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , kqShiftRuleEntity ) ;
}
//人性化规则
kqShiftRuleEntity = kqFormatShiftRule . doShiftRule ( workTime , kqShiftRuleEntity ) ;
kqLog . info ( " 人性化规则处理后数据 " + JSONObject . toJSONString ( kqShiftRuleEntity ) ) ;
if ( this . writeLog ) {
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 10005302 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , kqShiftRuleEntity ) ;
}
beLateMins = kqShiftRuleEntity . getBelatemins ( ) ;
graveBeLateMins = kqShiftRuleEntity . getGravebelatemins ( ) ;
leaveEarlyMins = kqShiftRuleEntity . getLeaveearlymins ( ) ;
graveLeaveEarlyMins = kqShiftRuleEntity . getGraveleaveearlymins ( ) ;
absenteeismMins = kqShiftRuleEntity . getAbsenteeismmins ( ) ;
forgotCheckMins = kqShiftRuleEntity . getForgotcheckmins ( ) ;
forgotBeginWorkCheckMins = kqShiftRuleEntity . getForgotBeginWorkCheckMins ( ) ;
2025-02-06 10:57:38 +08:00
int shiftOn_absenteeismMins = Util . getIntValue ( kqShiftRuleEntity . getOn_absenteeismMins ( ) ) ;
if ( shiftOn_absenteeismMins > 0 ) {
on_absenteeismMins = shiftOn_absenteeismMins ;
}
int shiftOff_absenteeismMins = Util . getIntValue ( kqShiftRuleEntity . getOff_absenteeismMins ( ) ) ;
if ( shiftOff_absenteeismMins > 0 ) {
off_absenteeismMins = shiftOff_absenteeismMins ;
}
2024-07-31 16:04:24 +08:00
boolean isondutyfreecheck = false ;
boolean isoffdutyfreecheck = false ;
Map < String , String > model_ShiftRule = kqFormatShiftRule . getModel_ShiftRule ( i , workTime . getSerialId ( ) ) ;
Iterator iter = model_ShiftRule . entrySet ( ) . iterator ( ) ;
while ( iter . hasNext ( ) ) {
Map . Entry entry = ( Map . Entry ) iter . next ( ) ;
String key = Util . null2String ( entry . getKey ( ) ) ;
String value = Util . null2String ( entry . getValue ( ) ) ;
if ( key . equals ( " start " ) & & value . equals ( " 1 " ) ) {
isondutyfreecheck = true ;
}
if ( key . equals ( " end " ) & & value . equals ( " 1 " ) ) {
isoffdutyfreecheck = true ;
}
}
boolean beforeBegin = ! new KQFormatBiz ( ) . needCal ( workBeginDate , workBeginTime ) ;
if ( beforeBegin ) { //还未到上班时间,不用计算任何状态
kqLog . writeLog ( " 还未到上班时间,不用计算任何状态 " ) ;
beLateMins = 0 ;
graveBeLateMins = 0 ;
leaveEarlyMins = 0 ;
graveLeaveEarlyMins = 0 ;
absenteeismMins = 0 ;
forgotCheckMins = 0 ;
forgotBeginWorkCheckMins = 0 ;
2025-02-06 10:57:38 +08:00
isAmAbsent = false ;
isPmAbsent = false ;
on_absenteeismMins = 0 ;
off_absenteeismMins = 0 ;
2024-07-31 16:04:24 +08:00
} else if ( ! new KQFormatBiz ( ) . needCal ( workEndDate , workEndTime ) ) { //还未到下班时间
kqLog . writeLog ( " 还未到上班时间 " ) ;
leaveEarlyMins = 0 ;
graveLeaveEarlyMins = 0 ;
forgotCheckMins = 0 ;
2025-02-06 10:57:38 +08:00
isPmAbsent = false ;
off_absenteeismMins = 0 ;
2024-07-31 16:04:24 +08:00
}
2025-02-06 10:57:38 +08:00
if ( 1 = = restShift | | workTime . getIsExclude ( ) ) { //休息日班次或者无需考勤人员没有异常状态
2024-07-31 16:04:24 +08:00
beLateMins = 0 ;
graveBeLateMins = 0 ;
leaveEarlyMins = 0 ;
graveLeaveEarlyMins = 0 ;
absenteeismMins = 0 ;
forgotCheckMins = 0 ;
forgotBeginWorkCheckMins = 0 ;
2025-02-06 10:57:38 +08:00
isAmAbsent = false ;
isPmAbsent = false ;
on_absenteeismMins = 0 ;
off_absenteeismMins = 0 ;
}
if ( 1 = = restShift ) { //非工作日班次連打卡時長和出勤时长也不給了
workMins = 0 ;
signMins = 0 ;
isAmAbsent = false ;
isPmAbsent = false ;
on_absenteeismMins = 0 ;
off_absenteeismMins = 0 ;
2024-07-31 16:04:24 +08:00
}
//允许下班不打卡 ,如果上班也没有打卡, 那么算上班旷工0.5天
if ( isoffdutyfreecheck ) {
if ( checkIn = = 0 ) { //(无签到),就会有上班漏签,如果有下班卡,那么上班漏签
if ( forgotBeginWorkCheckMins = = 0 & & absenteeismMins > 0 ) {
forgotBeginWorkCheckMins = absenteeismMins ;
}
}
absenteeismMins = 0 ;
forgotCheckMins = 0 ;
2025-02-06 10:57:38 +08:00
off_absenteeismMins = 0 ;
2024-07-31 16:04:24 +08:00
}
//允许上班不打卡,如果下班也没有打卡,那么算漏签
if ( isondutyfreecheck ) {
if ( checkOut = = 0 ) { //(无签退)
if ( forgotCheckMins = = 0 & & absenteeismMins > 0 ) {
forgotCheckMins = absenteeismMins ;
}
}
absenteeismMins = 0 ;
forgotBeginWorkCheckMins = 0 ;
2025-02-06 10:57:38 +08:00
on_absenteeismMins = 0 ;
2024-07-31 16:04:24 +08:00
}
if ( isondutyfreecheck & & isoffdutyfreecheck ) {
absenteeismMins = 0 ;
forgotCheckMins = 0 ;
forgotBeginWorkCheckMins = 0 ;
2025-02-06 10:57:38 +08:00
on_absenteeismMins = 0 ;
off_absenteeismMins = 0 ;
}
int repeatLeaveTime = ( int ) getRepeatLeaveTime ( ) ;
if ( repeatLeaveTime > 0 ) {
leaveMins = leaveMins + repeatLeaveTime ;
2024-07-31 16:04:24 +08:00
}
//计算实际出勤时间(出差公出算出勤)=应出勤-旷工-请假-迟到-早退
attendanceMins = workMins - absenteeismMins - leaveMins - beLateMins - graveBeLateMins - leaveEarlyMins - graveLeaveEarlyMins ;
2025-02-06 10:57:38 +08:00
if ( this . writeLog ) {
logInfo . put ( " is_half " , is_half ) ;
logInfo . put ( " shiftNums " , shiftNums ) ;
logInfo . put ( " isHandle2 " , isHandle2 ) ;
logInfo . put ( " isHandle1 " , isHandle1 ) ;
logInfo . put ( " workMins " + i , workMins ) ;
logInfo . put ( " absenteeismMins " + i , absenteeismMins ) ;
logInfo . put ( " middleMins " + i , middleMins ) ;
}
//如果开启半天特殊处理的, 请假是需要扣除0.5天
//说明没有打卡的情况,因为有打卡肯定是有迟到、早退、漏签这些异常的,不考虑迟到算旷工,早退算旷工的情况
//只处理1天1次, 和1天2次的情况, 因为1天3次的中间点可能在第二段, 需要考虑有没有打卡, 以及有打卡第三次是否需要处理等情况, 和上下午半天的概念不太适用
if ( " 1 " . equals ( is_half ) ) {
boolean absentFlag_1 = false ; //请假,
boolean absentFlag_2 = false ; //公出或出差
if ( isHandle1 | | isHandle2 ) {
if ( absenteeismMins > 0 & & ! ( beLateMins > 0 | | graveBeLateMins > 0 | | leaveEarlyMins > 0 | | graveLeaveEarlyMins > 0 | | forgotCheckMins > 0 | | forgotBeginWorkCheckMins > 0 ) ) {
if ( isHandle1 ) {
absentFlag_1 = true ; //可以理解为是1天3次和1天1次的情况, 因为1天2次的情况, 如果有旷工, 那么另外半天才是有请假,
}
if ( isHandle2 ) {
absentFlag_2 = true ; //可以理解为是1天3次和1天1次的情况, 因为1天2次的情况, 如果有旷工, 那么另外半天才是有公出或者出差
}
}
}
if ( this . writeLog ) {
logInfo . put ( " tmp_absenteeismMins " + i , absenteeismMins ) ;
logInfo . put ( " absentFlag_1 " + i , absentFlag_1 ) ;
logInfo . put ( " absentFlag_2 " + i , absentFlag_2 ) ;
}
/ * 1次 - - - 上午3小时 , 下午5小时
上午公出 , 下午旷工
上午公出 , 下午打卡
上午旷工 , 下午公出
上午打卡 , 下午公出
2次 - - - 上午3小时 , 下午5小时
上午公出 , 下午旷工 - - 需处理实际出勤 、 旷工时长
上午公出 , 下午打卡 - - 需处理实际出勤
上午旷工 , 下午公出 - - 需处理实际出勤 、 旷工时长
上午打卡 , 下午公出 - - 需处理实际出勤
* /
if ( isHandle2 ) {
if ( shiftNums = = 1 ) {
absenteeismMins = absentFlag_2 ? middleMins_final : 0 ;
attendanceMins = workMins - absenteeismMins ;
} else if ( shiftNums = = 2 ) {
if ( workMins > middleMins_final & & middleMins_final > 0 ) {
absenteeismMins = ( absenteeismMins > middleMins_final ) ? middleMins_final : ( ( absentFlag_2 | | outMins > 0 | | evectionMins > 0 ) ? Math . abs ( workMins - middleMins_final ) : 0 ) ;
absenteeismMins = ( i = = 1 & & middleMap . get ( " attendanceMins0 " ) > 0 ) ? ( absentFlag_2 ? absenteeismMins : 0 ) : absenteeismMins ; //上午打卡3小时, 下午公出5小时, 下午的就不要显示旷工1小时了
}
attendanceMins = workMins - absenteeismMins ;
}
}
if ( this . writeLog ) {
logInfo . put ( " absenteeismMins_1 " + i , absenteeismMins ) ;
logInfo . put ( " attendanceMins_1 " + i , attendanceMins ) ;
}
/ * 1次 - - - 上午3小时 , 下午5小时
上午请假 , 下午旷工
上午请假 , 下午打卡
上午旷工 , 下午请假
上午打卡 , 下午请假
2次 - - - 上午3小时 , 下午5小时
上午请假 , 下午旷工 - - 需处理实际出勤 、 旷工时长
上午请假 , 下午打卡 - - 需处理实际出勤
上午旷工 , 下午请假 - - 需处理实际出勤 、 旷工时长
上午打卡 , 下午请假 - - 需处理实际出勤
* /
if ( isHandle1 ) {
if ( shiftNums = = 1 ) {
absenteeismMins = absentFlag_1 ? middleMins_final : 0 ;
attendanceMins = workMins - absenteeismMins - ( leaveMins > 0 ? middleMins_final : ( absentFlag_1 ? ( workMins - middleMins_final ) : 0 ) ) ;
} else if ( shiftNums = = 2 ) {
if ( workMins > middleMins_final & & middleMins_final > 0 ) {
absenteeismMins = ( absenteeismMins > middleMins_final ) ? middleMins_final : ( ( absentFlag_1 | | leaveMins > 0 ) ? Math . abs ( workMins - middleMins_final ) : 0 ) ;
absenteeismMins = ( i = = 1 & & middleMap . get ( " attendanceMins0 " ) > 0 ) ? 0 : absenteeismMins ; //上午打卡3小时, 下午请假5小时, 下午的就不要显示旷工1小时了
}
attendanceMins = workMins - absenteeismMins - ( leaveMins > 0 ? middleMins_final : ( absentFlag_1 ? Math . abs ( workMins - middleMins_final ) : 0 ) ) ;
attendanceMins = attendanceMins > middleMins_final ? middleMins_final : attendanceMins ; //上午请假3小时, 下午打卡5小时
} else if ( shiftNums = = 3 ) { //比如一天三次上下班,那么中间点在第二次上下班区间
// if(workMins>middleMins && middleMins>0){
// absenteeismMins = (absenteeismMins > middleMins_final)?middleMins_final:((absentFlag_1||leaveMins>0)?(workMins - middleMins):0);
// absenteeismMins = (i>=1 && middleMap.get("attendanceMins"+(i-1))>0)?0:absenteeismMins;
// }
// attendanceMins = workMins - absenteeismMins - (leaveMins>0?middleMins_final:(absentFlag_1?Math.abs(workMins - middleMins_final):0));
// attendanceMins = attendanceMins>middleMins_final?middleMins_final:attendanceMins;//上午请假3小时, 下午打卡5小时
// if(workMins < middleMins){//客户可能是一天2次, 或者3次, 那么workmins有可能是小于半天的请假时间
// middleMins = middleMins-workMins;
// }else {
// middleMins = 0;
// }
}
if ( absenteeismMins > middleMins_final ) { //客户可能是一天2次, 或者3次
absenteeismMins = middleMins_final ;
}
}
middleMap . put ( " attendanceMins " + i , attendanceMins ) ;
middleMap . put ( " absenteeismMins " + i , absenteeismMins ) ;
middleMap . put ( " workMins " + i , workMins ) ;
middleMap . put ( " leaveMins " + i , leaveMins ) ;
middleMap . put ( " outMins " + i , outMins ) ;
middleMap . put ( " evectionMins " + i , evectionMins ) ;
middleMap . put ( " isHandle1 " + i , isHandle1 ? 1 : 0 ) ;
middleMap . put ( " isHandle2 " + i , isHandle2 ? 1 : 0 ) ;
middleMap . put ( " absentFlag_1 " + i , absentFlag_1 ? 1 : 0 ) ; //1表示有旷工
middleMap . put ( " absentFlag_2 " + i , absentFlag_2 ? 1 : 0 ) ; //1表示有旷工
}
2024-07-31 16:04:24 +08:00
// 如果没有开启"漏签是否算实际出勤"开关,则漏签不算实际出勤时长
if ( " 0 " . equals ( nosign_is_absent ) ) {
attendanceMins = attendanceMins - forgotCheckMins - forgotBeginWorkCheckMins ;
}
if ( beforeBegin | | attendanceMins < 0 ) { //还未到上班时间,不用计算任何状体
attendanceMins = 0 ;
}
2025-02-06 10:57:38 +08:00
/ * *
* 汇总报表的日历显示是有旷工就不显示漏签了 , 如果这里还统计漏签 , 张总表示日历也需要修改 , 改不动了
* 在处理完实际出勤之后 , 将漏签还原
* /
String nosign_ishandle = Util . null2String ( kqShiftRuleEntity . getNosign_ishandle ( ) ) ;
if ( " 1 " . equals ( nosign_ishandle ) ) {
forgotCheckMins = 0 ;
} else if ( " 2 " . equals ( nosign_ishandle ) ) {
forgotCheckMins = 0 ;
forgotBeginWorkCheckMins = 0 ;
}
2024-07-31 16:04:24 +08:00
kqLog . info ( " 实际出勤计算公式 " + " 实际出勤=应出勤- 旷工-请假-迟到-早退 userId " + userId + " kqDate== " + kqDate + " :hostIps: " + hostIps + " :uuid:: " + uuid ) ;
2025-02-06 10:57:38 +08:00
kqLog . info ( " 实际出勤计算结果 " + attendanceMins + " = " + workMins + " - " + absenteeismMins + " - " + leaveMins + " - " + ( beLateMins + graveBeLateMins ) + " - " + ( leaveEarlyMins - graveLeaveEarlyMins ) + " - " + ( repeatLeaveTime ) + " userId " + userId + " kqDate== " + kqDate + " :hostIps: " + hostIps + " :uuid:: " + uuid ) ;
2024-07-31 16:04:24 +08:00
if ( this . writeLog ) {
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 10005303 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 130566 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " = " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 132056 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " - " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 20085 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " - " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 670 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " - " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 20081 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " - " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 20082 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " ) ;
2025-02-06 10:57:38 +08:00
logInfo . put ( " " + weaver . systeminfo . SystemEnv . getHtmlLabelName ( 10005304 , weaver . general . ThreadVarLanguage . getLang ( ) ) + " " , attendanceMins + " = " + workMins + " - " + absenteeismMins + " - " + leaveMins + " - " + ( beLateMins + graveBeLateMins ) + " - " + ( leaveEarlyMins - graveLeaveEarlyMins ) + " - " + ( repeatLeaveTime ) ) ;
2024-07-31 16:04:24 +08:00
}
//判断当天考勤状态
// if (beLateMins > 0) {
// status = ButtonStatusEnum.BELATE.getStatusCode();
// } else if (leaveEarlyMins > 0) {
// status = ButtonStatusEnum.LEAVEERALY.getStatusCode();
// } else if (absenteeismMins > 0) {
// status = ButtonStatusEnum.ABSENT.getStatusCode();
// } else if (forgotCheckMins > 0) {
// status = ButtonStatusEnum.NOSIGN.getStatusCode();
// } else {
// status = ButtonStatusEnum.NORMAL.getStatusCode();
// }
String groupid = Util . null2String ( workTime . getGroupId ( ) ) ;
String serialid = Util . null2String ( workTime . getSerialId ( ) ) ;
params . add ( userId ) ;
params . add ( kqDate ) ;
params . add ( groupid . length ( ) = = 0 ? null : groupid ) ;
params . add ( serialid . length ( ) = = 0 ? null : serialid ) ;
params . add ( i ) ;
params . add ( workBeginDate ) ;
params . add ( kqTimesArrayComInfo . turn48to24Time ( ori_workBeginTime ) ) ;
params . add ( workEndDate ) ;
params . add ( kqTimesArrayComInfo . turn48to24Time ( ori_workEndTime ) ) ;
params . add ( workMins ) ;
params . add ( signInDate ) ;
params . add ( signInTime ) ;
params . add ( signInId . length ( ) = = 0 ? null : signInId ) ;
params . add ( signOutDate ) ;
params . add ( signOutTime ) ;
params . add ( signOutId . length ( ) = = 0 ? null : signOutId ) ;
kqLog . info ( " format in >>>>>userId " + userId + " kqDate== " + kqDate + " :hostIps: " + hostIps + " :uuid:: " + uuid
+ " :signInDate: " + signInDate + " :signInTime:: " + signInTime + " :signOutDate: " + signOutDate + " :signOutTime:: " + signOutTime ) ;
params . add ( signMins ) ;
params . add ( attendanceMins ) ;
params . add ( beLateMins ) ;
params . add ( graveBeLateMins ) ;
params . add ( leaveEarlyMins ) ;
params . add ( graveLeaveEarlyMins ) ;
params . add ( absenteeismMins ) ;
params . add ( forgotCheckMins ) ;
params . add ( leaveMins ) ;
params . add ( JSONObject . toJSONString ( leaveInfo ) ) ;
params . add ( evectionMins ) ;
params . add ( outMins ) ;
params . add ( forgotBeginWorkCheckMins ) ;
params . add ( JSONObject . toJSONString ( otherinfo ) ) ;
Map < String , Object > definedFieldInfo = new KQFormatBiz ( ) . getDefinedField ( ) ;
String [ ] definedFields = Util . splitString ( Util . null2String ( definedFieldInfo . get ( " definedField " ) ) , " , " ) ;
KQReportFieldComInfo kqReportFieldComInfo = new KQReportFieldComInfo ( ) ;
for ( int tmpIdx = 0 ; tmpIdx < definedFields . length ; tmpIdx + + ) {
String fieldname = definedFields [ tmpIdx ] ;
// System.out.println("fieldname=="+fieldname);
String fieldid = KQReportFieldComInfo . field2Id . get ( fieldname ) ;
String formula = kqReportFieldComInfo . getFormula ( fieldid ) ;
if ( formula . length ( ) = = 0 ) continue ;
String expression = formula ;
Pattern pattern = Pattern . compile ( " \\ $ \\ {[^}]+ \\ } " ) ;
Matcher matcher = pattern . matcher ( expression ) ;
Map < String , Object > env = new HashMap < > ( ) ;
String keyname = " " ;
while ( matcher . find ( ) ) {
String key = matcher . group ( 0 ) ;
keyname = key . substring ( 2 , key . length ( ) - 1 ) . trim ( ) ;
expression = matcher . replaceAll ( keyname ) ;
env . put ( keyname , keyname . equals ( " beLateMins " ) ? beLateMins : leaveEarlyMins ) ;
}
Expression compiledExp = AviatorEvaluator . compile ( expression , true ) ;
String value = Util . null2String ( compiledExp . execute ( env ) ) ;
params . add ( value ) ;
if ( value . equals ( " 1 " ) ) {
params . add ( keyname . equals ( " beLateMins " ) ? beLateMins : leaveEarlyMins ) ;
} else {
params . add ( " 0 " ) ;
}
}
kqLog . info ( " format in >>>>>userId " + userId + " kqDate== " + kqDate + " :hostIps: " + hostIps + " :uuid:: " + uuid
+ " :params: " + JSON . toJSONString ( params ) ) ;
2025-02-06 10:57:38 +08:00
Long id = IdGenerator . generate ( ) ;
params . add ( workTime . getDayType ( ) ) ;
params . add ( date ) ;
params . add ( date ) ;
params . add ( id ) ;
params . add ( JSONObject . toJSONString ( flowinfo ) ) ;
// if(isAmAbsent){
// params.add(1);
// }else {
// params.add(0);
// }
// if(isPmAbsent){
// params.add(1);
// }else {
// params.add(0);
// }
params . add ( on_absenteeismMins ) ;
params . add ( off_absenteeismMins ) ;
2024-07-31 16:04:24 +08:00
lsParam . add ( params ) ;
2025-02-06 10:57:38 +08:00
resetAttendRepeatBeans ( attendRepeatBeans ) ;
//这个只是记录每个时段消耗的哺乳假,用完就清掉
KQRepeatLengthContext . removeRepeatBeanLinkRange ( ) ;
//把每一段的请假时长记录一下
allLeaveMins + = leaveMins ;
}
KQRepeatLengthContext . removeRepeatBean ( ) ;
KQRepeatLengthContext . clear ( ) ;
KQRepeatLengthContext . removeRepeatBeanLinkRange ( ) ;
if ( repeatLeaveMins > 0 ) {
if ( allLeaveMins = = 0 ) {
//哺乳假 有这种情况, 没有迟到, 也没有早退, allLeaveMins未0的情况
if ( CollectionUtils . isNotEmpty ( lsParam ) ) {
List < Object > tmp = lsParam . get ( 0 ) ;
//目前请假时长是24位, 以后有新增调整列一定要记得改这里的
tmp . set ( 24 , repeatLeaveMins ) ;
}
}
2024-07-31 16:04:24 +08:00
}
} catch ( Exception e ) {
2025-02-06 10:57:38 +08:00
kqLog . info ( " 考勤格式化生成数据报错:KQFormatData: " ) ;
StringWriter errorsWriter = new StringWriter ( ) ;
e . printStackTrace ( new PrintWriter ( errorsWriter ) ) ;
kqLog . info ( errorsWriter . toString ( ) ) ;
2024-07-31 16:04:24 +08:00
}
return lsParam ;
}
2025-02-06 10:57:38 +08:00
/ * *
* 哺乳假被当前规则用完了之后 , 需要把late和early的已休时长重置一下
* 为什么要在这里搞 , 因为前面迟到 , 严重迟到在判断的时候都需要用到原始数据 , 只有前面的判断都用完了 , 最后才能去更新
* @param attendRepeatBeans
* /
private void resetAttendRepeatBeans ( List < KQRepeatBean > attendRepeatBeans ) {
if ( CollectionUtils . isEmpty ( attendRepeatBeans ) ) {
return ;
}
KQRepeatBean attendRepeatBeanLink = KQRepeatLengthContext . getRepeatBeanLink ( ) ;
if ( attendRepeatBeanLink = = null ) {
return ;
}
Long repeatLateLink = attendRepeatBeanLink . getRepeatLateLink ( ) ;
Long repeatEarlyLink = attendRepeatBeanLink . getRepeatEarlyLink ( ) ;
for ( int i = 0 ; i < attendRepeatBeans . size ( ) ; i + + ) {
KQRepeatBean attendRepeatBean = attendRepeatBeans . get ( i ) ;
Long repeatEarly = attendRepeatBean . getRepeatEarly ( ) ;
Long repeatLate = attendRepeatBean . getRepeatLate ( ) ;
if ( repeatLateLink ! = null & & repeatLateLink > 0 & & repeatLate ! = null & & repeatLate > 0 ) {
if ( repeatLateLink > repeatLate ) {
repeatLateLink = repeatLateLink - repeatLate ;
attendRepeatBean . setRepeatLateLink ( repeatLate ) ;
} else {
attendRepeatBean . setRepeatLateLink ( repeatLateLink ) ;
repeatLateLink = 0L ;
}
}
if ( repeatEarlyLink ! = null & & repeatEarlyLink > 0 & & repeatEarly ! = null & & repeatEarly > 0 ) {
if ( repeatEarlyLink > repeatEarly ) {
repeatEarlyLink = repeatEarlyLink - repeatEarly ;
attendRepeatBean . setRepeatEarlyLink ( repeatEarly ) ;
} else {
attendRepeatBean . setRepeatEarlyLink ( repeatEarlyLink ) ;
repeatEarlyLink = 0L ;
}
}
}
}
/ * *
* 实际出勤里也要去除哺乳假的时长
* @return
* /
private long getRepeatLeaveTime ( ) {
long repeatLeaveTime = 0L ;
KQRepeatBean attendRepeatBeanLink = KQRepeatLengthContext . getRepeatBeanLinkRange ( ) ;
if ( attendRepeatBeanLink = = null ) {
return repeatLeaveTime ;
}
Long repeatLateLink = attendRepeatBeanLink . getRepeatLateLink ( ) ;
Long repeatEarlyLink = attendRepeatBeanLink . getRepeatEarlyLink ( ) ;
if ( repeatLateLink > 0 ) {
repeatLeaveTime = repeatLateLink ;
}
if ( repeatEarlyLink > 0 ) {
if ( repeatLeaveTime > 0 ) {
repeatLeaveTime + = repeatEarlyLink ;
} else {
repeatLeaveTime = repeatEarlyLink ;
}
}
return repeatLeaveTime ;
}
/ * *
* 哺乳假针对异常时长部分的处理
* @param attendRepeatBeans
* @param repeatLength
* @param type
* @return
* /
private long handleRepeatLength ( List < KQRepeatBean > attendRepeatBeans , long repeatLength , String type ) {
if ( repeatLength < = 0 ) {
return repeatLength ;
}
Long oriLength = repeatLength ;
try {
// 当天总消耗哺乳假 用于当天迟到早退
KQRepeatBean attendRepeatBeanLink = KQRepeatLengthContext . getRepeatBeanLink ( ) ;
// 当前时段消耗哺乳假,用于计算缺勤
KQRepeatBean attendRepeatBeanLinkRange = KQRepeatLengthContext . getRepeatBeanLinkRange ( ) ;
if ( attendRepeatBeanLink = = null ) {
attendRepeatBeanLink = new KQRepeatBean ( ) ;
}
if ( attendRepeatBeanLinkRange = = null ) {
attendRepeatBeanLinkRange = new KQRepeatBean ( ) ;
}
Long repeatLateLink = attendRepeatBeanLink . getRepeatLateLink ( ) ;
if ( repeatLateLink = = null ) {
repeatLateLink = 0L ;
}
Long repeatEarlyLink = attendRepeatBeanLink . getRepeatEarlyLink ( ) ;
if ( repeatEarlyLink = = null ) {
repeatEarlyLink = 0L ;
}
Long repeatLateLinkRange = attendRepeatBeanLinkRange . getRepeatLateLink ( ) ;
if ( repeatLateLinkRange = = null ) {
repeatLateLinkRange = 0L ;
}
Long repeatEarlyLinkRange = attendRepeatBeanLinkRange . getRepeatEarlyLink ( ) ;
if ( repeatEarlyLinkRange = = null ) {
repeatEarlyLinkRange = 0L ;
}
if ( CollectionUtils . isNotEmpty ( attendRepeatBeans ) ) {
for ( int i = 0 ; i < attendRepeatBeans . size ( ) ; i + + ) {
KQRepeatBean attendRepeatBean = attendRepeatBeans . get ( i ) ;
if ( oriLength < = 0 ) {
attendRepeatBeanLink . setRepeatLateLink ( repeatLateLink ) ;
attendRepeatBeanLink . setRepeatEarlyLink ( repeatEarlyLink ) ;
KQRepeatLengthContext . setRepeatBeanLink ( attendRepeatBeanLink ) ;
attendRepeatBeanLinkRange . setRepeatLateLink ( repeatLateLinkRange ) ;
attendRepeatBeanLinkRange . setRepeatEarlyLink ( repeatEarlyLinkRange ) ;
KQRepeatLengthContext . setRepeatBeanLinkRange ( attendRepeatBeanLinkRange ) ;
return oriLength ;
}
if ( " late " . equals ( type ) ) {
Long repeatLate = attendRepeatBean . getRepeatLate ( ) ;
Long repeatLatTmp = attendRepeatBean . getRepeatLateLink ( ) ;
if ( repeatLate ! = null ) {
if ( repeatLatTmp ! = null & & repeatLatTmp > 0 ) {
repeatLate = repeatLate - repeatLatTmp ;
repeatLate = repeatLate < 0 ? 0 : repeatLate ;
}
oriLength = oriLength - repeatLate ;
oriLength = oriLength < 0 ? 0 : oriLength ;
if ( oriLength = = 0 ) {
//如果异常已经被每天重复时长完全抵扣了, 那么需要更新下AttendRepeatBeanLink
repeatLateLink + = repeatLength ;
repeatLateLinkRange + = repeatLength ;
} else {
repeatLateLink + = repeatLate ;
repeatLateLinkRange + = repeatLate ;
}
}
}
if ( " early " . equals ( type ) ) {
Long repeatEarly = attendRepeatBean . getRepeatEarly ( ) ;
Long repeatEarTmp = attendRepeatBean . getRepeatEarlyLink ( ) ;
if ( repeatEarly ! = null ) {
if ( repeatEarTmp ! = null & & repeatEarTmp > 0 ) {
repeatEarly = repeatEarly - repeatEarTmp ;
repeatEarly = repeatEarly < 0 ? 0 : repeatEarly ;
}
oriLength = oriLength - repeatEarly ;
oriLength = oriLength < 0 ? 0 : oriLength ;
if ( oriLength = = 0 ) {
//如果异常已经被每天重复时长完全抵扣了, 那么需要更新下AttendRepeatBean
repeatEarlyLink + = repeatLength ;
repeatEarlyLinkRange + = repeatLength ;
} else {
repeatEarlyLink + = repeatEarly ;
repeatEarlyLinkRange + = repeatEarly ;
}
}
}
}
}
attendRepeatBeanLink . setRepeatLateLink ( repeatLateLink ) ;
attendRepeatBeanLink . setRepeatEarlyLink ( repeatEarlyLink ) ;
KQRepeatLengthContext . setRepeatBeanLink ( attendRepeatBeanLink ) ;
attendRepeatBeanLinkRange . setRepeatLateLink ( repeatLateLinkRange ) ;
attendRepeatBeanLinkRange . setRepeatEarlyLink ( repeatEarlyLinkRange ) ;
KQRepeatLengthContext . setRepeatBeanLinkRange ( attendRepeatBeanLinkRange ) ;
} catch ( Exception e ) {
kqLog . error ( " handleRepeatLength " , e ) ;
}
return oriLength ;
}
public int handleRepeatWorkFlowInfo ( List < Object > workFlowRepeat , String repeatKey ) {
int repeatLeaveMins = 0 ;
for ( int j = 0 ; workFlowRepeat ! = null & & j < workFlowRepeat . size ( ) ; j + + ) {
Map < String , Object > data = ( Map < String , Object > ) workFlowRepeat . get ( j ) ;
String repeatType = Util . null2String ( data . get ( " repeatType " ) ) ;
String repeatLate = Util . null2String ( data . get ( " repeatLate " ) ) ;
String repeatEarly = Util . null2String ( data . get ( " repeatEarly " ) ) ;
String newleavetype = Util . null2String ( data . get ( " newleavetype " ) ) ;
String leavetypeKey = repeatKey + " _ " + newleavetype ;
KQRepeatBean repeatBean = new KQRepeatBean ( ) ;
repeatBean . setRepeatType ( repeatType ) ;
if ( " 0 " . equals ( repeatType ) ) {
if ( repeatLate . length ( ) > 0 ) {
repeatBean . setRepeatLate ( new Double ( Double . valueOf ( repeatLate ) ) . longValue ( ) ) ;
repeatLeaveMins + = new Double ( Double . valueOf ( repeatLate ) ) . longValue ( ) ;
}
}
if ( " 1 " . equals ( repeatType ) ) {
if ( repeatEarly . length ( ) > 0 ) {
repeatBean . setRepeatEarly ( new Double ( Double . valueOf ( repeatEarly ) ) . longValue ( ) ) ;
repeatLeaveMins + = new Double ( Double . valueOf ( repeatEarly ) ) . longValue ( ) ;
}
}
if ( " 2 " . equals ( repeatType ) ) {
if ( repeatLate . length ( ) > 0 ) {
repeatBean . setRepeatLate ( new Double ( Double . valueOf ( repeatLate ) ) . longValue ( ) ) ;
repeatLeaveMins + = new Double ( Double . valueOf ( repeatLate ) ) . longValue ( ) ;
}
if ( repeatEarly . length ( ) > 0 ) {
repeatBean . setRepeatEarly ( new Double ( Double . valueOf ( repeatEarly ) ) . longValue ( ) ) ;
repeatLeaveMins + = new Double ( Double . valueOf ( repeatEarly ) ) . longValue ( ) ;
}
}
KQRepeatLengthContext . setKQRepeatBean ( repeatKey , repeatBean ) ;
KQRepeatLengthContext . setKQRepeatBean ( leavetypeKey , repeatBean ) ;
}
return repeatLeaveMins ;
}
2024-07-31 16:04:24 +08:00
public void setWriteLog ( boolean writeLog ) {
this . writeLog = writeLog ;
}
public Map < String , Object > getLogInfo ( ) {
return logInfo ;
}
public void formatDateByKQDate ( String kqdate ) {
KQFormatBiz kqFormatBiz = new KQFormatBiz ( ) ;
kqFormatBiz . formatDateByKQDate ( kqdate ) ;
}
public void formatDateByGroupId ( String groupid , String kqdate ) {
KQFormatBiz kqFormatBiz = new KQFormatBiz ( ) ;
kqFormatBiz . formatDateByGroupId ( groupid , kqdate ) ;
}
public void formatDate ( String resourceid , String kqdate ) {
KQFormatBiz kqFormatBiz = new KQFormatBiz ( ) ;
kqFormatBiz . formatDate ( resourceid , kqdate ) ;
}
public void delFormatData ( String resourceid , String kqdate ) {
KQFormatBiz kqFormatBiz = new KQFormatBiz ( ) ;
kqFormatBiz . delFormatData ( resourceid , kqdate ) ;
}
/ * *
* 非工作日格式化考勤报表
* @param userId
* @param kqDate
* @param nonlsParam
* @param workTime
* @param workFlowInfo
* /
public void formatNonWork ( String userId , String kqDate , List < Object > nonlsParam , WorkTimeEntity workTime , Map < String , Object > workFlowInfo ) {
String signInId = " " ;
String signInDate = " " ;
String signInTime = " " ;
String signOutId = " " ;
String signOutDate = " " ;
String signOutTime = " " ;
int beginIdx = 0 ;
int endIdx = 0 ;
int leaveMins = 0 ; //请假时长
2025-02-06 10:57:38 +08:00
Map < String , Object > flowinfo = new HashMap < > ( ) ; //流程信息
2024-07-31 16:04:24 +08:00
Map < String , Object > leaveInfo = new HashMap < > ( ) ; //请假信息
int evectionMins = 0 ; //出差时长
int outMins = 0 ; //公出时长
int otherMins = 0 ; //异常流程时长
int [ ] dayMins = new int [ 2880 ] ; //一天所有分钟数
List < Object > workFlow = null ;
String dateKey = userId + " | " + kqDate ;
KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo ( ) ;
String preDate = DateUtil . addDate ( kqDate , - 1 ) ; //上一天日期
String nextDate = DateUtil . addDate ( kqDate , 1 ) ; //下一天日期
WorkTimeEntity pre_workTime = new KQWorkTime ( ) . getWorkTime ( userId , preDate ) ;
List < TimeScopeEntity > pre_lsSignTime = new ArrayList < > ( ) ;
if ( pre_workTime ! = null ) {
pre_lsSignTime = pre_workTime . getSignTime ( ) ; //允许打卡时间
pre_lsSignTime = pre_lsSignTime ! = null ? pre_lsSignTime : new ArrayList < > ( ) ;
}
WorkTimeEntity next_workTime = new KQWorkTime ( ) . getWorkTime ( userId , nextDate ) ;
List < TimeScopeEntity > next_lsSignTime = new ArrayList < > ( ) ;
if ( next_workTime ! = null ) {
next_lsSignTime = next_workTime . getSignTime ( ) ; //允许打卡时间
next_lsSignTime = next_lsSignTime ! = null ? next_lsSignTime : new ArrayList < > ( ) ;
}
List < Object > lsCheckInfo = new KQFormatSignData ( ) . getNonWorkSignInfo ( userId , preDate , kqDate , pre_lsSignTime , next_lsSignTime ) ;
for ( int j = 0 ; lsCheckInfo ! = null & & j < lsCheckInfo . size ( ) ; j + + ) {
Map < String , Object > checkInfo = ( Map < String , Object > ) lsCheckInfo . get ( j ) ;
String signStatus = Util . null2String ( checkInfo . get ( " signStatus " ) ) ;
String signId = Util . null2String ( checkInfo . get ( " signId " ) ) ;
String signDate = Util . null2String ( checkInfo . get ( " signDate " ) ) ;
String signTime = Util . null2String ( checkInfo . get ( " signTime " ) ) ;
if ( checkInfo . get ( " signType " ) . equals ( " 1 " ) ) { //签到
signInId = signId ;
signInDate = signDate ;
signInTime = signTime ;
} else if ( checkInfo . get ( " signType " ) . equals ( " 2 " ) ) { //签退
signOutId = signId ;
signOutDate = signDate ;
signOutTime = signTime ;
}
}
if ( workFlowInfo . get ( dateKey ) ! = null ) {
workFlow = ( List < Object > ) workFlowInfo . get ( dateKey ) ;
}
for ( int j = 0 ; workFlow ! = null & & j < workFlow . size ( ) ; j + + ) {
Map < String , Object > data = ( Map < String , Object > ) workFlow . get ( j ) ;
String flowType = Util . null2String ( data . get ( " flowtype " ) ) ;
String newLeaveType = Util . null2String ( data . get ( " newleavetype " ) ) ;
2025-02-06 10:57:38 +08:00
String begintime = Util . null2String ( data . get ( " begintime " ) ) ;
String endtime = Util . null2String ( data . get ( " endtime " ) ) ;
beginIdx = kqTimesArrayComInfo . getArrayindexByTimes ( begintime ) ;
endIdx = kqTimesArrayComInfo . getArrayindexByTimes ( endtime ) ;
if ( beginIdx > endIdx ) {
continue ;
}
Map < String , String > flowMap = Maps . newHashMap ( ) ;
flowMap . put ( " newLeaveType " , newLeaveType ) ;
flowMap . put ( " begintime " , begintime ) ;
flowMap . put ( " endtime " , endtime ) ;
List < Map < String , String > > flowMapList = Lists . newArrayList ( ) ;
if ( flowinfo . containsKey ( flowType ) ) {
List < Map < String , String > > tmpFlowMapList = ( List < Map < String , String > > ) flowinfo . get ( flowType ) ;
tmpFlowMapList . add ( flowMap ) ;
} else {
flowMapList . add ( flowMap ) ;
flowinfo . put ( flowType , flowMapList ) ;
}
2024-07-31 16:04:24 +08:00
if ( flowType . equals ( FlowReportTypeEnum . EVECTION . getFlowType ( ) ) ) {
Arrays . fill ( dayMins , beginIdx , endIdx , 7 ) ; //出差抵扣时段标识 7
} else if ( flowType . equals ( FlowReportTypeEnum . OUT . getFlowType ( ) ) ) {
Arrays . fill ( dayMins , beginIdx , endIdx , 8 ) ; //公出抵扣时段标识 8
} else if ( flowType . equalsIgnoreCase ( FlowReportTypeEnum . LEAVE . getFlowType ( ) ) ) {
if ( endIdx > beginIdx ) {
Arrays . fill ( dayMins , beginIdx , endIdx , 5 ) ; //流程抵扣时段标识 5
int tmpBeginIdx = beginIdx ;
int tmpEndIdx = endIdx ;
Integer val = 0 ;
if ( leaveInfo . get ( newLeaveType ) = = null ) {
leaveInfo . put ( newLeaveType , val ) ;
} else {
val = ( Integer ) leaveInfo . get ( newLeaveType ) ;
}
if ( tmpEndIdx > tmpBeginIdx ) {
leaveInfo . put ( newLeaveType , val + ( tmpEndIdx - tmpBeginIdx ) ) ;
}
}
} else {
if ( endIdx > beginIdx ) {
Arrays . fill ( dayMins , beginIdx , endIdx , 99 ) ; //异常流程抵扣时段标识99
}
}
}
for ( int j = 0 ; j < 2880 ; j + + ) {
switch ( dayMins [ j ] ) {
case 5 :
leaveMins + + ;
break ;
case 7 :
evectionMins + + ;
break ;
case 8 :
outMins + + ;
break ;
case 99 :
otherMins + + ;
break ;
default :
break ;
}
}
nonlsParam . add ( userId ) ;
nonlsParam . add ( kqDate ) ;
nonlsParam . add ( workTime . getGroupId ( ) ) ;
nonlsParam . add ( 0 ) ;
nonlsParam . add ( signInDate ) ;
nonlsParam . add ( signInTime ) ;
nonlsParam . add ( signInId . length ( ) = = 0 ? null : signInId ) ;
nonlsParam . add ( signOutDate ) ;
nonlsParam . add ( signOutTime ) ;
nonlsParam . add ( signOutId . length ( ) = = 0 ? null : signOutId ) ;
nonlsParam . add ( leaveMins ) ;
nonlsParam . add ( JSONObject . toJSONString ( leaveInfo ) ) ;
nonlsParam . add ( evectionMins ) ;
nonlsParam . add ( outMins ) ;
2025-02-06 10:57:38 +08:00
nonlsParam . add ( workTime . getDayType ( ) ) ;
Timestamp date = new Timestamp ( System . currentTimeMillis ( ) ) ;
Long id = IdGenerator . generate ( ) ;
nonlsParam . add ( date ) ;
nonlsParam . add ( date ) ;
nonlsParam . add ( id ) ;
nonlsParam . add ( JSONObject . toJSONString ( flowinfo ) ) ;
2024-07-31 16:04:24 +08:00
}
}