@ -1,14 +1,26 @@
package com.engine.jucailinkq.attendance.workflow.service.impl ;
import com.engine.common.util.ServiceUtil ;
import com.engine.jucailinkq.attendance.component.persongroup.service.SchedulingResultsService ;
import com.engine.jucailinkq.attendance.component.persongroup.service.impl.SchedulingResultsServiceImpl ;
import com.engine.jucailinkq.attendance.enums.AccountingUnitEnum ;
import com.engine.jucailinkq.attendance.enums.CheckBoxEnum ;
import com.engine.jucailinkq.attendance.enums.ClassSegmentTypeEnum ;
import com.engine.jucailinkq.attendance.enums.DateTypeEnum ;
import com.engine.jucailinkq.attendance.workflow.cmd.GetRestDayIntervalCmd ;
import com.engine.jucailinkq.attendance.workflow.enums.AskAndEvctionWayEnum ;
import com.engine.jucailinkq.attendance.workflow.service.BusinessTripsApplyService ;
import com.engine.jucailinkq.attendance.workflow.service.MakeUpClockInService ;
import com.engine.jucailinkq.common.util.CommonUtil ;
import com.engine.jucailinkq.common.util.DateUtil ;
import com.engine.jucailinkq.common.util.DbTools ;
import com.engine.core.impl.Service ;
import com.engine.jucailinkq.common.util.Utils ;
import lombok.extern.slf4j.Slf4j ;
import weaver.general.Util ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.* ;
import java.util.stream.Collectors ;
/ * *
* @Author : sy
@ -17,6 +29,11 @@ import java.util.Map;
* * /
@Slf4j
public class BusinessTripsApplyServiceImpl extends Service implements BusinessTripsApplyService {
private SchedulingResultsService schedulingResultsService = ServiceUtil . getService ( SchedulingResultsServiceImpl . class ) ;
private MakeUpClockInService makeUpClockInService = ServiceUtil . getService ( MakeUpClockInServiceImpl . class ) ;
@Override
public Map < String , Object > getBusinessTripsApplyList ( Map < String , Object > params ) {
@ -40,4 +57,482 @@ public class BusinessTripsApplyServiceImpl extends Service implements BusinessTr
return retmap ;
}
@Override
public Map < String , Object > generateBusinessTripsList ( Map < String , Object > params ) {
Map < String , Object > resultMap = new HashMap < > ( ) ;
try {
List < String > errorMessage = new ArrayList < > ( ) ;
// 流程表单主表数据
Map < String , String > mainTableData = ( Map < String , String > ) params . get ( "mainTableData" ) ;
log . info ( "mainTableData : {}" , mainTableData ) ;
// 流程表单明细表1数据
List < Map < String , String > > detailTableData = ( List < Map < String , String > > ) params . get ( "detailTableData" ) ;
//开始日期、结束日期、出差方式、开始时间、结束时间、出差类型、出差时长
String startDate = Util . null2String ( mainTableData . get ( "ksrq" ) ) ;
String endDate = Util . null2String ( mainTableData . get ( "jsrq" ) ) ;
String startTime = Util . null2String ( mainTableData . get ( "kssj" ) ) ;
String endTime = Util . null2String ( mainTableData . get ( "jssj" ) ) ;
String ccMode = Util . null2String ( mainTableData . get ( "ccsd" ) ) ;
String ccType = Util . null2String ( mainTableData . get ( "cclx" ) ) ;
String ccDuration = Util . null2String ( mainTableData . get ( "ccsc" ) ) ;
String dailyRepeat = Util . null2String ( mainTableData . get ( "mttsdcc" ) ) ;
//获取出差日期集合
List < String > ccDateList = DateUtil . getDatesBetween ( startDate , endDate ) ;
//记录已编辑的出差记录,<人员id-出差类型-日期, 请假时长>
Map < String , String > editedCcInfo = new HashMap < > ( ) ;
//处理明细表1数据, 生成触发接口之前编辑内容中的出差信息
editedCcInfo = dealDetailTableData ( detailTableData , editedCcInfo ) ;
//处理主表数据
String ccr = Util . null2String ( mainTableData . get ( "ccr" ) ) ;
//出差人姓名映射
Map < String , String > empIdToName = new HashMap < > ( ) ;
//出差人员列表
List < String > ccEmpIdList = new ArrayList < > ( ) ;
if ( ! "" . equals ( ccr ) ) {
ccEmpIdList = Arrays . asList ( ccr . split ( "," ) ) ;
String sql = "select id, lastname from hrmresource where id in (" + ccr + ")" ;
List < Map < String , Object > > data = DbTools . getSqlToList ( sql ) ;
empIdToName = data . stream ( ) . collect ( Collectors . toMap ( e - > Util . null2String ( e . get ( "id" ) ) , e - > Util . null2String ( e . get ( "lastname" ) ) ) ) ;
}
//获取填写的出差类型关联的考勤项目
String sql = "select id,mc,hsdw,hsl,jcbyxsyqjb,yxsydjb,qzsyyxjb,zdycbcndfgzsd,zdycrqqjndxxb,yxyz,zdyzsl,zysd from uf_jcl_kq_kqxm where id=?" ;
Map < String , Object > holidayItem = DbTools . getSqlToMap ( sql , ccType ) ;
//出差类型名称
String checkItemName = Util . null2String ( holidayItem . get ( "mc" ) ) ;
//核算单位
String hsdw = Util . null2String ( holidayItem . get ( "hsdw" ) ) ;
//核算量
double hsl = Double . parseDouble ( Util . null2String ( holidayItem . get ( "hsl" ) ) ) ;
//核算单位为天时,只允许请全天假、半天假
if ( hsdw . equals ( AccountingUnitEnum . DAY . getKey ( ) ) & & ! ccMode . equals ( AskAndEvctionWayEnum . ALLDAY . getKey ( ) ) & & ! ccMode . equals ( AskAndEvctionWayEnum . HALFDAY . getKey ( ) ) ) {
resultMap . put ( "status" , false ) ;
resultMap . put ( "errorInfo" , "出差类型的核算单位为天时,只允许选择全天、半天!" ) ;
resultMap . put ( "data" , null ) ;
return resultMap ;
}
//判断是否需要自动移除时间区间内的非工作时长、自动移除日期区间内的休息日
boolean removeNonWorkTimeRange = "1" . equals ( Util . null2String ( holidayItem . get ( "zdycbcndfgzsd" ) ) ) ;
boolean removeNonWorkDayRange = "1" . equals ( Util . null2String ( holidayItem . get ( "zdycrqqjndxxb" ) ) ) ;
//获取作用时段
String zysd = Util . null2String ( holidayItem . get ( "zysd" ) ) ;
//获取需要统计时长的班段类型集合(仅作用在“指定时间区间”请假方式)
List < String > countBdlxList = new ArrayList < > ( ) ;
List < String > zysdList = new ArrayList < > ( ) ;
if ( ! "" . equals ( zysd ) ) {
zysdList = Arrays . asList ( zysd . split ( "," ) ) ;
for ( String zysdKey : zysdList ) {
countBdlxList . add ( Utils . getClassSegmenByWorkFor ( zysdKey ) ) ;
}
if ( ! removeNonWorkTimeRange ) {
countBdlxList . add ( ClassSegmentTypeEnum . REST_AND_DINE . getKey ( ) ) ;
countBdlxList . add ( ClassSegmentTypeEnum . REST_PERIOD . getKey ( ) ) ;
countBdlxList . add ( ClassSegmentTypeEnum . DINING_PERIOD . getKey ( ) ) ;
}
}
//遍历人员、日期,生成人员+日期+出差时长的出差信息
//出差人的出差区间内每一天的日期类型信息,来自于企业日历
Map < String , List < String > > restDayInfo = removeNonWorkDayRange ? getRestDayWithEmpId ( ccEmpIdList , startDate , endDate ) : new HashMap < > ( ) ;
//出差人的出差区间内的排班结果
Map < String , List < Map < String , Object > > > scheduleInfoMap = ( removeNonWorkDayRange | | removeNonWorkTimeRange ) ? getScheduleInfoWithEmpId ( ccEmpIdList , DateUtil . beforeDay ( startDate , 1 ) , DateUtil . AfterDay ( endDate , 1 ) ) : new HashMap < > ( ) ;
//生成出差明细数据
List < Map < String , String > > simpleDetailList ;
if ( ccMode . equals ( AskAndEvctionWayEnum . TIME_INTERVAL . getKey ( ) ) & & ! "1" . equals ( dailyRepeat ) ) {
simpleDetailList = createDetailListWithNoDaily ( ccEmpIdList , ccDateList , removeNonWorkDayRange , scheduleInfoMap ,
restDayInfo , startDate , endDate , startTime , endTime , countBdlxList , hsdw , hsl , ccType , empIdToName , checkItemName ) ;
} else {
simpleDetailList = createDetailList ( ccEmpIdList , ccDateList , removeNonWorkDayRange , scheduleInfoMap ,
restDayInfo , ccMode , startTime , endTime , ccDuration , countBdlxList , hsdw , hsl , ccType , empIdToName , checkItemName ) ;
}
//按照人员id分组处理请假明细信息, 关联假期余额数据
Map < String , List < Map < String , String > > > ccDetailGroupByEmp = simpleDetailList . stream ( ) . collect ( Collectors . groupingBy ( e - > Util . null2String ( e . get ( "ccr" ) ) ) ) ;
//收集需要新建的出差明细数据
List < Map < String , String > > completeLeaveDetailList = new ArrayList < > ( ) ;
Map < String , String > finalEditedCcInfo = editedCcInfo ;
for ( Map . Entry < String , List < Map < String , String > > > entry : ccDetailGroupByEmp . entrySet ( ) ) {
//校验该人员的考勤周期是否正常
boolean kqCycleAllow = kqCycleCheck ( entry . getKey ( ) , entry . getValue ( ) , errorMessage , empIdToName . get ( entry . getKey ( ) ) ) ;
if ( ! kqCycleAllow ) {
continue ;
}
List < Map < String , String > > detailListItem = entry . getValue ( ) . stream ( )
. filter ( f - > finalEditedCcInfo . get ( Util . null2String ( f . get ( "ccr" ) ) + "_" + Util . null2String ( f . get ( "cclx" ) ) + "_" + Util . null2String ( f . get ( "ksrq" ) ) ) = = null )
. collect ( Collectors . toList ( ) ) ;
if ( detailListItem . size ( ) > 0 ) {
completeLeaveDetailList . addAll ( detailListItem ) ;
}
}
if ( errorMessage . size ( ) = = 0 ) {
resultMap . put ( "status" , true ) ;
resultMap . put ( "data" , completeLeaveDetailList ) ;
} else {
resultMap . put ( "status" , false ) ;
resultMap . put ( "errorInfo" , errorMessage ) ;
resultMap . put ( "data" , null ) ;
}
} catch ( Exception e ) {
log . info ( e . getMessage ( ) ) ;
resultMap . put ( "status" , false ) ;
resultMap . put ( "errorInfo" , e . getMessage ( ) ) ;
resultMap . put ( "data" , null ) ;
}
return resultMap ;
}
/ * *
* 出 差 人 的 出 差 区 间 内 属 于 休 息 日 的 日 期 集 合 , 企 业 日 历 角 度
* @param empIdList 出 差 人 id 集 合
* @param startDate 开 始 日 期
* @param endDate 结 束 日 期
* /
private Map < String , List < String > > getRestDayWithEmpId ( List < String > empIdList , String startDate , String endDate ) {
Map < String , List < String > > restDayInfoWithEmpId = new HashMap < > ( ) ;
Map < String , Object > restDayParam = new HashMap < > ( ) ;
restDayParam . put ( "startDate" , startDate ) ;
restDayParam . put ( "endDate" , endDate ) ;
List < String > dateTypeList = new ArrayList < > ( ) ;
dateTypeList . add ( DateTypeEnum . HOLIDAY . getKey ( ) ) ;
dateTypeList . add ( DateTypeEnum . PUBLIC_RESTDAY . getKey ( ) ) ;
dateTypeList . add ( DateTypeEnum . EXCHANGE_LEAVEDAY . getKey ( ) ) ;
Map < String , Object > restDayInfo ;
List < Map < String , Object > > dataList ;
List < String > restDateList = new ArrayList < > ( ) ;
for ( String empId : empIdList ) {
restDayParam . put ( "userId" , empId ) ;
restDayInfo = commandExecutor . execute ( new GetRestDayIntervalCmd ( restDayParam , user ) ) ;
dataList = ( List < Map < String , Object > > ) restDayInfo . get ( "data" ) ;
if ( dataList ! = null & & dataList . size ( ) > 0 ) {
restDateList = dataList . stream ( )
. filter ( f - > dateTypeList . contains ( Util . null2String ( f . get ( "rqlx" ) ) ) )
. map ( e - > Util . null2String ( e . get ( "rq" ) ) )
. collect ( Collectors . toList ( ) ) ;
}
restDayInfoWithEmpId . put ( empId , restDateList ) ;
}
return restDayInfoWithEmpId ;
}
/ * *
* 出 差 人 的 出 差 区 间 内 的 排 班 结 果
* @param empIdList 出 差 人 id 集 合
* @param startDate 开 始 日 期
* @param endDate 结 束 日 期
* /
private Map < String , List < Map < String , Object > > > getScheduleInfoWithEmpId ( List < String > empIdList , String startDate , String endDate ) {
Map < String , List < Map < String , Object > > > scheduleInfo = new HashMap < > ( ) ;
Map < String , Object > params = new HashMap < > ( ) ;
params . put ( "tableName" , "uf_pbjg" ) ;
params . put ( "startDate" , startDate ) ;
params . put ( "endDate" , endDate ) ;
params . put ( "pblx" , "0" ) ;
params . put ( "current" , "1" ) ;
params . put ( "pageSize" , "999" ) ;
params . put ( "recurrence" , "1" ) ;
for ( String empId : empIdList ) {
params . put ( "pbdx" , empId ) ;
Map < String , Object > schedulingResultsMap = schedulingResultsService . queryDataTableActualUse ( params ) ;
scheduleInfo . put ( empId , ( List < Map < String , Object > > ) schedulingResultsMap . get ( "data" ) ) ;
}
return scheduleInfo ;
}
/ * *
* @param empId 人 员 id
* @param detailTableData 明 细 数 据 列 表
* @param errorMessage 错 误 信 息
* @param empName 人 员 姓 名
* @return 校 验 该 人 员 的 考 勤 周 期 是 否 正 常
* /
private boolean kqCycleCheck ( String empId , List < Map < String , String > > detailTableData , List < String > errorMessage , String empName ) {
Map < String , Object > params = new HashMap < > ( ) ;
params . put ( "userId" , empId ) ;
params . put ( "submitDate" , DateUtil . getCurrentDate ( ) ) ;
params . put ( "submitStr" , "ksrq" ) ;
params . put ( "submitDataList" , detailTableData ) ;
if ( detailTableData = = null | | detailTableData . size ( ) = = 0 ) {
errorMessage . add ( empName + "没有明细数据!" ) ;
return false ;
}
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" ) ;
boolean status = ( boolean ) dataMap . get ( "status" ) ;
if ( ! status ) {
errorMessage . add ( empName + "没有考勤周期!" ) ;
return false ;
}
if ( closeList . size ( ) > 0 | | nocycleList . size ( ) > 0 ) {
String message = empName + ": " ;
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 ) + "对应的考勤周期的考勤周期已关账" ;
}
errorMessage . add ( message ) ;
return false ;
}
return true ;
}
/ * *
* @param detailTableData 明 细 表 1 数 据
* @param editedLeaveInfo 记 录 已 编 辑 的 出 差 记 录 , < 人 员 id - 出 差 类 型 - 日 期 , 出 差 时 长 >
* @return 处 理 明 细 表 1 数 据 , 生 成 触 发 接 口 之 前 编 辑 内 容 中 的 出 差 信 息
* /
private Map < String , String > dealDetailTableData ( List < Map < String , String > > detailTableData , Map < String , String > editedLeaveInfo ) {
if ( detailTableData ! = null & & detailTableData . size ( ) > 0 ) {
editedLeaveInfo = detailTableData . stream ( )
. collect ( Collectors . toMap ( e - > Util . null2String ( e . get ( "ccr" ) ) + "_" + Util . null2String ( e . get ( "cclx" ) ) + "_" + Util . null2String ( e . get ( "ksrq" ) ) ,
e - > Util . null2String ( e . get ( "qjsc" ) ) ) ) ;
}
return editedLeaveInfo ;
}
/ * *
* @param empIdList 人 员 id 集 合
* @param dateList 日 期 集 合
* @param removeNonWorkDayRange 是 否 移 除 非 工 作 日 时 长
* @param scheduleInfoMap 排 班 信 息
* @param restDayInfo 休 息 日 信 息
* @param mode 出 差 方 式
* @param startTime 开 始 时 间
* @param endTime 结 束 时 间
* @param ccDuration 出 差 时 长
* @param countBdlxList 收 集 需 要 统 计 时 长 的 班 段 类 型
* @return 组 装 初 步 的 出 差 明 细
* /
private List < Map < String , String > > createDetailList ( List < String > empIdList , List < String > dateList , boolean removeNonWorkDayRange ,
Map < String , List < Map < String , Object > > > scheduleInfoMap , Map < String , List < String > > restDayInfo ,
String mode , String startTime , String endTime , String ccDuration , List < String > countBdlxList ,
String hsdw , double hsl , String ccType , Map < String , String > empIdToName , String checkItemName ) {
List < Map < String , String > > simpleDetailList = new ArrayList < > ( ) ;
Map < String , String > simpleDetailItem ;
for ( String ccEmpId : empIdList ) {
//需要自动移除日期区间内的休息日时,去除出差日期区间中的休息日
List < Map < String , Object > > scheduleInfoList = scheduleInfoMap . getOrDefault ( ccEmpId , new ArrayList < > ( ) ) ;
Map < String , String > dateToBcxxMap = scheduleInfoList . stream ( ) . collect ( Collectors . toMap ( e - > Util . null2String ( e . get ( "bcrq" ) ) , e - > Util . null2String ( e . get ( "bcxx" ) ) ) ) ;
List < String > restDateList = new ArrayList < > ( ) ;
if ( removeNonWorkDayRange ) {
//排班结果中休息的日期
List < String > restDateListFromSchedule = scheduleInfoList . stream ( )
. filter ( f - > Util . null2String ( f . get ( "sfxx" ) ) . equals ( CheckBoxEnum . CHECKED . getKey ( ) ) )
. map ( e - > Util . null2String ( e . get ( "bcrq" ) ) )
. collect ( Collectors . toList ( ) ) ;
List < String > allDateListFromSchedule = scheduleInfoList . stream ( ) . map ( e - > Util . null2String ( e . get ( "bcrq" ) ) ) . collect ( Collectors . toList ( ) ) ;
//排班结果中未出现的日期
List < String > nonSetDateListFromSchedule = dateList . stream ( ) . filter ( f - > ! allDateListFromSchedule . contains ( f ) ) . collect ( Collectors . toList ( ) ) ;
//企业日历中人员对应日期的休息日
restDateList = restDayInfo . get ( ccEmpId ) ;
//筛选排班信息无法辨别的日期,依靠企业日历的日期信息
restDateList = restDateList . stream ( ) . filter ( nonSetDateListFromSchedule : : contains ) . collect ( Collectors . toList ( ) ) ;
restDateList . addAll ( restDateListFromSchedule ) ;
}
String ccEmpName = empIdToName . get ( ccEmpId ) ;
for ( String ccDate : dateList ) {
//出差方式为“指定时间区间”时
if ( mode . equals ( AskAndEvctionWayEnum . TIME_INTERVAL . getKey ( ) ) ) {
simpleDetailItem = new HashMap < > ( ) ;
//组装初步的明细数据
simpleDetailItem . put ( "ccr" , ccEmpId ) ;
simpleDetailItem . put ( "cclx" , ccType ) ;
simpleDetailItem . put ( "ccrName" , ccEmpName ) ;
simpleDetailItem . put ( "cclxName" , checkItemName ) ;
simpleDetailItem . put ( "ksrq" , ccDate ) ;
simpleDetailItem . put ( "jsrq" , ccDate ) ;
simpleDetailItem . put ( "kssj" , startTime ) ;
simpleDetailItem . put ( "jssj" , endTime ) ;
//获取当天班次id
String currentDayBcId = restDateList . contains ( ccDate ) ? "" : Util . null2String ( dateToBcxxMap . get ( ccDate ) ) . split ( "-" ) [ 0 ] ;
//获取前一天班次id
String yesterday = DateUtil . beforeDay ( ccDate , 1 ) ;
String yesterdayBcId = restDateList . contains ( yesterday ) ? "" : Util . null2String ( dateToBcxxMap . get ( yesterday ) ) . split ( "-" ) [ 0 ] ;
//获取次日班次id
String nextDay = DateUtil . AfterDay ( ccDate , 1 ) ;
String nextDayBcId = restDateList . contains ( nextDay ) ? "" : Util . null2String ( dateToBcxxMap . get ( nextDay ) ) . split ( "-" ) [ 0 ] ;
String sql = "" ;
List < Map < String , Object > > bcDetailData ;
String endDate = ccDate ;
int scMinutes = 0 ;
//开始时时和结束时间存在跨天情况时,即开始时间大于等于结束时间
if ( startTime . compareTo ( endTime ) > = 0 ) {
endDate = nextDay ;
simpleDetailItem . put ( "jsrq" , nextDay ) ;
}
if ( ! "" . equals ( yesterdayBcId ) ) {
sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + yesterdayBcId ;
bcDetailData = DbTools . getSqlToList ( sql ) ;
bcDetailData = bcDetailData . stream ( ) . filter ( e - > countBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
//获取需要累计的班段时长区间和请假区间存在交集的分钟数
scMinutes = Utils . removeTime ( ccDate + " " + startTime , endDate + " " + endTime , bcDetailData , yesterday ) ;
}
if ( ! "" . equals ( currentDayBcId ) ) {
sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + currentDayBcId ;
bcDetailData = DbTools . getSqlToList ( sql ) ;
bcDetailData = bcDetailData . stream ( ) . filter ( e - > countBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
//获取需要累计的班段时长区间和请假区间存在交集的分钟数
scMinutes = scMinutes + Utils . removeTime ( ccDate + " " + startTime , endDate + " " + endTime , bcDetailData , ccDate ) ;
}
if ( ! "" . equals ( nextDayBcId ) ) {
sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + nextDayBcId ;
bcDetailData = DbTools . getSqlToList ( sql ) ;
bcDetailData = bcDetailData . stream ( ) . filter ( e - > countBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
//获取需要累计的班段时长区间和请假区间存在交集的分钟数
scMinutes = scMinutes + Utils . removeTime ( ccDate + " " + startTime , endDate + " " + endTime , bcDetailData , nextDay ) ;
}
//增加加班计划中的数据,加班计划明细中的数据作为“加班计划”班段类型数据的补充
if ( countBdlxList . contains ( ClassSegmentTypeEnum . OVERTIME_PLAN . getKey ( ) ) ) {
sql = "select b.jbry,b.ksrq,b.kssj,b.jblx,b.jsrq,b.jssj,b.jbsc,b.gsrq from uf_jcl_kq_jbjh a left join uf_jcl_kq_jbjh_dt1 b on a.id=b.mainid where b.jbry =? and b.ksrq>=? and b.jsrq<=? and (b.jbcx=0 or b.jbcx is null) and a.jlzt=1" ;
List < Map < String , Object > > overtimePlanList = DbTools . getSqlToList ( sql , ccEmpId , DateUtil . beforeDay ( ccDate , 1 ) , DateUtil . AfterDay ( endDate , 1 ) ) ;
int scMinutesInOvertimePlan = Utils . removeTimeWithOvertimePlan ( ccDate + " " + startTime , endDate + " " + endTime , overtimePlanList ) ;
scMinutes = scMinutes + scMinutesInOvertimePlan ;
}
if ( scMinutes > 0 ) {
double ccscByAccount = Utils . getItemduration ( hsl , hsdw , scMinutes , AccountingUnitEnum . MINUTES , 8.0 ) ;
//组装初步的出差时长
simpleDetailItem . put ( "ccsc" , hsdw . equals ( AccountingUnitEnum . MINUTES . getKey ( ) )
? String . format ( "%.2f" , ccscByAccount / 60.0 )
: String . valueOf ( ccscByAccount ) ) ;
simpleDetailList . add ( simpleDetailItem ) ;
}
} else if ( mode . equals ( AskAndEvctionWayEnum . HOUR . getKey ( ) ) & & ! restDateList . contains ( ccDate ) ) {
simpleDetailItem = new HashMap < > ( ) ;
//组装初步的明细数据
simpleDetailItem . put ( "ccr" , ccEmpId ) ;
simpleDetailItem . put ( "cclx" , ccType ) ;
simpleDetailItem . put ( "ccrName" , ccEmpName ) ;
simpleDetailItem . put ( "cclxName" , checkItemName ) ;
simpleDetailItem . put ( "ksrq" , ccDate ) ;
simpleDetailItem . put ( "jsrq" , ccDate ) ;
simpleDetailItem . put ( "ccsc" , ccDuration ) ;
if ( Double . parseDouble ( ccDuration ) > 0 ) {
double ccscByAccount = Utils . getItemduration ( hsl , hsdw , Double . parseDouble ( ccDuration ) , AccountingUnitEnum . HOUR , 8.0 ) ;
//组装初步的出差时长
simpleDetailItem . put ( "ccsc" , hsdw . equals ( AccountingUnitEnum . MINUTES . getKey ( ) )
? String . format ( "%.2f" , ccscByAccount / 60.0 )
: String . valueOf ( ccscByAccount ) ) ;
simpleDetailList . add ( simpleDetailItem ) ;
}
} else if ( mode . equals ( AskAndEvctionWayEnum . ALLDAY . getKey ( ) ) & & ! restDateList . contains ( ccDate ) ) {
simpleDetailItem = new HashMap < > ( ) ;
//组装初步的明细数据
simpleDetailItem . put ( "ccr" , ccEmpId ) ;
simpleDetailItem . put ( "cclx" , ccType ) ;
simpleDetailItem . put ( "ccrName" , ccEmpName ) ;
simpleDetailItem . put ( "cclxName" , checkItemName ) ;
simpleDetailItem . put ( "ksrq" , ccDate ) ;
simpleDetailItem . put ( "jsrq" , ccDate ) ;
simpleDetailItem . put ( "qtcc" , "1" ) ;
simpleDetailList . add ( simpleDetailItem ) ;
} else if ( mode . equals ( AskAndEvctionWayEnum . HALFDAY . getKey ( ) ) & & ! restDateList . contains ( ccDate ) ) {
simpleDetailItem = new HashMap < > ( ) ;
//组装初步的明细数据
simpleDetailItem . put ( "ccr" , ccEmpId ) ;
simpleDetailItem . put ( "cclx" , ccType ) ;
simpleDetailItem . put ( "ccrName" , ccEmpName ) ;
simpleDetailItem . put ( "cclxName" , checkItemName ) ;
simpleDetailItem . put ( "ksrq" , ccDate ) ;
simpleDetailItem . put ( "jsrq" , ccDate ) ;
simpleDetailItem . put ( "btcc" , "1" ) ;
simpleDetailList . add ( simpleDetailItem ) ;
}
}
}
return simpleDetailList ;
}
/ * *
* @param empIdList 出 差 人 员 id 集 合
* @param dateList 出 差 日 期 集 合
* @param removeNonWorkDayRange 是 否 移 除 非 工 作 日 时 长
* @param scheduleInfoMap 排 班 信 息
* @param restDayInfo 休 息 日 信 息
* @param startDate 开 始 日 期
* @param endDate 结 束 日 期
* @param startTime 开 始 时 间
* @param endTime 结 束 时 间
* @param countBdlxList 收 集 需 要 统 计 时 长 的 班 段 类 型
* @return 组 装 初 步 的 出 差 明 细 , 这 边 只 处 理 “ 每 天 同 时 段 出 差 ” 未 勾 选 , 且 出 差 方 式 为 “ 指 定 时 间 区 间 ”
* /
private List < Map < String , String > > createDetailListWithNoDaily ( List < String > empIdList , List < String > dateList , boolean removeNonWorkDayRange ,
Map < String , List < Map < String , Object > > > scheduleInfoMap , Map < String , List < String > > restDayInfo ,
String startDate , String endDate , String startTime , String endTime , List < String > countBdlxList ,
String hsdw , double hsl , String ccType , Map < String , String > empIdToName , String checkItemName ) {
List < Map < String , String > > simpleDetailList = new ArrayList < > ( ) ;
Map < String , String > simpleDetailItem ;
String sql = "" ;
List < Map < String , Object > > bcDetailData ;
String targetDateBcId = "" ;
int scMinutes = 0 ;
dateList . add ( 0 , DateUtil . beforeDay ( startDate , 1 ) ) ;
dateList . add ( DateUtil . AfterDay ( endDate , 1 ) ) ;
for ( String ccEmpId : empIdList ) {
//需要自动移除日期区间内的休息日时,去除出差日期区间中的休息日
List < Map < String , Object > > scheduleInfoList = scheduleInfoMap . getOrDefault ( ccEmpId , new ArrayList < > ( ) ) ;
Map < String , String > dateToBcxxMap = scheduleInfoList . stream ( ) . collect ( Collectors . toMap ( e - > Util . null2String ( e . get ( "bcrq" ) ) , e - > Util . null2String ( e . get ( "bcxx" ) ) ) ) ;
List < String > restDateList = new ArrayList < > ( ) ;
if ( removeNonWorkDayRange ) {
//排班结果中休息的日期
List < String > restDateListFromSchedule = scheduleInfoList . stream ( )
. filter ( f - > Util . null2String ( f . get ( "sfxx" ) ) . equals ( CheckBoxEnum . CHECKED . getKey ( ) ) )
. map ( e - > Util . null2String ( e . get ( "bcrq" ) ) )
. collect ( Collectors . toList ( ) ) ;
List < String > allDateListFromSchedule = scheduleInfoList . stream ( ) . map ( e - > Util . null2String ( e . get ( "bcrq" ) ) ) . collect ( Collectors . toList ( ) ) ;
//排班结果中未出现的日期
List < String > nonSetDateListFromSchedule = dateList . stream ( ) . filter ( f - > ! allDateListFromSchedule . contains ( f ) ) . collect ( Collectors . toList ( ) ) ;
//企业日历中人员对应日期的休息日
restDateList = restDayInfo . get ( ccEmpId ) ;
//筛选排班信息无法辨别的日期,依靠企业日历的日期信息
restDateList = restDateList . stream ( ) . filter ( nonSetDateListFromSchedule : : contains ) . collect ( Collectors . toList ( ) ) ;
restDateList . addAll ( restDateListFromSchedule ) ;
}
String ccEmpName = empIdToName . get ( ccEmpId ) ;
simpleDetailItem = new HashMap < > ( ) ;
//组装初步的出差明细数据
simpleDetailItem . put ( "ccr" , ccEmpId ) ;
simpleDetailItem . put ( "cclx" , ccType ) ;
simpleDetailItem . put ( "ccrName" , ccEmpName ) ;
simpleDetailItem . put ( "cclxName" , checkItemName ) ;
simpleDetailItem . put ( "ksrq" , startDate ) ;
simpleDetailItem . put ( "jsrq" , endDate ) ;
simpleDetailItem . put ( "kssj" , startTime ) ;
simpleDetailItem . put ( "jssj" , endTime ) ;
for ( String date : dateList ) {
targetDateBcId = restDateList . contains ( date ) ? "" : Util . null2String ( dateToBcxxMap . get ( date ) ) . split ( "-" ) [ 0 ] ;
if ( ! "" . equals ( targetDateBcId ) ) {
sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + targetDateBcId ;
bcDetailData = DbTools . getSqlToList ( sql ) ;
bcDetailData = bcDetailData . stream ( ) . filter ( e - > countBdlxList . contains ( Util . null2String ( e . get ( "bdlx" ) ) ) ) . collect ( Collectors . toList ( ) ) ;
//获取需要累计的班段时长区间和请假区间存在交集的分钟数
scMinutes = scMinutes + Utils . removeTime ( startDate + " " + startTime , endDate + " " + endTime , bcDetailData , date ) ;
}
}
//增加加班计划中的数据,加班计划明细中的数据作为“加班计划”班段类型数据的补充
if ( countBdlxList . contains ( ClassSegmentTypeEnum . OVERTIME_PLAN . getKey ( ) ) ) {
sql = "select b.jbry,b.ksrq,b.kssj,b.jblx,b.jsrq,b.jssj,b.jbsc,b.gsrq from uf_jcl_kq_jbjh a left join uf_jcl_kq_jbjh_dt1 b on a.id=b.mainid where b.jbry =? and b.ksrq>=? and b.jsrq<=? and (b.jbcx=0 or b.jbcx is null) and a.jlzt=1" ;
List < Map < String , Object > > overtimePlanList = DbTools . getSqlToList ( sql , ccEmpId , DateUtil . beforeDay ( startDate , 1 ) , DateUtil . AfterDay ( endDate , 1 ) ) ;
int scMinutesInOvertimePlan = Utils . removeTimeWithOvertimePlan ( startDate + " " + startTime , endDate + " " + endTime , overtimePlanList ) ;
scMinutes = scMinutes + scMinutesInOvertimePlan ;
}
if ( scMinutes > 0 ) {
double ccscByAccount = Utils . getItemduration ( hsl , hsdw , scMinutes , AccountingUnitEnum . MINUTES , 8.0 ) ;
//组装初步的出差时长
simpleDetailItem . put ( "ccsc" , hsdw . equals ( AccountingUnitEnum . MINUTES . getKey ( ) )
? String . format ( "%.2f" , ccscByAccount / 60.0 )
: String . valueOf ( ccscByAccount ) ) ;
simpleDetailList . add ( simpleDetailItem ) ;
}
}
return simpleDetailList ;
}
}