@ -4,7 +4,10 @@ import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service ;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.UtilService ;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.impl.UtilServiceImpl ;
import com.engine.jucailinkq.attendance.enums.AttendanceItemTypeEnum ;
import com.engine.jucailinkq.attendance.enums.ClassSegmentTypeEnum ;
import com.engine.jucailinkq.attendance.enums.DateTypeEnum ;
import com.engine.jucailinkq.attendance.enums.WorkForTimeEnum ;
import com.engine.jucailinkq.attendance.workflow.service.OvertimePlanService ;
import com.engine.jucailinkq.common.util.CommonUtil ;
import com.engine.jucailinkq.common.util.DateUtil ;
@ -28,13 +31,13 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
@Override
public Map < String , Object > generateOvertimePlanDetails ( Map < String , Object > params ) {
Map < String , Object > resultMap = new HashMap < > ( ) ;
List < String > errorMessage = new ArrayList < > ( ) ;
try {
// 流程表单主表数据
Map < String , String > mainTableData = ( Map < String , String > ) params . get ( "mainTableData" ) ;
log . info ( "mainTableData : {}" , mainTableData ) ;
//加班人员、开始日期、结束日期、开始时间、结束时间
String jbry = Util . null2String ( mainTableData . get ( "jbry" ) ) ;
String jblx = Util . null2String ( mainTableData . get ( "jblx" ) ) ;
String startDate = Util . null2String ( mainTableData . get ( "ksrq" ) ) ;
String endDate = Util . null2String ( mainTableData . get ( "jsrq" ) ) ;
String startTime = Util . null2String ( mainTableData . get ( "kssj" ) ) ;
@ -44,32 +47,34 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//获取加班日期集合
List < String > dateList = DateUtil . getDatesBetween ( startDate , endDate ) ;
//获取人员列表在日期区间的班次数据
Map < String , List < Map < String , Object > > > scheduleInfoMap = utilService . getScheduleInfoWithEmpId ( empIdList , startDate, DateUtil . AfterDay ( endDate , 1 ) ) ;
Map < String , List < Map < String , Object > > > scheduleInfoMap = utilService . getScheduleInfoWithEmpId ( empIdList , DateUtil. beforeDay ( startDate, 1 ) , DateUtil . AfterDay ( endDate , 1 ) ) ;
List < Map < String , String > > overtimePlanDetailList = new ArrayList < > ( ) ;
List < String > workBdlxList = new ArrayList < > ( ) ;
workBdlxList . add ( ClassSegmentTypeEnum . WORK_TIME . getKey ( ) ) ; workBdlxList . add ( ClassSegmentTypeEnum . EXTENDED_OVERTIME . getKey ( ) ) ;
workBdlxList . add ( ClassSegmentTypeEnum . EARLY_OVERTIME . getKey ( ) ) ; workBdlxList . add ( ClassSegmentTypeEnum . OVERTIME_IN_CLASS . getKey ( ) ) ;
Map < String , String > detailItem ;
String sql = "" ;
//获取 加班类型信息
sql = "select id,mc from uf_jcl_kq_kqxm where id = " + jblx ;
Map< String , Object > jblxData = DbTools . getSqlToMap ( sql ) ;
String jblxName = Util . null2String ( jblxData . get ( "mc" ) ) ;
//获取 作用时段包含计划加班的加班类型的考勤项目集合
sql = "select id,mc , bddrqlx from uf_jcl_kq_kqxm where xmlx = ? and zysd = ?" ;
List< Map< String , Object > > jblxAttendanceList = DbTools . getSqlToList ( sql , AttendanceItemTypeEnum . WORK_OVERTIME . getKey ( ) , WorkForTimeEnum . PLAN_WORK_OVERTIME . getKey ( ) ) ;
//获取人员id和姓名信息
Map < String , String > empIdToNameInfo = CommonUtil . empIdToNameInfo ( empIdList ) ;
List < Map < String , Object > > bcDetailData ;
for ( String empId : empIdList ) {
List < Map < String , Object > > scheduleInfoList = scheduleInfoMap . get ( empId ) ;
Map < String , String > dateToBcxxMap = scheduleInfoList = = null ? new HashMap < > ( ) : scheduleInfoList . stream ( ) . collect ( Collectors . toMap ( e - > Util . null2String ( e . get ( "bcrq" ) ) , e - > Util . null2String ( e . get ( "bcxx" ) ) ) ) ;
Map < String , String > dateTypeInfoFromBc = scheduleInfoList = = null ? new HashMap < > ( ) : scheduleInfoList . stream ( ) . collect ( Collectors . toMap ( e - > Util . null2String ( e . get ( "bcrq" ) ) , e - > Util . null2String ( e . get ( "rqlx" ) ) ) ) ;
for ( String date : dateList ) {
String realEndDate = date ;
detailItem = new HashMap < > ( ) ;
detailItem . put ( "jbry" , empId ) ;
detailItem . put ( "jbryName" , Util . null2String ( empIdToNameInfo . get ( empId ) ) ) ;
detailItem . put ( "jblx" , jblx ) ;
detailItem . put ( "jblxName" , jblxName ) ;
detailItem . put ( "ksrq" , date ) ;
detailItem . put ( "kssj" , startTime ) ;
detailItem . put ( "jssj" , endTime ) ;
detailItem . put ( "jblx" , null ) ;
detailItem . put ( "jblxName" , null ) ;
//开始时时和结束时间存在跨天情况时,即开始时间大于等于结束时间
if ( startTime . compareTo ( endTime ) > = 0 ) {
realEndDate = DateUtil . AfterDay ( date , 1 ) ;
@ -81,47 +86,95 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//根据班次数据,设置归属日期
//获取当天班次id
String currentDayBcId = Util . null2String ( dateToBcxxMap . get ( date ) ) . split ( "-" ) [ 0 ] ;
//当天比较最晚工作时段/加班时段的结束时间点和加班计划明细的开始时间点的差值
Integer currentDayDiffMinutes = 9999 ;
if ( ! "" . equals ( currentDayBcId ) ) {
//查询当天班次明细
sql = "select id, bdlx, gsrq, kssj, jssj from uf_jcl_kq_bcxx_dt1 where mainid = " + currentDayBcId + " order by gsrq desc, kssj desc" ;
bcDetailData = DbTools . getSqlToList ( sql ) ;
bcDetailData = bcDetailData . stream ( ) . filter ( e - > workBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
if ( bcDetailData . size ( ) > 0 ) {
String gsrqValue = Util . null2String ( bcDetailData . get ( 0 ) . get ( "gsrq" ) ) ;
String jssj = Util . null2String ( bcDetailData . get ( 0 ) . get ( "jssj" ) ) ;
String matchDate = "2" . equals ( gsrqValue ) ? DateUtil . AfterDay ( date , 1 ) : ( "0" . equals ( gsrqValue ) ? DateUtil . beforeDay ( date , 1 ) : date ) ;
currentDayDiffMinutes = ( matchDate + jssj ) . compareTo ( date + startTime ) > 0 ? DateUtil . getBetWeenMinutes ( date + " " + startTime , matchDate + " " + jssj ) : DateUtil . getBetWeenMinutes ( matchDate + " " + jssj , date + " " + startTime ) ;
}
}
//获取当天班次开始时间和结束时间
String currentDayStartToEnd = getBcStartAndEndTime ( date , currentDayBcId , workBdlxList ) ;
String currentDayStartTime = ! "" . equals ( currentDayStartToEnd ) ? currentDayStartToEnd . split ( "," ) [ 0 ] : "" ;
String currentDayEndTime = ! "" . equals ( currentDayStartToEnd ) ? currentDayStartToEnd . split ( "," ) [ 1 ] : "" ;
//获取前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 beforeDayStartTime = ! "" . equals ( beforeDayStartToEnd ) ? beforeDayStartToEnd . split ( "," ) [ 0 ] : "" ;
String beforeDayEndTime = ! "" . equals ( beforeDayStartToEnd ) ? beforeDayStartToEnd . split ( "," ) [ 1 ] : "" ;
//获取次日班次id
String nextDay = DateUtil . AfterDay ( date , 1 ) ;
String nextDayBcId = Util . null2String ( dateToBcxxMap . get ( nextDay ) ) . split ( "-" ) [ 0 ] ;
//次日比较最早工作时段/加班时段的开始时间点和加班计划明细的结束时间点的差值
Integer nextDayDiffMinutes = 9999 ;
if ( ! "" . equals ( nextDayBcId ) ) {
//查次日班次明细
sql = "select id, bdlx, gsrq, kssj, jssj from uf_jcl_kq_bcxx_dt1 where mainid = " + nextDayBcId + " order by gsrq, kssj" ;
bcDetailData = DbTools . getSqlToList ( sql ) ;
bcDetailData = bcDetailData . stream ( ) . filter ( e - > workBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
if ( bcDetailData . size ( ) > 0 ) {
String gsrqValue = Util . null2String ( bcDetailData . get ( 0 ) . get ( "gsrq" ) ) ;
String kssj = Util . null2String ( bcDetailData . get ( 0 ) . get ( "kssj" ) ) ;
String matchDate = "2" . equals ( gsrqValue ) ? DateUtil . AfterDay ( nextDay , 1 ) : ( "0" . equals ( gsrqValue ) ? DateUtil . beforeDay ( nextDay , 1 ) : nextDay ) ;
nextDayDiffMinutes = ( matchDate + kssj ) . compareTo ( realEndDate + endTime ) > 0 ? DateUtil . getBetWeenMinutes ( realEndDate + " " + endTime , matchDate + " " + kssj ) : DateUtil . getBetWeenMinutes ( matchDate + " " + kssj , realEndDate + " " + endTime ) ;
}
String nextDayBcId = Util . null2String ( dateToBcxxMap . get ( DateUtil . AfterDay ( date , 1 ) ) ) . split ( "-" ) [ 0 ] ;
//获取次日班次开始时间和结束时间
String nextDayStartToEnd = getBcStartAndEndTime ( DateUtil . AfterDay ( date , 1 ) , nextDayBcId , workBdlxList ) ;
String nextDayStartTime = ! "" . equals ( nextDayStartToEnd ) ? nextDayStartToEnd . split ( "," ) [ 0 ] : "" ;
String nextDayEndTime = ! "" . equals ( nextDayStartToEnd ) ? nextDayStartToEnd . split ( "," ) [ 1 ] : "" ;
//梳理加班时间段和班段时间段合理的情况
boolean beforeToCurrentDay = false ;
boolean currentToNextDay = false ;
boolean beforeToNextDay = false ;
String belongDate = "" ;
if ( ! "" . equals ( currentDayStartToEnd ) ) {
//1-加班时间段处于前一日下班后和当日上班前
beforeToCurrentDay = ( "" . equals ( beforeDayEndTime ) | | beforeDayEndTime . compareTo ( date + " " + startTime ) < = 0 ) & & currentDayStartTime . compareTo ( realEndDate + " " + endTime ) > = 0 ;
//2-加班时间段处于当日下班后和次日上班前
currentToNextDay = ( "" . equals ( nextDayStartTime ) | | nextDayStartTime . compareTo ( realEndDate + " " + endTime ) > = 0 ) & & currentDayEndTime . compareTo ( date + " " + startTime ) < = 0 ;
} else {
//3-加班时间段处于前一日下班后和次日上班前
beforeToNextDay = ( "" . equals ( beforeDayEndTime ) | | beforeDayEndTime . compareTo ( date + " " + startTime ) < = 0 )
& & ( "" . equals ( nextDayStartTime ) | | nextDayStartTime . compareTo ( realEndDate + " " + endTime ) > = 0 ) ;
}
if ( currentDayDiffMinutes < = nextDayDiffMinutes ) {
detailItem . put ( "gsrq" , date ) ;
if ( beforeToCurrentDay ) {
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 ) ;
} 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 ) ;
} else if ( beforeToNextDay ) {
int beforeDayDiffMinutes = ! "" . equals ( beforeDayEndTime ) ? DateUtil . getBetWeenMinutes ( beforeDayEndTime , date + " " + startTime ) : 9999 ;
int nextDayDiffMinutes = ! "" . equals ( nextDayStartTime ) ? DateUtil . getBetWeenMinutes ( realEndDate + " " + endTime , nextDayStartTime ) : 9999 ;
if ( beforeDayDiffMinutes > 120 & & nextDayDiffMinutes > 120 ) {
//当天没班次时, 前后两天班次班段与加班区间相隔超过120分钟时, 则归属日为请假开始日期
belongDate = date ;
} else {
belongDate = beforeDayDiffMinutes < = nextDayDiffMinutes ? DateUtil . beforeDay ( date , 1 ) : DateUtil . AfterDay ( date , 1 ) ;
}
} else {
detailItem . put ( "gsrq" , nextDay ) ;
//4-其他情况,属于不合理加班安排,返回报错
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + date + "的加班计划区间和班次班段出现时间重叠,不允许申请加班!" ) ;
continue ;
}
//判断归属日的日期类型,首先从排班的信息来获取
String belongDateType = dateTypeInfoFromBc . getOrDefault ( belongDate , "" ) ;
//排班信息无法获取日期类型时,从日历信息获取
belongDateType = "" . equals ( belongDateType ) ? CommonUtil . getRqlx ( empId , belongDate ) : belongDateType ;
//排班和日历都无法获取时,默认为工作日
belongDateType = "" . equals ( belongDateType ) ? DateTypeEnum . WORK_DAY . getKey ( ) : belongDateType ;
//通过人员id、归属日期、归属日期类型来自动匹配加班类型
//获取人员在归属日被设置的考勤项目
List < Map < String , Object > > attendanceItemSetList = CommonUtil . getAttendanceItemsByEmpIdDate ( empId , belongDate ) ;
List < String > kqxmSetIds = attendanceItemSetList . stream ( ) . map ( f - > f . get ( "keyid" ) . toString ( ) ) . collect ( Collectors . toList ( ) ) ;
for ( Map < String , Object > attendanceItemInfo : jblxAttendanceList ) {
//判断该加班类型考勤项目是否被该人员使用,且考勤项目的绑定的日期类型是否包含归属日期类型
if ( kqxmSetIds . contains ( Util . null2String ( attendanceItemInfo . get ( "id" ) ) )
& & Util . null2String ( attendanceItemInfo . get ( "bddrqlx" ) ) . contains ( belongDateType ) ) {
detailItem . put ( "jblx" , Util . null2String ( attendanceItemInfo . get ( "id" ) ) ) ;
detailItem . put ( "jblxName" , Util . null2String ( attendanceItemInfo . get ( "mc" ) ) ) ;
}
}
detailItem . put ( "gsrq" , belongDate ) ;
overtimePlanDetailList . add ( detailItem ) ;
}
}
resultMap . put ( "status" , true ) ;
resultMap . put ( "data" , overtimePlanDetailList ) ;
if ( errorMessage . size ( ) = = 0 ) {
resultMap . put ( "status" , true ) ;
resultMap . put ( "data" , overtimePlanDetailList ) ;
} else {
resultMap . put ( "status" , false ) ;
resultMap . put ( "errorInfo" , errorMessage ) ;
resultMap . put ( "data" , null ) ;
}
} catch ( Exception e ) {
log . info ( e . getMessage ( ) ) ;
resultMap . put ( "status" , false ) ;
@ -130,4 +183,28 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
}
return resultMap ;
}
public String getBcStartAndEndTime ( String date , String currentDayBcId , List < String > workBdlxList ) {
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" ;
List < Map < String , Object > > bcDetailData = DbTools . getSqlToList ( sql ) ;
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 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 bdStartDate = "2" . equals ( startGsrqValue ) ? DateUtil . AfterDay ( date , 1 ) : ( "0" . equals ( startGsrqValue ) ? DateUtil . beforeDay ( date , 1 ) : date ) ;
startToEnd = bdStartDate + " " + firstKssj + "," + bdEndDate + " " + lastJssj ;
}
}
return startToEnd ;
}
}