@ -14,6 +14,7 @@ import lombok.extern.slf4j.Slf4j;
import weaver.general.TimeUtil ;
import weaver.general.Util ;
import java.time.ZoneOffset ;
import java.util.* ;
import java.util.stream.Collectors ;
@ -54,7 +55,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
Map < String , String > detailItem ;
String sql = "" ;
//获取作用时段包含计划加班的加班类型的考勤项目集合
sql = "select id,mc, bddrqlx, jbqsfzs, xzzjbsc, rzdjbxss, zzdjbxss, yzdjbxss, zysd, ccclfs,zdkcjcxxsc from uf_jcl_kq_kqxm where xmlx = ?";
sql = "select id,mc, bddrqlx, jbqsfzs, xzzjbsc, rzdjbxss, zzdjbxss, yzdjbxss, zysd, ccclfs,zdkcjcxxsc ,sfkcxxdsc from uf_jcl_kq_kqxm where xmlx = ?";
List < Map < String , Object > > jblxAttendanceList = DbTools . getSqlToList ( sql , AttendanceItemTypeEnum . WORK_OVERTIME . getKey ( ) ) ;
jblxAttendanceList = jblxAttendanceList . stream ( ) . filter ( f - > Util . null2String ( f . get ( "zysd" ) ) . contains ( WorkForTimeEnum . PLAN_WORK_OVERTIME . getKey ( ) ) ) . collect ( Collectors . toList ( ) ) ;
//获取人员id和姓名信息
@ -95,10 +96,11 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
int overtimeMinutes = DateUtil . getBetWeenMinutes ( date + " " + startTime , realEndDate + " " + endTime ) ;
detailItem . put ( "jbsc" , String . format ( "%.2f" , overtimeMinutes / 60.0 ) ) ;
//根据班次数据,设置归属日期
Map < String , List < Map < String , Object > > > bcDetailListToDateMap = new HashMap < > ( ) ;
//获取当天班次id
String currentDayBcId = Util . null2String ( dateToBcxxMap . get ( date ) ) . split ( "-" ) [ 0 ] ;
//获取当天班次开始时间和结束时间
String currentDayStartToEnd = getBcStartAndEndTime ( date , currentDayBcId , workBdlxList );
String currentDayStartToEnd = getBcStartAndEndTime ( date , currentDayBcId , workBdlxList , bcDetailListToDateMap );
String currentDayStartTime = ! "" . equals ( currentDayStartToEnd ) ? currentDayStartToEnd . split ( "," ) [ 0 ] : "" ;
String currentDayEndTime = ! "" . equals ( currentDayStartToEnd ) ? currentDayStartToEnd . split ( "," ) [ 1 ] : "" ;
//判断当天班次是否为休息班次、且“休息班打卡自动加班”未勾选
@ -107,7 +109,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//获取前1天班次id
String beforeDayBcId = Util . null2String ( dateToBcxxMap . get ( DateUtil . beforeDay ( date , 1 ) ) ) . split ( "-" ) [ 0 ] ;
//获取前1天班次开始时间和结束时间
String beforeDayStartToEnd = getBcStartAndEndTime ( DateUtil . beforeDay ( date , 1 ) , beforeDayBcId , workBdlxList );
String beforeDayStartToEnd = getBcStartAndEndTime ( DateUtil . beforeDay ( date , 1 ) , beforeDayBcId , workBdlxList , bcDetailListToDateMap );
String beforeDayStartTime = ! "" . equals ( beforeDayStartToEnd ) ? beforeDayStartToEnd . split ( "," ) [ 0 ] : "" ;
String beforeDayEndTime = ! "" . equals ( beforeDayStartToEnd ) ? beforeDayStartToEnd . split ( "," ) [ 1 ] : "" ;
//判断前1天班次是否为休息班次、且“休息班打卡自动加班”未勾选
@ -116,7 +118,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//获取次日班次id
String nextDayBcId = Util . null2String ( dateToBcxxMap . get ( DateUtil . AfterDay ( date , 1 ) ) ) . split ( "-" ) [ 0 ] ;
//获取次日班次开始时间和结束时间
String nextDayStartToEnd = getBcStartAndEndTime ( DateUtil . AfterDay ( date , 1 ) , nextDayBcId , workBdlxList );
String nextDayStartToEnd = getBcStartAndEndTime ( DateUtil . AfterDay ( date , 1 ) , nextDayBcId , workBdlxList , bcDetailListToDateMap );
String nextDayStartTime = ! "" . equals ( nextDayStartToEnd ) ? nextDayStartToEnd . split ( "," ) [ 0 ] : "" ;
String nextDayEndTime = ! "" . equals ( nextDayStartToEnd ) ? nextDayStartToEnd . split ( "," ) [ 1 ] : "" ;
//判断次日班次是否为休息班次、且“休息班打卡自动加班”未勾选
@ -133,8 +135,25 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
boolean nextDayOverLap = false ;
//20240820需求变更, 非休息班次, 加班区间完全处于休息班段内时, 允许申请加班计划, 并在匹配加班类型时避开勾选了去除休息时段的加班类型
boolean onlyInRestPeriod = false ;
//20240924需求变更, 区分“休息”、“就餐”、“休息和就餐”三类时段的时长和要求, 并且对加班区间的首尾如果有不许累计时长的以上三类区间, 要灵活修改加班区间的首尾时间点
boolean onlyInDinePeriod = false ;
boolean onlyInRestAndDinePeriod = false ;
boolean borderHaveRest = false ;
boolean allowOvertimeSign = true ;
Map < String , Object > overtimeBorderInfo = new HashMap < > ( ) ;
overtimeBorderInfo . put ( "onlyInRestPeriod" , false ) ;
overtimeBorderInfo . put ( "onlyInDinePeriod" , false ) ;
overtimeBorderInfo . put ( "onlyInRestAndDinePeriod" , false ) ;
overtimeBorderInfo . put ( "borderHaveRest" , false ) ;
overtimeBorderInfo . put ( "allowOvertimeSign" , true ) ;
//20240814需求变更。非休息班次, 出现重叠时间, 自动调整加班开始或结束时间, 并返回提示
Map < String , String > adjustInfo = new HashMap < > ( ) ;
adjustInfo . put ( "startWithAdjust" , date + " " + startTime ) ;
adjustInfo . put ( "endWithAdjust" , realEndDate + " " + endTime ) ;
adjustInfo . put ( "startDate" , date ) ;
adjustInfo . put ( "startTime" , startTime ) ;
adjustInfo . put ( "endDate" , realEndDate ) ;
adjustInfo . put ( "endTime" , endTime ) ;
if ( ! "" . equals ( currentDayStartToEnd ) ) {
//1-加班时间段处于前一日下班后和当日上班前
beforeToCurrentDay = ( "" . equals ( beforeDayEndTime ) | | beforeDayEndTime . compareTo ( date + " " + startTime ) < = 0 ) & & currentDayStartTime . compareTo ( realEndDate + " " + endTime ) > = 0 ;
@ -149,10 +168,16 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
int beforeDayDiffMinutes = ! "" . equals ( beforeDayEndTime ) ? DateUtil . getBetWeenMinutes ( beforeDayEndTime , date + " " + startTime ) : 9999 ;
int currentDayDiffMinutes = DateUtil . getBetWeenMinutes ( realEndDate + " " + endTime , currentDayStartTime ) ;
belongDate = currentDayDiffMinutes < beforeDayDiffMinutes ? date : DateUtil . beforeDay ( date , 1 ) ;
//20240924需求变更, 判断加班区间是否与班次的休息或就餐班段有交集
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , date + " " + startTime , realEndDate + " " + endTime ,
DateUtil . beforeDay ( date , 1 ) , date , null , false ) ;
} else if ( currentToNextDay ) {
int nextDayDiffMinutes = ! "" . equals ( nextDayStartTime ) ? DateUtil . getBetWeenMinutes ( realEndDate + " " + endTime , nextDayStartTime ) : 9999 ;
int currentDayDiffMinutes = DateUtil . getBetWeenMinutes ( currentDayEndTime , date + " " + startTime ) ;
belongDate = currentDayDiffMinutes < = nextDayDiffMinutes ? date : DateUtil . AfterDay ( date , 1 ) ;
//20240924需求变更, 判断加班区间是否与班次的休息或就餐班段有交集
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , date + " " + startTime , realEndDate + " " + endTime ,
date , DateUtil . AfterDay ( date , 1 ) , null , false ) ;
} else if ( beforeToNextDay ) {
int beforeDayDiffMinutes = ! "" . equals ( beforeDayEndTime ) ? DateUtil . getBetWeenMinutes ( beforeDayEndTime , date + " " + startTime ) : 9999 ;
int nextDayDiffMinutes = ! "" . equals ( nextDayStartTime ) ? DateUtil . getBetWeenMinutes ( realEndDate + " " + endTime , nextDayStartTime ) : 9999 ;
@ -162,58 +187,73 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
} else {
belongDate = beforeDayDiffMinutes < = nextDayDiffMinutes ? DateUtil . beforeDay ( date , 1 ) : DateUtil . AfterDay ( date , 1 ) ;
}
//20240924需求变更, 判断加班区间是否与班次的休息或就餐班段有交集
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , date + " " + startTime , realEndDate + " " + endTime ,
DateUtil . beforeDay ( date , 1 ) , DateUtil . AfterDay ( date , 1 ) , null , false ) ;
} else {
//20240812需求变更, 休息班次, 允许加班计划区间和班次班段区间有重叠
currentDayOverLap = ! "" . equals ( currentDayStartToEnd ) & & DateUtil . isOverlapping ( date + " " + startTime , realEndDate + " " + endTime , currentDayStartTime , currentDayEndTime ) ;
beforeDayOverLap = ! "" . equals ( beforeDayStartToEnd ) & & DateUtil . isOverlapping ( date + " " + startTime , realEndDate + " " + endTime , beforeDayStartTime , beforeDayEndTime ) ;
nextDayOverLap = ! "" . equals ( nextDayStartToEnd ) & & DateUtil . isOverlapping ( date + " " + startTime , realEndDate + " " + endTime , nextDayStartTime , nextDayEndTime ) ;
//20240814需求变更。非休息班次, 出现重叠时间, 自动调整加班开始或结束时间, 并返回提示
adjustInfo . put ( "startWithAdjust" , date + " " + startTime ) ;
adjustInfo . put ( "endWithAdjust" , realEndDate + " " + endTime ) ;
adjustInfo . put ( "startDate" , date ) ;
adjustInfo . put ( "startTime" , startTime ) ;
adjustInfo . put ( "endDate" , realEndDate ) ;
adjustInfo . put ( "endTime" , endTime ) ;
if ( ( ! currentDayRestBc & & currentDayOverLap ) | | ( ! beforeDayRestBc & & beforeDayOverLap ) | | ( ! nextDayRestBc & & nextDayOverLap ) ) {
//处理前一天
if ( ! beforeDayRestBc & & beforeDayOverLap ) {
belongDate = DateUtil . beforeDay ( date , 1 ) ;
if ( overtimeOnlyInRestRange ( beforeDayBcId , date + " " + startTime , realEndDate + " " + endTime , DateUtil . beforeDay ( date , 1 ) ) ) {
onlyInRestPeriod = true ;
} else {
//20240924需求变更, 区分“休息”、“就餐”、“休息和就餐”三类时段的时长和要求, 并且对加班区间的首尾如果有不许累计时长的以上三类区间, 要灵活修改加班区间的首尾时间点
//处理前一天
if ( beforeDayOverLap ) {
belongDate = DateUtil . beforeDay ( date , 1 ) ;
if ( ! beforeDayRestBc ) {
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , date + " " + startTime , realEndDate + " " + endTime ,
null , null , belongDate , false ) ;
onlyInRestPeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInRestPeriod" ) ;
onlyInDinePeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInDinePeriod" ) ;
onlyInRestAndDinePeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInRestAndDinePeriod" ) ;
if ( ! onlyInRestPeriod & & ! onlyInDinePeriod & & ! onlyInRestAndDinePeriod ) {
adjustInfo = doAdjust ( adjustInfo , beforeDayStartTime , beforeDayEndTime ) ;
}
} else {
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , date + " " + startTime , realEndDate + " " + endTime ,
null , null , belongDate , true ) ;
}
//处理当天
if ( ! currentDayRestBc & & currentDayOverLap ) {
belongDate = "" . equals ( belongDate ) ? date : belongDate ;
if ( overtimeOnlyInRestRange ( currentDayBcId , date + " " + startTime , realEndDate + " " + endTime , date ) ) {
onlyInRestPeriod = true ;
} else {
}
//处理当天
if ( currentDayOverLap ) {
belongDate = "" . equals ( belongDate ) ? date : belongDate ;
if ( ! currentDayRestBc ) {
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , date + " " + startTime , realEndDate + " " + endTime ,
null , null , belongDate , false ) ;
onlyInRestPeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInRestPeriod" ) ;
onlyInDinePeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInDinePeriod" ) ;
onlyInRestAndDinePeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInRestAndDinePeriod" ) ;
if ( ! onlyInRestPeriod & & ! onlyInDinePeriod & & ! onlyInRestAndDinePeriod ) {
adjustInfo = doAdjust ( adjustInfo , currentDayStartTime , currentDayEndTime ) ;
}
} else {
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , date + " " + startTime , realEndDate + " " + endTime ,
null , null , belongDate , true ) ;
}
//处理次日
if ( ! nextDayRestBc & & nextDayOverLap ) {
belongDate = "" . equals ( belongDate ) ? DateUtil . AfterDay ( date , 1 ) : belongDate ;
if ( overtimeOnlyInRestRange ( nextDayBcId , date + " " + startTime , realEndDate + " " + endTime , DateUtil . AfterDay ( date , 1 ) ) ) {
onlyInRestPeriod = true ;
} else {
}
//处理次日
if ( nextDayOverLap ) {
belongDate = "" . equals ( belongDate ) ? DateUtil . AfterDay ( date , 1 ) : belongDate ;
if ( ! nextDayRestBc ) {
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , date + " " + startTime , realEndDate + " " + endTime ,
null , null , belongDate , false ) ;
onlyInRestPeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInRestPeriod" ) ;
onlyInDinePeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInDinePeriod" ) ;
onlyInRestAndDinePeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInRestAndDinePeriod" ) ;
if ( ! onlyInRestPeriod & & ! onlyInDinePeriod & & ! onlyInRestAndDinePeriod ) {
adjustInfo = doAdjust ( adjustInfo , nextDayStartTime , nextDayEndTime ) ;
}
} else {
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , date + " " + startTime , realEndDate + " " + endTime ,
null , null , belongDate , true ) ;
}
//重置加班开始和结束时间、加班时长
detailItem . put ( "ksrq" , adjustInfo . get ( "startDate" ) ) ;
detailItem . put ( "kssj" , adjustInfo . get ( "startTime" ) ) ;
detailItem . put ( "jssj" , adjustInfo . get ( "endTime" ) ) ;
detailItem . put ( "jsrq" , adjustInfo . get ( "endDate" ) ) ;
overtimeMinutes = DateUtil . getBetWeenMinutes ( adjustInfo . get ( "startWithAdjust" ) , adjustInfo . get ( "endWithAdjust" ) ) ;
//4-非休息班次,出现重叠时间,属于不合理加班安排,返回提示”已自动调整开始和结束时间点“
if ( ! onlyInRestPeriod ) {
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班计划区间和非休息班次班段出现时间重叠,已自动调整开始和结束时间点!" ) ;
}
}
//以上三天处理过后,还要考虑调整过加班起始时间后的区间,处于两天之间的情况,此处仅考虑非休息班次自动调整过加班开始、结束时间后处于两班次之间的情况
if ( ( beforeDayOverLap & & ! beforeDayRestBc ) | | ( currentDayOverLap & & ! currentDayRestBc ) | | ( nextDayOverLap & & ! nextDayRestBc ) ) {
overtimeBorderCheck ( overtimeBorderInfo , bcDetailListToDateMap , adjustInfo . get ( "startDate" ) + " " + adjustInfo . get ( "startTime" ) ,
adjustInfo . get ( "endDate" ) + " " + adjustInfo . get ( "endTime" ) ,
belongDate , DateUtil . AfterDay ( belongDate , 1 ) , null , false ) ;
}
overtimeMinutes = DateUtil . getBetWeenMinutes ( adjustInfo . get ( "startWithAdjust" ) , adjustInfo . get ( "endWithAdjust" ) ) ;
//5-加班区间和休息班次出现重叠,首次重叠的日期,即为归属日期;如果已有归属日,则比较当前日期和归属日谁更早
if ( beforeDayRestBc & & beforeDayOverLap ) {
belongDate = DateUtil . beforeDay ( date , 1 ) ;
@ -235,13 +275,19 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
List < Map < String , Object > > attendanceItemSetList = CommonUtil . getAttendanceItemsByEmpIdDate ( empId , belongDate ) ;
List < String > kqxmSetIds = attendanceItemSetList . stream ( ) . map ( f - > f . get ( "keyid" ) . toString ( ) ) . collect ( Collectors . toList ( ) ) ;
// log.info(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的可用考勤项目:" + kqxmSetIds);
onlyInRestPeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInRestPeriod" ) ;
onlyInDinePeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInDinePeriod" ) ;
onlyInRestAndDinePeriod = ( boolean ) overtimeBorderInfo . get ( "onlyInRestAndDinePeriod" ) ;
Map < String , Object > matchItemInfo = new HashMap < > ( ) ;
for ( Map < String , Object > attendanceItemInfo : jblxAttendanceList ) {
//判断该加班类型考勤项目是否被该人员使用,且考勤项目的绑定的日期类型是否包含归属日期类型
if ( kqxmSetIds . contains ( Util . null2String ( attendanceItemInfo . get ( "id" ) ) )
& & Util . null2String ( attendanceItemInfo . get ( "bddrqlx" ) ) . contains ( belongDateType ) ) {
//非休息班次,加班区间完全处于休息班段内时,在匹配加班类型时避开勾选了“是否扣除时间区间内的就餐时长”的加班类型
if ( onlyInRestPeriod & & "1" . equals ( Util . null2String ( attendanceItemInfo . get ( "zdkcjcxxsc" ) ) ) ) {
//非休息班次,加班区间完全处于“就餐”或“休息和就餐”班段内时,在匹配加班类型时避开勾选了“是否扣除时间区间内的就餐时长”的加班类型
if ( ( onlyInDinePeriod | | onlyInRestAndDinePeriod ) & & "1" . equals ( Util . null2String ( attendanceItemInfo . get ( "zdkcjcxxsc" ) ) ) ) {
continue ;
//非休息班次,加班区间完全处于“休息”或“休息和就餐”班段内时,在匹配加班类型时避开勾选了“是否扣除时间区间内的休息时长”的加班类型
} else if ( ( onlyInRestPeriod | | onlyInRestAndDinePeriod ) & & "1" . equals ( Util . null2String ( attendanceItemInfo . get ( "sfkcxxdsc" ) ) ) ) {
continue ;
}
detailItem . put ( "jblx" , Util . null2String ( attendanceItemInfo . get ( "id" ) ) ) ;
@ -255,92 +301,107 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
log . info ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班计划未匹配到合适的加班类型!" ) ;
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班计划未匹配到合适的加班类型!" ) ;
continue ;
} else {
log . info ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班计划匹配到:" + Util . null2String ( matchItemInfo . get ( "mc" ) ) ) ;
//20240816需求变更, 根据zdkcjcxxsc字段设置, 即“是否扣除时间区间内的就餐时长”需要去除重叠的休息班次中的休息时段时长
String removeRestSc = Util . null2String ( matchItemInfo . get ( "zdkcjcxxsc" ) ) ;
int restOverLapMinutes = 0 ;
if ( beforeDayRestBc & & beforeDayOverLap & & "1" . equals ( removeRestSc ) ) {
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes ( beforeDayBcId , adjustInfo . get ( "startWithAdjust" ) , adjustInfo . get ( "endWithAdjust" ) , DateUtil . beforeDay ( date , 1 ) ) ;
} else if ( currentDayRestBc & & currentDayOverLap & & "1" . equals ( removeRestSc ) ) {
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes ( currentDayBcId , adjustInfo . get ( "startWithAdjust" ) , adjustInfo . get ( "endWithAdjust" ) , date ) ;
} else if ( nextDayRestBc & & nextDayOverLap & & "1" . equals ( removeRestSc ) ) {
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes ( nextDayBcId , adjustInfo . get ( "startWithAdjust" ) , adjustInfo . get ( "endWithAdjust" ) , DateUtil . AfterDay ( date , 1 ) ) ;
}
overtimeMinutes = overtimeMinutes - restOverLapMinutes ;
detailItem . put ( "jbsc" , String . format ( "%.2f" , overtimeMinutes / 60.0 ) ) ;
//单条明细的最小加班分钟数校验
String minMinutes = Util . null2String ( matchItemInfo . get ( "jbqsfzs" ) ) ;
if ( ! "" . equals ( minMinutes ) & & Integer . parseInt ( minMinutes ) > overtimeMinutes ) {
//最小加班分钟数大于单条明细的加班时长分钟数
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班分钟数小于加班类型-"
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的最小加班分钟数!" ) ;
continue ;
}
log . info ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班计划匹配到:" + Util . null2String ( matchItemInfo . get ( "mc" ) ) ) ;
//20240924需求变更, 区分“休息”、“就餐”、“休息和就餐”三类时段的时长和要求, 并且对加班区间的首尾如果有不许累计时长的以上三类区间, 要灵活修改加班区间的首尾时间点
//根据sfkcxxdsc字段设置, 即“是否扣除时间区间内的休息时长”需要去除重叠的休息班次中的休息时段时长
String removeRestSc = Util . null2String ( matchItemInfo . get ( "sfkcxxdsc" ) ) ;
//20240816需求变更, 根据zdkcjcxxsc字段设置, 即“是否扣除时间区间内的就餐时长”需要去除重叠的休息班次中的就餐时段时长
String removeDineSc = Util . null2String ( matchItemInfo . get ( "zdkcjcxxsc" ) ) ;
//根据匹配的加班类型中的sfkcxxdsc字段和zdkcjcxxsc字段设置再次处理加班时长和加班区间
List < Map < String , Object > > borderOverlapBcDetails = ( List < Map < String , Object > > ) overtimeBorderInfo . get ( "borderOverlapBcDetails" ) ;
int restOverLapMinutes = 0 ;
if ( borderOverlapBcDetails ! = null & & borderOverlapBcDetails . size ( ) > 0 ) {
restOverLapMinutes = countDineOrRestOverLapMinutes ( borderOverlapBcDetails , adjustInfo , removeRestSc , removeDineSc ) ;
}
overtimeMinutes = overtimeMinutes - restOverLapMinutes ;
detailItem . put ( "jbsc" , String . format ( "%.2f" , overtimeMinutes / 60.0 ) ) ;
//重置加班开始和结束时间、加班时长
detailItem . put ( "ksrq" , adjustInfo . get ( "startDate" ) ) ;
detailItem . put ( "kssj" , adjustInfo . get ( "startTime" ) ) ;
detailItem . put ( "jssj" , adjustInfo . get ( "endTime" ) ) ;
detailItem . put ( "jsrq" , adjustInfo . get ( "endDate" ) ) ;
//对于不允许加班的情况,此处指非休息班次中,和非休息、就餐班段有重叠时
allowOvertimeSign = ( boolean ) overtimeBorderInfo . get ( "allowOvertimeSign" ) ;
if ( ! allowOvertimeSign ) {
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班区间和工作班次的非休息/就餐班段有重叠!" ) ;
continue ;
}
//单条明细的最小加班分钟数校验
String minMinutes = Util . null2String ( matchItemInfo . get ( "jbqsfzs" ) ) ;
if ( ! "" . equals ( minMinutes ) & & Integer . parseInt ( minMinutes ) > overtimeMinutes ) {
//最小加班分钟数大于单条明细的加班时长分钟数
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班分钟数小于加班类型-"
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的最小加班分钟数!" ) ;
continue ;
}
String limitTotalOvertimeSc = Util . null2String ( matchItemInfo . get ( "xzzjbsc" ) ) ;
if ( "1" . equals ( limitTotalOvertimeSc ) ) {
String limitWorkDayHours = Util . null2String ( matchItemInfo . get ( "rzdjbxss" ) ) ;
String limitWeekHours = Util . null2String ( matchItemInfo . get ( "zzdjbxss" ) ) ;
String limitMonthHours = Util . null2String ( matchItemInfo . get ( "yzdjbxss" ) ) ;
String limitDealType = Util . null2String ( matchItemInfo . get ( "ccclfs" ) ) ;
boolean doLimitWorkDayHours = false ;
boolean doLimitWeekHours = false ;
boolean doLimitMonthHours = false ;
//判断是否满足工作日加班最大小时数
boolean needCheckWorkDayHours = ! "" . equals ( limitWorkDayHours ) & & ( belongDateType . equals ( DateTypeEnum . WORK_DAY . getKey ( ) ) | | belongDateType . equals ( DateTypeEnum . CHANGECLASS . getKey ( ) ) ) ;
if ( needCheckWorkDayHours & & Double . compare ( Double . parseDouble ( limitWorkDayHours ) , overtimeMinutes / 60.0 ) < 0 ) {
doLimitWorkDayHours = true ;
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的工作日加班最大小时数!" ) ;
}
String limitTotalOvertimeSc = Util . null2String ( matchItemInfo . get ( "xzzjbsc" ) ) ;
if ( "1" . equals ( limitTotalOvertimeSc ) ) {
String limitWorkDayHours = Util . null2String ( matchItemInfo . get ( "rzdjbxss" ) ) ;
String limitWeekHours = Util . null2String ( matchItemInfo . get ( "zzdjbxss" ) ) ;
String limitMonthHours = Util . null2String ( matchItemInfo . get ( "yzdjbxss" ) ) ;
String limitDealType = Util . null2String ( matchItemInfo . get ( "ccclfs" ) ) ;
boolean doLimitWorkDayHours = false ;
boolean doLimitWeekHours = false ;
boolean doLimitMonthHours = false ;
//判断是否满足工作日加班最大小时数
boolean needCheckWorkDayHours = ! "" . equals ( limitWorkDayHours ) & & ( belongDateType . equals ( DateTypeEnum . WORK_DAY . getKey ( ) ) | | belongDateType . equals ( DateTypeEnum . CHANGECLASS . getKey ( ) ) ) ;
if ( needCheckWorkDayHours & & Double . compare ( Double . parseDouble ( limitWorkDayHours ) , overtimeMinutes / 60.0 ) < 0 ) {
doLimitWorkDayHours = true ;
//判断是否满足周加班最大小时数
if ( ! "" . equals ( limitWeekHours ) ) {
int weekRank = DateUtil . weekRank ( belongDate ) ;
double maxWeekMinutes = Double . parseDouble ( limitWeekHours ) * 60 ;
double weekOvertimeMinutes ;
if ( weekOvertimeInfo . get ( belongDate . split ( "-" ) [ 0 ] + "" + weekRank ) = = null ) {
String countStartDate = DateUtil . beforeDay ( belongDate . split ( "-" ) [ 0 ] + "-" + belongDate . split ( "-" ) [ 1 ] + "-01" , 6 ) ;
String countEndDate = DateUtil . AfterDay ( belongDate . split ( "-" ) [ 0 ] + "-" + belongDate . split ( "-" ) [ 1 ] + "-28" , 9 ) ;
weekOvertimeMinutes = getWeekTimeMinutes ( getWorkOverTimeResults ( countStartDate , countEndDate , empId ) , belongDate ) ;
} else {
weekOvertimeMinutes = weekOvertimeInfo . get ( belongDate . split ( "-" ) [ 0 ] + "" + weekRank ) ;
}
weekOvertimeInfo . put ( belongDate . split ( "-" ) [ 0 ] + "" + weekRank , weekOvertimeMinutes + overtimeMinutes ) ;
if ( maxWeekMinutes - weekOvertimeMinutes - overtimeMinutes < 0 ) {
//达到周加班最大小时数
doLimitWeekHours = true ;
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的工作日加班最大小时数!" ) ;
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的 周 加班最大小时数!") ;
}
//判断是否满足周加班最大小时数
if ( ! "" . equals ( limitWeekHours ) ) {
int weekRank = DateUtil . weekRank ( belongDate ) ;
double maxWeekMinutes = Double . parseDouble ( limitWeekHours ) * 60 ;
double weekOvertimeMinutes ;
if ( weekOvertimeInfo . get ( belongDate . split ( "-" ) [ 0 ] + "" + weekRank ) = = null ) {
String countStartDate = DateUtil . beforeDay ( belongDate . split ( "-" ) [ 0 ] + "-" + belongDate . split ( "-" ) [ 1 ] + "-01" , 6 ) ;
String countEndDate = DateUtil . AfterDay ( belongDate . split ( "-" ) [ 0 ] + "-" + belongDate . split ( "-" ) [ 1 ] + "-28" , 9 ) ;
weekOvertimeMinutes = getWeekTimeMinutes ( getWorkOverTimeResults ( countStartDate , countEndDate , empId ) , belongDate ) ;
} else {
weekOvertimeMinutes = weekOvertimeInfo . get ( belongDate . split ( "-" ) [ 0 ] + "" + weekRank ) ;
}
weekOvertimeInfo . put ( belongDate . split ( "-" ) [ 0 ] + "" + weekRank , weekOvertimeMinutes + overtimeMinutes ) ;
if ( maxWeekMinutes - weekOvertimeMinutes - overtimeMinutes < 0 ) {
//达到周加班最大小时数
doLimitWeekHours = true ;
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的周加班最大小时数!" ) ;
}
}
//判断是否满足月加班最大小时数
if ( ! "" . equals ( limitMonthHours ) ) {
String yearMonth = belongDate . substring ( 0 , 7 ) ;
double maxMonthMinutes = Double . parseDouble ( limitMonthHours ) * 60 ;
double monthOvertimeMinutes ;
if ( monthOvertimeInfo . get ( yearMonth ) = = null ) {
String countStartDate = belongDate . split ( "-" ) [ 0 ] + "-" + belongDate . split ( "-" ) [ 1 ] + "-01" ;
String countEndDate = belongDate . split ( "-" ) [ 0 ] + "-" + belongDate . split ( "-" ) [ 1 ] + "-31" ;
monthOvertimeMinutes = getMonthTimeMinutes ( getWorkOverTimeResults ( countStartDate , countEndDate , empId ) , belongDate ) ;
} else {
monthOvertimeMinutes = monthOvertimeInfo . get ( yearMonth ) ;
}
//判断是否满足月加班最大小时数
if ( ! "" . equals ( limitMonthHours ) ) {
String yearMonth = belongDate . substring ( 0 , 7 ) ;
double maxMonthMinutes = Double . parseDouble ( limitMonthHours ) * 60 ;
double monthOvertimeMinutes ;
if ( monthOvertimeInfo . get ( yearMonth ) = = null ) {
String countStartDate = belongDate . split ( "-" ) [ 0 ] + "-" + belongDate . split ( "-" ) [ 1 ] + "-01" ;
String countEndDate = belongDate . split ( "-" ) [ 0 ] + "-" + belongDate . split ( "-" ) [ 1 ] + "-31" ;
monthOvertimeMinutes = getMonthTimeMinutes ( getWorkOverTimeResults ( countStartDate , countEndDate , empId ) , belongDate ) ;
} else {
monthOvertimeMinutes = monthOvertimeInfo . get ( yearMonth ) ;
}
monthOvertimeInfo . put ( yearMonth , monthOvertimeMinutes + overtimeMinutes ) ;
if ( maxMonthMinutes - monthOvertimeMinutes - overtimeMinutes < 0 ) {
//达到月加班最大小时数
doLimitMonthHours = true ;
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的月加班最大小时数!" ) ;
}
monthOvertimeInfo . put ( yearMonth , monthOvertimeMinutes + overtimeMinutes ) ;
if ( maxMonthMinutes - monthOvertimeMinutes - overtimeMinutes < 0 ) {
//达到月加班最大小时数
doLimitMonthHours = true ;
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的月加班最大小时数!" ) ;
}
}
// //判断是否超出工作日、周、月最大小时数要求
// if ("1".equals(limitDealType) && (doLimitWorkDayHours || doLimitWeekHours || doLimitMonthHours)) {
// continue;
// }
}
}
//如果实际加班时长为0, 加班开始时间和结束时间置为初始值
if ( overtimeMinutes = = 0 ) {
detailItem . put ( "ksrq" , date ) ;
detailItem . put ( "kssj" , startTime ) ;
detailItem . put ( "jssj" , endTime ) ;
detailItem . put ( "jsrq" , realEndDate ) ;
}
overtimePlanDetailList . add ( detailItem ) ;
}
@ -377,6 +438,90 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
return Utils . removeTime ( startTime , endTime , bcDetailData , date ) ;
}
/ * *
* 目 标 区 间 和 日 期 所 在 班 次 中 需 要 扣 除 的 “ 就 餐 ” 、 “ 休 息 ” 、 “ 就 餐 和 休 息 ” 时 段 重 叠 的 分 钟 数
* @param borderOverlapBcDetails
* @param adjustInfo
* @param removeRestSc
* @param removeDineSc
* /
private int countDineOrRestOverLapMinutes ( List < Map < String , Object > > borderOverlapBcDetails , Map < String , String > adjustInfo , String removeRestSc , String removeDineSc ) {
List < String > countBdlxList = new ArrayList < > ( ) ;
if ( "1" . equals ( removeRestSc ) & & "1" . equals ( removeDineSc ) ) {
countBdlxList . add ( ClassSegmentTypeEnum . REST_AND_DINE . getKey ( ) ) ;
countBdlxList . add ( ClassSegmentTypeEnum . REST_PERIOD . getKey ( ) ) ;
countBdlxList . add ( ClassSegmentTypeEnum . DINING_PERIOD . getKey ( ) ) ;
} else if ( "1" . equals ( removeRestSc ) ) {
countBdlxList . add ( ClassSegmentTypeEnum . REST_PERIOD . getKey ( ) ) ;
} else if ( "1" . equals ( removeDineSc ) ) {
countBdlxList . add ( ClassSegmentTypeEnum . DINING_PERIOD . getKey ( ) ) ;
} else {
return 0 ;
}
for ( Map < String , Object > bcDetailItem : borderOverlapBcDetails ) {
if ( ! countBdlxList . contains ( bcDetailItem . get ( "bdlx" ) . toString ( ) ) ) {
continue ;
}
String dtkssj = Utils . getkssjTime ( bcDetailItem , ( String ) bcDetailItem . get ( "bcBelongDate" ) ) ;
String dtjssj = Utils . getjssjTime ( bcDetailItem , ( String ) bcDetailItem . get ( "bcBelongDate" ) ) ;
bcDetailItem . put ( "bdStartTime" , dtkssj ) ;
bcDetailItem . put ( "bdEndTime" , dtjssj ) ;
}
//筛选出处理过的班次明细数据,并根据开始时间排序
List < Map < String , Object > > countBcDetails = borderOverlapBcDetails . stream ( ) . filter ( f - > f . get ( "bdStartTime" ) ! = null ) . collect ( Collectors . toList ( ) ) ;
if ( countBcDetails . size ( ) = = 0 ) {
return 0 ;
}
countBcDetails = countBcDetails . stream ( ) . sorted ( Comparator . comparing ( e - > DateUtil . getTime ( e . get ( "bdStartTime" ) . toString ( ) ) . toInstant ( ZoneOffset . of ( "+8" ) ) . toEpochMilli ( ) ) ) . collect ( Collectors . toList ( ) ) ;
//合并相邻休息、就餐时段
List < Map < String , Object > > finalCountBcDetails = new ArrayList < > ( ) ;
for ( Map < String , Object > bcDetailItem : countBcDetails ) {
if ( finalCountBcDetails . size ( ) = = 0 ) {
finalCountBcDetails . add ( bcDetailItem ) ;
continue ;
}
Map < String , Object > finalCountItem = finalCountBcDetails . get ( finalCountBcDetails . size ( ) - 1 ) ;
if ( finalCountItem . get ( "bdEndTime" ) . toString ( ) . equals ( bcDetailItem . get ( "bdStartTime" ) . toString ( ) ) ) {
finalCountItem . put ( "bdEndTime" , bcDetailItem . get ( "bdEndTime" ) ) ;
} else {
finalCountBcDetails . add ( bcDetailItem ) ;
}
}
//累计时间,并且调整加班区间
int countMinutes = 0 ;
String overtimeStartTime = adjustInfo . get ( "startWithAdjust" ) ;
String overtimeEndTime = adjustInfo . get ( "endWithAdjust" ) ;
String bdStartTime = "" ;
String bdEndTime = "" ;
for ( Map < String , Object > bcDetailItem : finalCountBcDetails ) {
if ( overtimeStartTime . compareTo ( overtimeEndTime ) = = 0 ) {
break ;
}
bdStartTime = ( String ) bcDetailItem . get ( "bdStartTime" ) ;
bdEndTime = ( String ) bcDetailItem . get ( "bdEndTime" ) ;
countMinutes = countMinutes + DateUtil . getOverlappedMinutes ( overtimeStartTime , overtimeEndTime , bdStartTime , bdEndTime ) ;
//调整加班开始和结束时间
if ( overtimeStartTime . compareTo ( bdStartTime ) > = 0 & & overtimeStartTime . compareTo ( bdEndTime ) < 0 ) {
overtimeStartTime = bdEndTime ;
}
if ( overtimeEndTime . compareTo ( bdStartTime ) > 0 & & overtimeEndTime . compareTo ( bdEndTime ) < = 0 ) {
overtimeEndTime = bdStartTime ;
}
if ( overtimeStartTime . compareTo ( overtimeEndTime ) > 0 ) {
overtimeEndTime = overtimeStartTime ;
}
}
adjustInfo . put ( "startWithAdjust" , overtimeStartTime ) ;
adjustInfo . put ( "endWithAdjust" , overtimeEndTime ) ;
adjustInfo . put ( "startDate" , overtimeStartTime . split ( " " ) [ 0 ] ) ;
adjustInfo . put ( "startTime" , overtimeStartTime . split ( " " ) [ 1 ] ) ;
adjustInfo . put ( "endDate" , overtimeEndTime . split ( " " ) [ 0 ] ) ;
adjustInfo . put ( "endTime" , overtimeEndTime . split ( " " ) [ 1 ] ) ;
return countMinutes ;
}
/ * *
* 加 班 区 间 和 非 休 息 班 次 出 现 重 叠 时 , 自 动 调 整 加 班 区 间 的 开 始 / 结 束 时 间
* /
@ -406,7 +551,92 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
}
/ * *
* 判 断 请 假 区 间 是 否 完 全 处 于 班 次 中 的 休 息 时 段 内
* 判 断 加 班 区 间 与 班 次 中 非 工 作 时 段 的 关 系
* /
private void overtimeBorderCheck ( Map < String , Object > overtimeBorderInfo , Map < String , List < Map < String , Object > > > bcDetailListToDateMap ,
String startTime , String endTime , String beforeDate , String afterDate , String overlapDate , boolean overlapRestBc ) {
List < String > countBdlxList = new ArrayList < > ( ) ;
countBdlxList . add ( ClassSegmentTypeEnum . REST_AND_DINE . getKey ( ) ) ;
countBdlxList . add ( ClassSegmentTypeEnum . REST_PERIOD . getKey ( ) ) ;
countBdlxList . add ( ClassSegmentTypeEnum . DINING_PERIOD . getKey ( ) ) ;
List < Map < String , Object > > overlapBcDetailList = new ArrayList < > ( ) ;
if ( overlapDate = = null ) {
//如果重叠日期为null, 只需判断加班区间的首尾是否和班次的非工作时段有重叠
//处理加班区间首部的附近的班次数据
List < Map < String , Object > > beforeOvertimeBcDetailList = bcDetailListToDateMap . get ( beforeDate ) ;
if ( beforeOvertimeBcDetailList ! = null & & beforeOvertimeBcDetailList . size ( ) > 0 ) {
beforeOvertimeBcDetailList = beforeOvertimeBcDetailList . stream ( ) . filter ( e - > countBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
for ( Map < String , Object > bcDetailItem : beforeOvertimeBcDetailList ) {
int overlapMinutes = Utils . removeTime ( startTime , endTime , Collections . singletonList ( bcDetailItem ) , beforeDate ) ;
if ( overlapMinutes > 0 ) {
bcDetailItem . put ( "bcBelongDate" , beforeDate ) ;
overlapBcDetailList . add ( bcDetailItem ) ;
}
}
}
//处理加班区间尾部的附近的班次数据
List < Map < String , Object > > afterOvertimeBcDetailList = bcDetailListToDateMap . get ( afterDate ) ;
if ( afterOvertimeBcDetailList ! = null & & afterOvertimeBcDetailList . size ( ) > 0 ) {
afterOvertimeBcDetailList = afterOvertimeBcDetailList . stream ( ) . filter ( e - > countBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
for ( Map < String , Object > bcDetailItem : afterOvertimeBcDetailList ) {
int overlapMinutes = Utils . removeTime ( startTime , endTime , Collections . singletonList ( bcDetailItem ) , afterDate ) ;
if ( overlapMinutes > 0 ) {
bcDetailItem . put ( "bcBelongDate" , afterDate ) ;
overlapBcDetailList . add ( bcDetailItem ) ;
}
}
}
//处理重叠班段数据
if ( overlapBcDetailList . size ( ) > 0 ) {
overtimeBorderInfo . put ( "borderHaveRest" , true ) ;
overtimeBorderInfo . put ( "borderOverlapBcDetails" , overlapBcDetailList ) ;
}
} else {
//如果重叠日期不为null, 还需要区分重叠的班次是否为休息班次
List < Map < String , Object > > overlapOvertimeBcDetailList = bcDetailListToDateMap . get ( overlapDate ) ;
if ( overlapOvertimeBcDetailList = = null | | overlapOvertimeBcDetailList . size ( ) = = 0 ) {
return ;
}
overlapOvertimeBcDetailList = overlapOvertimeBcDetailList . stream ( ) . filter ( e - > countBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
//处理加班区间重叠的班次数据
for ( Map < String , Object > bcDetailItem : overlapOvertimeBcDetailList ) {
int overlapMinutes = Utils . removeTime ( startTime , endTime , Collections . singletonList ( bcDetailItem ) , overlapDate ) ;
if ( overlapMinutes > 0 ) {
bcDetailItem . put ( "bcBelongDate" , overlapDate ) ;
overlapBcDetailList . add ( bcDetailItem ) ;
}
}
if ( overlapBcDetailList . size ( ) = = 0 ) {
return ;
}
List < Map < String , Object > > existOverlapBcDetailList = ( List < Map < String , Object > > ) overtimeBorderInfo . getOrDefault ( "borderOverlapBcDetails" , new ArrayList < > ( ) ) ;
existOverlapBcDetailList . addAll ( overlapBcDetailList ) ;
if ( overlapRestBc ) {
//休息班次时,需要判断开始或者结束是否处于班次的非工作时段
overtimeBorderInfo . put ( "overlapRestBcRest" , true ) ;
overtimeBorderInfo . put ( "borderOverlapBcDetails" , existOverlapBcDetailList ) ;
} else {
//非休息班次时,只需判断是不是只在就餐/休息班段内加班
int overRangeMinutes = DateUtil . getBetWeenMinutes ( startTime , endTime ) ;
if ( overRangeMinutes ! = Utils . removeTime ( startTime , endTime , overlapBcDetailList , overlapDate ) ) {
overtimeBorderInfo . put ( "allowOvertimeSign" , false ) ;
return ;
}
List < String > bdlxList = overlapBcDetailList . stream ( ) . map ( e - > e . get ( "bdlx" ) . toString ( ) ) . collect ( Collectors . toList ( ) ) ;
if ( ( bdlxList . contains ( ClassSegmentTypeEnum . REST_PERIOD . getKey ( ) ) & & bdlxList . contains ( ClassSegmentTypeEnum . DINING_PERIOD . getKey ( ) ) )
| | bdlxList . contains ( ClassSegmentTypeEnum . REST_AND_DINE . getKey ( ) ) ) {
overtimeBorderInfo . put ( "onlyInRestAndDinePeriod" , true ) ;
} else if ( bdlxList . contains ( ClassSegmentTypeEnum . REST_PERIOD . getKey ( ) ) ) {
overtimeBorderInfo . put ( "onlyInRestPeriod" , true ) ;
} else if ( bdlxList . contains ( ClassSegmentTypeEnum . DINING_PERIOD . getKey ( ) ) ) {
overtimeBorderInfo . put ( "onlyInDinePeriod" , true ) ;
}
}
}
}
/ * *
* 判 断 加 班 区 间 是 否 完 全 处 于 班 次 中 的 休 息 时 段 内
* /
private boolean overtimeOnlyInRestRange ( String bcId , String startTime , String endTime , String date ) {
int overRangeMinutes = DateUtil . getBetWeenMinutes ( startTime , endTime ) ;
@ -468,22 +698,23 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
return result ;
}
public String getBcStartAndEndTime ( String date , String currentDayBcId , List < String > workBdlxList ) {
public String getBcStartAndEndTime ( String date , String currentDayBcId , List < String > workBdlxList , Map < String , List < Map < String , Object > > > bcDetailListToDateMap ) {
String startToEnd = "" ;
if ( ! "" . equals ( currentDayBcId ) ) {
//查询当天班次明细
String sql = "select id, bdlx, gsrq, kssj , jssj from uf_jcl_kq_bcxx_dt1 where mainid = " + currentDayBcId + " order by gsrq desc, kssj desc";
String sql = "select id, bdlx, gsrq, kssj as dtkssj , jssj as dt jssj from uf_jcl_kq_bcxx_dt1 where mainid = " + currentDayBcId + " order by gsrq desc, dt kssj desc";
List < Map < String , Object > > bcDetailData = DbTools . getSqlToList ( sql ) ;
bcDetailListToDateMap . put ( date , new ArrayList < > ( bcDetailData ) ) ;
bcDetailData = bcDetailData . stream ( ) . filter ( e - > workBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
if ( bcDetailData . size ( ) > 0 ) {
String endGsrqValue = Util . null2String ( bcDetailData . get ( 0 ) . get ( "gsrq" ) ) ;
String lastJssj = Util . null2String ( bcDetailData . get ( 0 ) . get ( " jssj") ) ;
String lastKssj = Util . null2String ( bcDetailData . get ( 0 ) . get ( " kssj") ) ;
String lastJssj = Util . null2String ( bcDetailData . get ( 0 ) . get ( " dt jssj") ) ;
String lastKssj = Util . null2String ( bcDetailData . get ( 0 ) . get ( " dt kssj") ) ;
String bdEndDate = "2" . equals ( endGsrqValue ) ? DateUtil . AfterDay ( date , 1 ) : ( "0" . equals ( endGsrqValue ) ? DateUtil . beforeDay ( date , 1 ) : date ) ;
bdEndDate = lastKssj . compareTo ( lastJssj ) > = 0 ? DateUtil . AfterDay ( bdEndDate , 1 ) : bdEndDate ;
String startGsrqValue = Util . null2String ( bcDetailData . get ( bcDetailData . size ( ) - 1 ) . get ( "gsrq" ) ) ;
String firstKssj = Util . null2String ( bcDetailData . get ( bcDetailData . size ( ) - 1 ) . get ( " kssj") ) ;
String firstKssj = Util . null2String ( bcDetailData . get ( bcDetailData . size ( ) - 1 ) . get ( " dt kssj") ) ;
String bdStartDate = "2" . equals ( startGsrqValue ) ? DateUtil . AfterDay ( date , 1 ) : ( "0" . equals ( startGsrqValue ) ? DateUtil . beforeDay ( date , 1 ) : date ) ;
startToEnd = bdStartDate + " " + firstKssj + "," + bdEndDate + " " + lastJssj ;
@ -518,7 +749,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
double totalMinutes = 0 ;
for ( Map < String , Object > data : list ) {
String hsdw = data . get ( "hsdw" ) . toString ( ) ;
totalMinutes + = Utils . getItemduration ( 1, AccountingUnitEnum . MINUTES . getKey ( ) , Double . valueOf ( data . get ( "sjjbsc" ) . toString ( ) ) , AccountingUnitEnum . getEnum ( hsdw ) , 8 ) ;
totalMinutes + = Utils . getItemduration ( 0. 1, AccountingUnitEnum . MINUTES . getKey ( ) , Double . valueOf ( data . get ( "sjjbsc" ) . toString ( ) ) , AccountingUnitEnum . getEnum ( hsdw ) , 8 ) ;
}
return totalMinutes ;
}
@ -536,7 +767,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
double totalMinutes = 0 ;
for ( Map < String , Object > data : list ) {
String hsdw = data . get ( "hsdw" ) . toString ( ) ;
totalMinutes + = Utils . getItemduration ( 1, AccountingUnitEnum . MINUTES . getKey ( ) , Double . valueOf ( data . get ( "sjjbsc" ) . toString ( ) ) , AccountingUnitEnum . getEnum ( hsdw ) , 8 ) ;
totalMinutes + = Utils . getItemduration ( 0. 1, AccountingUnitEnum . MINUTES . getKey ( ) , Double . valueOf ( data . get ( "sjjbsc" ) . toString ( ) ) , AccountingUnitEnum . getEnum ( hsdw ) , 8 ) ;
}
return totalMinutes ;