package com.engine.xmgsecond.util ;
import com.engine.xmgsecond.entity.KqFormatTotal ;
import weaver.conn.RecordSet ;
import weaver.general.Util ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.Optional ;
import java.util.concurrent.atomic.AtomicInteger ;
/ * *
* @Author liang . cheng
* @Date 2025 / 5 / 14 16 : 16
* @Description :
* @Version 1.0
* /
public class KqCalulateUtil {
/ * *
* @Description : 时 间 范 围 内 考 勤 报 表 增 加 缺 勤 天 数
* @Author : liang . cheng
* @Date : 2025 / 5 / 14 16 : 22
* @param : [ resourceId , fromDate , toDate ]
* @return : java . util . List < com . engine . xmgsecond . entity . KqFormatTotal >
* /
public static List < KqFormatTotal > abnormalAttendance ( String resourceId , String fromDate , String toDate ) {
RecordSet rs = new RecordSet ( ) ;
List < KqFormatTotal > kqFormatTotalList = new ArrayList < > ( ) ;
rs . executeQuery ( "select resourceid, forgotCheck, absenteeism, beLateMins, gravebeLateMins, leaveEearly, " +
" graveLeaveEarly from kq_format_total where resourceid = ? and kqdate >= '" + fromDate + "' and kqdate <= '" + toDate + "'" , resourceId ) ;
while ( rs . next ( ) ) {
boolean isAbsence ;
int absenteeism = Util . getIntValue ( rs . getString ( "absenteeism" ) ) ;
int forgotCheck = Util . getIntValue ( rs . getString ( "forgotCheck" ) ) ;
int beLateMins = Util . getIntValue ( rs . getString ( "beLateMins" ) , 0 ) ;
int gravebeLateMins = Util . getIntValue ( rs . getString ( "gravebeLateMins" ) , 0 ) ;
int leaveEearly = Util . getIntValue ( rs . getString ( "leaveEearly" ) ) ;
int graveLeaveEarly = Util . getIntValue ( rs . getString ( "graveLeaveEarly" ) ) ;
//规则1
isAbsence = isPositive ( absenteeism ) | |
isPositive ( forgotCheck ) | |
sumPositive ( leaveEearly , graveLeaveEarly ) > 0 ;
kqFormatTotalList . add ( KqFormatTotal . builder ( )
. resourceId ( Util . getIntValue ( rs . getString ( "resourceid" ) ) )
. beLateMins ( beLateMins )
. gravebeLateMins ( gravebeLateMins )
. isAbsence ( isAbsence )
. absenceDays ( isAbsence ? 1 : 0 )
. build ( ) ) ;
}
//规则2
AtomicInteger graceCounter = new AtomicInteger ( 0 ) ;
kqFormatTotalList . forEach ( record - > {
if ( ! record . isAbsence ( ) ) {
int lateMinutes = sumNullSafe ( record . getBeLateMins ( ) , record . getGravebeLateMins ( ) ) ;
record . setAbsenceDays ( calculateAbsenceDays ( lateMinutes , graceCounter ) ) ;
}
} ) ;
rs . writeLog ( "kqFormatTotalList2:" + kqFormatTotalList . toString ( ) ) ;
return kqFormatTotalList ;
}
/ * *
* @Description : 时 间 范 围 内 考 勤 报 表 增 加 夜 班 天 数
* @Author : liang . cheng
* @Date : 2025 / 5 / 16 0 9 : 28
* @param : [ resourceId , fromDate , toDate ]
* @return : int
* /
public static int nightWorkSums ( String resourceId , String fromDate , String toDate ) {
RecordSet rs = new RecordSet ( ) ;
int count = 0 ;
rs . executeQuery ( " select a.kqdate,a.serialid,a.belatemins,a.leaveearlymins,a.absenteeismmins,a.forgotcheckMins,a.leaveMins,\n" +
" a.evectionMins,a.outMins,b.serial,b.is_rest,b.shiftonoffworkcount from kq_format_total a \n" +
" left join kq_ShiftManagement b on a.serialid = b.id where a.resourceid = ? and a.kqdate >= '" + fromDate + "' and a.kqdate <= '" + toDate + "'" , resourceId ) ;
while ( rs . next ( ) ) {
int serialid = Util . getIntValue ( rs . getString ( "serialid" ) ) ;
String kqdate = Util . null2String ( rs . getString ( "kqdate" ) ) ;
if ( serialid = = - 1 ) {
continue ;
}
int isRest = Util . getIntValue ( rs . getString ( "is_rest" ) ) ;
if ( isRest = = 1 ) {
//1.休息班
if ( Util . getIntValue ( rs . getString ( "shiftonoffworkcount" ) ) = = 1 ) {
//一天一次上下班卡
if ( calculateClockTime ( resourceId , kqdate , serialid ) ) {
count = count + 1 ;
}
}
} else {
//2.非休息班
String serial = Util . null2String ( rs . getString ( "serial" ) ) ;
if ( serial . contains ( "夜班" ) ) {
int beLateMins = Util . getIntValue ( rs . getString ( "beLateMins" ) , 0 ) ;
int leaveearlymins = Util . getIntValue ( rs . getString ( "leaveearlymins" ) , 0 ) ;
int absenteeismmins = Util . getIntValue ( rs . getString ( "absenteeismmins" ) , 0 ) ;
int forgotcheckMins = Util . getIntValue ( rs . getString ( "forgotcheckMins" ) , 0 ) ;
int leaveMins = Util . getIntValue ( rs . getString ( "leaveMins" ) , 0 ) ;
int evectionMins = Util . getIntValue ( rs . getString ( "evectionMins" ) , 0 ) ;
int outMins = Util . getIntValue ( rs . getString ( "outMins" ) , 0 ) ;
if ( beLateMins = = 0 & & leaveearlymins = = 0 & & absenteeismmins = = 0 & & forgotcheckMins = = 0
& & leaveMins = = 0 & & evectionMins = = 0 & & outMins = = 0 ) {
count = count + 1 ;
}
}
}
}
return count ;
}
public static boolean isPositive ( Integer num ) {
return Optional . ofNullable ( num ) . orElse ( 0 ) > 0 ;
}
// 辅助方法:安全求和(处理 null 情况)
public static int sumPositive ( Integer a , Integer b ) {
return Optional . ofNullable ( a ) . orElse ( 0 ) + Optional . ofNullable ( b ) . orElse ( 0 ) ;
}
private static double calculateAbsenceDays ( int lateMinutes , AtomicInteger graceCounter ) {
if ( lateMinutes < = 0 ) {
return 0 ;
}
if ( graceCounter . get ( ) < 3 & & lateMinutes > 0 & & lateMinutes < = 15 ) {
graceCounter . incrementAndGet ( ) ;
return 0 ;
}
return ( lateMinutes > 0 & & lateMinutes < = 240 ) ? 0.5 : 1 ;
}
private static int sumNullSafe ( Integer a , Integer b ) {
return Optional . ofNullable ( a ) . orElse ( 0 ) + Optional . ofNullable ( b ) . orElse ( 0 ) ;
}
public static boolean calculateClockTime ( String resourceId , String kqDate , int serialid ) {
RecordSet rs = new RecordSet ( ) ;
rs . executeQuery ( "select resourceid,kqdate,signintime,signouttime from kq_format_detail where kqdate = '" + kqDate + "' and resourceid = ? and serialid = ? \n" +
" and signintime >= '18:00:00' and signintime <= '20:30:00' and signouttime >= '05:30:00'" , resourceId , serialid ) ;
return rs . getCounts ( ) > 0 ;
}
}