package com.engine.jucailinkq.attendance.workflow.action ;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.UtilService ;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.impl.UtilServiceImpl ;
import com.engine.jucailinkq.attendance.enums.AccountingUnitEnum ;
import com.engine.jucailinkq.attendance.enums.AttendanceItemTypeEnum ;
import com.engine.jucailinkq.attendance.enums.DateTypeEnum ;
import com.engine.jucailinkq.attendance.enums.WorkForTimeEnum ;
import com.engine.jucailinkq.attendance.workflow.service.MakeUpClockInService ;
import com.engine.jucailinkq.attendance.workflow.service.impl.MakeUpClockInServiceImpl ;
import com.engine.jucailinkq.common.util.CommonUtil ;
import com.engine.jucailinkq.common.util.DateUtil ;
import com.engine.common.util.ServiceUtil ;
import com.engine.jucailinkq.common.util.DbTools ;
import com.engine.jucailinkq.common.util.Utils ;
import com.google.common.collect.Maps ;
import lombok.extern.slf4j.Slf4j ;
import weaver.general.TimeUtil ;
import weaver.general.Util ;
import weaver.interfaces.workflow.action.Action ;
import weaver.soa.workflow.request.RequestInfo ;
import java.util.* ;
import java.util.stream.Collectors ;
/ * *
* 加 班 计 划 流 程 提 交 检 查
* /
@Slf4j
public class OvertimePlanCheckAction implements Action {
private MakeUpClockInService makeUpClockInService = ServiceUtil . getService ( MakeUpClockInServiceImpl . class ) ;
private UtilService utilService = ServiceUtil . getService ( UtilServiceImpl . class ) ;
@Override
public String execute ( RequestInfo requestInfo ) {
String requestid = requestInfo . getRequestid ( ) ;
// 流程表单主表数据
HashMap < String , String > mainTableData = CommonUtil . getMainTableInfo ( requestInfo ) ;
// 流程表单明细表数据
List < Map < String , String > > detailTableData = CommonUtil . getDetailTableInfo ( requestInfo , 0 ) ;
//加班人员
String jbry = mainTableData . get ( "jbry" ) ;
try {
//获取人员id和姓名信息
List < String > empIdList = Arrays . asList ( jbry . split ( "," ) ) ;
Map < String , String > empIdToNameInfo = CommonUtil . empIdToNameInfo ( empIdList ) ;
//获取作用时段包含计划加班的加班类型的考勤项目集合
String sql = "select id,mc, bddrqlx, jbqsfzs, xzzjbsc, rzdjbxss, zzdjbxss, yzdjbxss, zysd, ccclfs from uf_jcl_kq_kqxm where xmlx = ?" ;
List < Map < String , Object > > jblxAttendanceList = DbTools . getSqlToList ( sql , AttendanceItemTypeEnum . WORK_OVERTIME . getKey ( ) ) ;
Map < String , Map < String , Object > > jblxInfo = jblxAttendanceList . stream ( )
. filter ( f - > Util . null2String ( f . get ( "zysd" ) ) . contains ( WorkForTimeEnum . PLAN_WORK_OVERTIME . getKey ( ) ) )
. collect ( Collectors . toMap ( e - > e . get ( "id" ) . toString ( ) , e - > e ) ) ;
//明细数据按照人员分组
Map < String , List < Map < String , String > > > detailGroupMap = detailTableData . stream ( ) . collect ( Collectors . groupingBy ( e - > Util . null2String ( e . get ( "jbry" ) ) ) ) ;
List < String > errorMessage = new ArrayList < > ( ) ;
for ( Map . Entry < String , List < Map < String , String > > > tableEntry : detailGroupMap . entrySet ( ) ) {
List < Map < String , String > > detailGroupByUserList = tableEntry . getValue ( ) ;
Map < String , Object > params = Maps . newHashMap ( ) ;
String empId = tableEntry . getKey ( ) ;
if ( "" . equals ( empId ) ) {
log . error ( "明细表中存在缺少加班人员信息的数据!" ) ;
requestInfo . getRequestManager ( ) . setMessageid ( "11111" + requestid + "22222" ) ;
requestInfo . getRequestManager ( ) . setMessagecontent ( "明细表中存在缺少加班人员信息的数据!" ) ;
return Action . FAILURE_AND_CONTINUE ;
} else {
params . put ( "userId" , empId ) ;
}
params . put ( "submitDate" , DateUtil . getCurrentDate ( ) ) ;
params . put ( "submitStr" , "ksrq" ) ;
params . put ( "submitDataList" , detailGroupByUserList ) ;
/ * *
* 考 勤 周 期 校 验
* /
if ( detailGroupByUserList = = null | | detailGroupByUserList . size ( ) = = 0 ) {
log . error ( "明细表没有数据!" ) ;
requestInfo . getRequestManager ( ) . setMessageid ( "11111" + requestid + "22222" ) ;
requestInfo . getRequestManager ( ) . setMessagecontent ( "明细表没有数据!" ) ;
return Action . FAILURE_AND_CONTINUE ;
}
Map < String , Object > dataMap = makeUpClockInService . getKqCycleTimeIntervalCmd ( params ) ;
List < Map < String , Object > > closeList = ( List < Map < String , Object > > ) dataMap . get ( "closeList" ) ;
List < String > nocycleList = ( List < String > ) dataMap . get ( "nocycleList" ) ;
List < Map < String , Object > > dateList = ( List < Map < String , Object > > ) dataMap . get ( "dataList" ) ;
boolean status = ( boolean ) dataMap . get ( "status" ) ;
if ( ! status ) {
log . error ( "该人员没有考勤周期" ) ;
requestInfo . getRequestManager ( ) . setMessageid ( "11111" + requestid + "22222" ) ;
requestInfo . getRequestManager ( ) . setMessagecontent ( "该人员没有考勤周期!" ) ;
return Action . FAILURE_AND_CONTINUE ;
}
if ( closeList . size ( ) > 0 | | nocycleList . size ( ) > 0 ) {
String message = "" ;
if ( nocycleList . size ( ) > 0 ) {
message = message + String . join ( "," , nocycleList ) + "未找对对应的考勤周期;" ;
}
if ( closeList . size ( ) > 0 ) {
List < String > list = closeList . stream ( ) . map ( e - > e . get ( "rq" ) . toString ( ) ) . collect ( Collectors . toList ( ) ) ;
message = message + String . join ( "," , list ) + "对应的考勤周期的考勤周期已关账" ;
}
requestInfo . getRequestManager ( ) . setMessageid ( "11111" + requestid + "22222" ) ;
requestInfo . getRequestManager ( ) . setMessagecontent ( message ) ;
return Action . FAILURE_AND_CONTINUE ;
}
//校验加班类型中最小加班分钟数、工作日最大加班小时数、周最大加班小时数、月最大加班小时数等限定值
List < Map < String , String > > overtimeDetailList = tableEntry . getValue ( ) ;
Map < String , Object > matchItemInfo ;
if ( overtimeDetailList = = null | | overtimeDetailList . size ( ) = = 0 ) {
continue ;
}
Map < String , Double > weekOvertimeInfo = new HashMap < > ( ) ;
Map < String , Double > monthOvertimeInfo = new HashMap < > ( ) ;
for ( Map < String , String > overtimeDetailItem : overtimeDetailList ) {
String belongDate = overtimeDetailItem . get ( "gsrq" ) ;
//从排班信息获取归属日日期类型
String belongDateType = utilService . getRqlxInScheduleInfo ( empId , belongDate ) ;
//排班信息无法获取日期类型时,从日历信息获取
belongDateType = "" . equals ( belongDateType ) ? CommonUtil . getRqlx ( empId , belongDate ) : belongDateType ;
//排班和日历都无法获取时,默认为工作日
belongDateType = "" . equals ( belongDateType ) ? DateTypeEnum . WORK_DAY . getKey ( ) : belongDateType ;
String startDate = overtimeDetailItem . get ( "ksrq" ) ;
String jbsc = overtimeDetailItem . get ( "jbsc" ) ;
double overtimeMinutes = Double . parseDouble ( jbsc ) * 60 ;
String jblxId = overtimeDetailItem . getOrDefault ( "jblx" , "" ) ;
matchItemInfo = jblxInfo . getOrDefault ( jblxId , new HashMap < > ( ) ) ;
String minMinutes = Util . null2String ( matchItemInfo . get ( "jbqsfzs" ) ) ;
if ( ! "" . equals ( minMinutes ) & & Integer . parseInt ( minMinutes ) > overtimeMinutes ) {
//最小加班分钟数大于单条明细的加班时长分钟数
String message = Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + startDate + "的加班分钟数小于加班类型-"
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的最小加班分钟数!" ;
log . error ( message ) ;
requestInfo . getRequestManager ( ) . setMessageid ( "11111" + requestid + "22222" ) ;
requestInfo . getRequestManager ( ) . setMessagecontent ( message ) ;
return Action . FAILURE_AND_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 ) ) + "在日期" + startDate + "的加班时长累计后超过了加班类型-"
+ 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 ) ) + "在日期" + startDate + "的加班时长累计后超过了加班类型-"
+ 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 ) ;
}
monthOvertimeInfo . put ( yearMonth , monthOvertimeMinutes + overtimeMinutes ) ;
if ( maxMonthMinutes - monthOvertimeMinutes - overtimeMinutes < 0 ) {
//达到月加班最大小时数
doLimitMonthHours = true ;
errorMessage . add ( Util . null2String ( empIdToNameInfo . get ( empId ) ) + "在日期" + startDate + "的加班时长累计后超过了加班类型-"
+ Util . null2String ( matchItemInfo . get ( "mc" ) ) + "设置的月加班最大小时数!" ) ;
}
}
//判断是否超出工作日、周、月最大小时数要求,在加班类型考勤项目中设置为“禁止提交时”,返回报错
if ( "1" . equals ( limitDealType ) & & ( doLimitWorkDayHours | | doLimitWeekHours | | doLimitMonthHours ) ) {
log . error ( "超出加班类型工作日/周/月最大加班小时数限制!" ) ;
requestInfo . getRequestManager ( ) . setMessageid ( "11111" + requestid + "22222" ) ;
requestInfo . getRequestManager ( ) . setMessagecontent ( String . valueOf ( errorMessage ) ) ;
return Action . FAILURE_AND_CONTINUE ;
}
}
}
}
} catch ( Exception e ) {
log . error ( "OvertimePlanCheckAction error : [{}]" , e ) ;
return Action . FAILURE_AND_CONTINUE ;
}
return Action . SUCCESS ;
}
/ * *
* 获 得 一 周 加 班 分 钟 数
* @param dataList
* @return
* /
public double getWeekTimeMinutes ( List < Map < String , Object > > dataList , String date ) {
int day = TimeUtil . getDayOfWeek ( date ) ;
if ( day = = 0 ) {
day = 7 ;
}
String startDate = DateUtil . beforeDay ( date , day - 1 ) ;
String endDate = DateUtil . AfterDay ( date , 7 - day ) ;
List < Map < String , Object > > list = dataList . stream ( ) . filter ( e - > {
String sjksrq = Util . null2String ( e . get ( "sjksrq" ) ) ;
if ( DateUtil . getTime ( sjksrq ) . compareTo ( DateUtil . getTime ( startDate ) ) > = 0 & &
DateUtil . getTime ( sjksrq ) . compareTo ( DateUtil . getTime ( endDate ) ) < = 0 & &
DateUtil . getTime ( sjksrq ) . compareTo ( DateUtil . getTime ( date ) ) ! = 0 ) {
return true ;
} else {
return false ;
}
} ) . collect ( Collectors . toList ( ) ) ;
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 ) ;
}
return totalMinutes ;
}
/ * *
* 获 得 一 个 月 加 班 分 钟 数
* @param dataList
* @return
* /
public double getMonthTimeMinutes ( List < Map < String , Object > > dataList , String date ) {
String startDate = date . split ( "-" ) [ 0 ] + "-" + date . split ( "-" ) [ 1 ] + "-01" ;
String endDate = date . split ( "-" ) [ 0 ] + "-" + date . split ( "-" ) [ 1 ] + "-31" ;
List < Map < String , Object > > list = dataList . stream ( ) . filter ( e - > DateUtil . getTime ( e . get ( "sjksrq" ) . toString ( ) ) . compareTo ( DateUtil . getTime ( startDate ) ) > = 0 & &
DateUtil . getTime ( e . get ( "sjjsrq" ) . toString ( ) ) . compareTo ( DateUtil . getTime ( endDate ) ) < = 0 ) . collect ( Collectors . toList ( ) ) ;
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 ) ;
}
return totalMinutes ;
}
/ * *
* 获 取 目 标 人 员 时 间 区 间 内 的 加 班 结 果
* /
public List < Map < String , Object > > getWorkOverTimeResults ( String startDate , String endDate , String userId ) {
String sql = "select a.sjjbsc, a.sjksrq, a.sjjsrq, a.jblx, b.hsdw from uf_jcl_kq_jbjg a left join uf_jcl_kq_kqxm b on a.jblx = b.id where a.jbry=? and a.sjksrq>=? and a.sjjsrq<=?" ;
List < Map < String , Object > > dataList = DbTools . getSqlToList ( sql , userId , startDate , endDate ) ;
return dataList ;
}
}