@ -1,7 +1,9 @@
package com.engine.jucailinkq.attendance.workflow.action.askforleave ;
import com.engine.jucailinkq.attendance.enums.AccountingUnitEnum ;
import com.engine.jucailinkq.attendance.enums.AttendanceItemTypeEnum ;
import com.engine.jucailinkq.common.util.CommonUtil ;
import com.engine.jucailinkq.common.util.DateUtil ;
import com.engine.jucailinkq.common.util.DbTools ;
import com.engine.jucailinkq.common.util.Utils ;
import com.google.common.collect.Lists ;
@ -14,6 +16,7 @@ import weaver.soa.workflow.request.RequestInfo;
import java.math.BigDecimal ;
import java.math.MathContext ;
import java.math.RoundingMode ;
import java.time.ZoneOffset ;
import java.util.* ;
import java.util.stream.Collectors ;
@ -41,28 +44,51 @@ public class BatchAskForLeaveWorkFlowSubmitAction implements Action {
log . info ( "detail2TableName : [{}]" , detail2TableName ) ;
//第一笔开始时间
String firstStartDate = detailTableData . get ( 0 ) . get ( "ksrq" ) ;
List < String > startDateList = detailTableData . stream ( ) . map ( map - > map . get ( "ksrq" ) ) . collect ( Collectors . toList ( ) ) ;
String minStartDate = startDateList . stream ( ) . min ( Comparator . comparing ( e - > DateUtil . getTime ( e ) . toInstant ( ZoneOffset . of ( "+8" ) ) . toEpochMilli ( ) ) ) . get ( ) ;
//请假人员列表
List < String > leaveEmpIdList = detailTableData . stream ( ) . map ( map - > map . get ( "qjr" ) ) . distinct ( ) . collect ( Collectors . toList ( ) ) ;
List < Map < String , Object > > detailTable2 = Lists . newArrayList ( ) ;
//请假人姓名映射
String sql ;
Map < String , String > empIdToName = new HashMap < > ( ) ;
if ( leaveEmpIdList . size ( ) > 0 ) {
sql = "select id, lastname from hrmresource where id in (" + String . join ( "," , leaveEmpIdList ) + ")" ;
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" ) ) ) ) ;
}
//获取假期类型的考勤项目
sql = "select id, mc, hsdw, zdyzsl, yxyz from uf_jcl_kq_kqxm where xmlx=?" ;
List < Map < String , Object > > holidayItemList = DbTools . getSqlToList ( sql , AttendanceItemTypeEnum . HOLIDAY . getKey ( ) ) ;
Map < String , Map < String , Object > > kqxmInfo = holidayItemList . stream ( ) . collect ( Collectors . toMap ( e - > Util . null2String ( e . get ( "id" ) ) , e - > e ) ) ;
List < Map < String , Object > > detailTable2 = Lists . newArrayList ( ) ;
Map < String , Object > holidayBalanceMap = new HashMap < > ( ) ;
//需要校验假期额度的假期类型
List < String > checkAmountJqIdList = CommonUtil . getJqInfoWithAmount ( ) ;
//根据明细表1, 根据请假类型分组, 对于需要校验余额的遍历生成明细表2
Map < String , List < Map < String , String > > > detail1TabDataGroupByJqlx = detailTableData . stream ( ) . collect ( Collectors . groupingBy ( e - > Util . null2String ( e . get ( "qjlx" ) ) ) ) ;
//收集假期类型和使用人员id的映射
Map < String , List < String > > jqlxToEmpIds = new HashMap < > ( ) ;
//收集假期类型和使用人员id的映射
Map < String , List < Map < String , Object > > > jqlxToJqye = new HashMap < > ( ) ;
//收集假期余额id和本次流程中使用的小时时长映射
Map < String , Double > jqyeIdToUseHours = new HashMap < > ( ) ;
for ( Map . Entry < String , List < Map < String , String > > > entry : detail1TabDataGroupByJqlx . entrySet ( ) ) {
if ( checkAmountJqIdList . contains ( entry . getKey ( ) ) ) {
// String sql = "select id,jqid,sxrq,ktsc,yxsc,wxsc,yqsxrq,ztsc from uf_jcl_kq_jqye where jqid=? and sxrq<=? and yqsxrq>=? order by sxrq";
// List<Map<String, Object>> holidayBalanceList = DbTools.getSqlToList(sql, entry.getKey(), firstStartDate, firstStartDate);
String sql = "select id,jqid,sxrq,ktsc,yxsc,wxsc,yqsxrq,ztsc from uf_jcl_kq_jqye where jqid=?" ;
List < Map < String , Object > > holidayBalanceList = DbTools . getSqlToList ( sql , entry . getKey ( ) ) ;
sql = "select id,jqid,sxrq,ktsc,yxsc,wxsc,yqsxrq,ztsc,ygid from uf_jcl_kq_jqye where jqid=? and sxrq <= ? order by yqsxrq, modedatacreatedate, modedatacreatetime" ;
List < Map < String , Object > > holidayBalanceList = DbTools . getSqlToList ( sql , entry . getKey ( ) , minStartDate ) ;
if ( holidayBalanceList . size ( ) > 0 ) {
holidayBalanceMap . putAll ( holidayBalanceList . stream ( ) . collect ( Collectors . toMap ( e - > e . get ( "id" ) . toString ( ) , e - > e ) ) ) ;
jqlxToJqye . put ( entry . getKey ( ) , holidayBalanceList ) ;
}
sql = "select id,mc,hsdw,hsl,jcbyxsyqjb,yxsydjb,qzsyyxjb from uf_jcl_kq_kqxm where id=?" ;
Map < String , Object > holidayItem = DbTools . getSqlToMap ( sql , entry . getKey ( ) ) ;
//假期核算单位
String hsdw = Util . null2String ( holidayItem . get ( "hsdw" ) ) ;
//遍历生成明细表2
List < String > empIds = new ArrayList < > ( ) ;
for ( Map < String , String > detailData : entry . getValue ( ) ) {
String jqyeInfoStr = Util . null2String ( detailData . get ( "jqye" ) ) ;
List < String > jqyeInfoList = Arrays . asList ( jqyeInfoStr . split ( "," ) ) ;
@ -72,16 +98,46 @@ public class BatchAskForLeaveWorkFlowSubmitAction implements Action {
detail2Map . put ( "jqye" , jqyeInfo . split ( "_" ) [ 0 ] ) ;
detail2Map . put ( "mainid" , mainTableData . get ( "id" ) ) ;
detail2Map . put ( "glrq" , detailData . get ( "ksrq" ) ) ;
if ( hsdw . equals ( AccountingUnitEnum . DAY . getKey ( ) ) ) {
detail2Map . put ( "sysc" , Utils . divide ( Double . parseDouble ( jqyeInfo . split ( "_" ) [ 1 ] ) , 8 ) ) ;
} else {
detail2Map . put ( "sysc" , jqyeInfo . split ( "_" ) [ 1 ] ) ;
}
// if (hsdw.equals(AccountingUnitEnum.DAY.getKey())) {
// detail2Map.put("sysc", Utils.divide(Double.parseDouble(jqyeInfo.split("_")[1]), 8));
// } else {
// detail2Map.put("sysc", jqyeInfo.split("_")[1]);
// }
//20241118需求变更, 时长不进行核算单位倍率转换, 按照原本核算单位进行收集和处理
detail2Map . put ( "sysc" , jqyeInfo . split ( "_" ) [ 1 ] ) ;
detailTable2 . add ( detail2Map ) ;
//累计假期余额id对应的使用小时数/天数,具体单位根据假别的核算单位
jqyeIdToUseHours . put ( jqyeInfo . split ( "_" ) [ 0 ] ,
jqyeIdToUseHours . getOrDefault ( jqyeInfo . split ( "_" ) [ 0 ] , ( double ) 0 ) + Double . parseDouble ( jqyeInfo . split ( "_" ) [ 1 ] ) ) ;
}
//收集使用该假期类型的人员id
empIds . add ( Util . null2String ( detailData . get ( "qjr" ) ) ) ;
}
jqlxToEmpIds . put ( entry . getKey ( ) , empIds ) ;
}
}
//校验假期余额使用是否满足要求,并且区分核算单位“天”和“小时”
StringBuilder jqyeCheckFailMessage = new StringBuilder ( ) ;
Map < String , String > jqyeIdToJqMc = new HashMap < > ( ) ;
Map < String , String > jqyeIdToEmpName = new HashMap < > ( ) ;
//获取本次使用的假期余额对应还可使用的假期余额小时数
List < String > errorMessage = new ArrayList < > ( ) ;
Map < String , Double > jqyeIdToCanUseHours = getJqyeCanUseHours ( jqlxToEmpIds , jqlxToJqye , errorMessage , empIdToName , kqxmInfo , jqyeIdToJqMc , jqyeIdToEmpName ) ;
for ( Map . Entry < String , Double > entry : jqyeIdToUseHours . entrySet ( ) ) {
if ( jqyeIdToCanUseHours . getOrDefault ( entry . getKey ( ) , ( double ) 0 ) < entry . getValue ( ) ) {
//记录假期余额不足信息
jqyeCheckFailMessage . append ( jqyeIdToEmpName . get ( entry . getKey ( ) ) ) . append ( "-" ) . append ( jqyeIdToJqMc . get ( entry . getKey ( ) ) ) . append ( "的假期余额不足!" ) ;
}
}
if ( errorMessage . size ( ) > 0 ) {
jqyeCheckFailMessage . append ( errorMessage ) ;
}
if ( ! "" . equals ( jqyeCheckFailMessage . toString ( ) ) ) {
log . error ( jqyeCheckFailMessage . toString ( ) ) ;
requestInfo . getRequestManager ( ) . setMessageid ( "11111" + requestid + "22222" ) ;
requestInfo . getRequestManager ( ) . setMessagecontent ( jqyeCheckFailMessage . toString ( ) ) ;
return Action . FAILURE_AND_CONTINUE ;
}
//明细表2有数据时, 更新明细表2入库, 并且更新假期余额表
//更新流程明细表2
String delteSql = "delete from " + detail2TableName + " where mainid=?" ;
@ -112,8 +168,6 @@ public class BatchAskForLeaveWorkFlowSubmitAction implements Action {
double havedztsc = Util . null2String ( map . get ( "ztsc" ) ) . equals ( "" ) ? 0 : Double . valueOf ( map . get ( "ztsc" ) . toString ( ) ) ;
double havedwxsc = Util . null2String ( map . get ( "wxsc" ) ) . equals ( "" ) ? 0 : Double . valueOf ( map . get ( "wxsc" ) . toString ( ) ) ;
// double updatedztsc = Utils.add(havedztsc, ztsc);
// double updatedwxsc = Utils.subtract(havedwxsc, ztsc);
double updatedztsc = new BigDecimal ( String . valueOf ( havedztsc ) ) . add ( new BigDecimal ( String . valueOf ( ztsc ) ) , new MathContext ( 5 , RoundingMode . HALF_UP ) ) . doubleValue ( ) ;
double updatedwxsc = new BigDecimal ( String . valueOf ( havedwxsc ) ) . subtract ( new BigDecimal ( String . valueOf ( ztsc ) ) , new MathContext ( 5 , RoundingMode . HALF_UP ) ) . doubleValue ( ) ;
@ -127,8 +181,6 @@ public class BatchAskForLeaveWorkFlowSubmitAction implements Action {
return Action . FAILURE_AND_CONTINUE ;
}
}
////////////////////////////
} catch ( Exception e ) {
log . error ( "BatchAskForLeaveWorkFlowSubmitAction error : [{}]" , e ) ;
@ -137,4 +189,116 @@ public class BatchAskForLeaveWorkFlowSubmitAction implements Action {
return Action . SUCCESS ;
}
private Map < String , Double > getJqyeCanUseHours ( Map < String , List < String > > jqlxToEmpIds , Map < String , List < Map < String , Object > > > jqlxToJqye ,
List < String > errorMessage , Map < String , String > empIdToName , Map < String , Map < String , Object > > kqxmInfo ,
Map < String , String > jqyeIdToJqMc , Map < String , String > jqyeIdToEmpName ) {
Map < String , Double > result = new HashMap < > ( ) ;
if ( jqlxToEmpIds . size ( ) = = 0 ) {
return result ;
}
//获取modeId, 假期额度规则的modeId
Map < String , String > formmodeIdMap = Utils . getFormmodeIdMap ( ) ;
String modeId = formmodeIdMap . get ( "uf_jcl_kq_jqed" ) ;
List < Map < String , Object > > jqyeInfoList ;
Map < String , Object > holidayItem = new HashMap < > ( ) ;
for ( Map . Entry < String , List < String > > entry : jqlxToEmpIds . entrySet ( ) ) {
holidayItem = kqxmInfo . get ( entry . getKey ( ) ) ;
jqyeInfoList = jqlxToJqye . get ( entry . getKey ( ) ) ;
if ( jqyeInfoList = = null | | jqyeInfoList . size ( ) = = 0 ) {
continue ;
}
jqyeInfoList = jqyeInfoList . stream ( ) . filter ( f - > entry . getValue ( ) . contains ( f . get ( "ygid" ) . toString ( ) ) ) . collect ( Collectors . toList ( ) ) ;
if ( jqyeInfoList . size ( ) = = 0 ) {
continue ;
}
//获取假期额度规则中额度可休次数、单次最小休时长、额度单位
Map < String , Object > jqedInfo = new HashMap < > ( ) ;
String sql = "select id, eddw, dczskxsc, edbxdcxw from uf_jcl_kq_jqed where jb = ? and gzzt = 0" ;
List < Map < String , Object > > jqedData = DbTools . getSqlToList ( sql , entry . getKey ( ) ) ;
//按人员分组
Map < String , List < Map < String , Object > > > empIdToJqyeInfo = jqyeInfoList . stream ( ) . collect ( Collectors . groupingBy ( map - > ( String ) map . get ( "ygid" ) ) ) ;
for ( Map . Entry < String , List < Map < String , Object > > > entry2 : empIdToJqyeInfo . entrySet ( ) ) {
List < Map < String , Object > > waitDealHolidayBalanceList = entry2 . getValue ( ) ;
//获取延期失效日期最晚的一条
Map < String , Object > maxYqsxrqMap = waitDealHolidayBalanceList . stream ( ) . reduce ( ( m1 , m2 ) - > m2 ) . orElse ( null ) ;
Integer empPriority = null ;
boolean samePriority = false ;
for ( Map < String , Object > jqedItem : jqedData ) {
String dataId = jqedItem . get ( "id" ) . toString ( ) ;
//获取假期额度规则适用的人员id列表
Map < String , Integer > empInfo = CommonUtil . getEmpIdWithPriority ( dataId , modeId ) ;
if ( empInfo . get ( entry2 . getKey ( ) ) ! = null ) {
if ( empPriority = = null ) {
jqedInfo = jqedItem ;
empPriority = empInfo . get ( entry2 . getKey ( ) ) ;
} else if ( empPriority > empInfo . get ( entry2 . getKey ( ) ) ) {
jqedInfo = jqedItem ;
empPriority = empInfo . get ( entry2 . getKey ( ) ) ;
} else if ( empPriority . equals ( empInfo . get ( entry2 . getKey ( ) ) ) ) {
samePriority = true ;
}
}
}
if ( empPriority ! = null & & samePriority ) {
String message = empIdToName . get ( entry2 . getKey ( ) ) ;
message = message + "可使用的假别—‘" + holidayItem . get ( "mc" ) + "’同一优先级情况下存在超过一种适用的假期额度规则,无法确定唯一规则!" ;
errorMessage . add ( message ) ;
continue ;
}
//假期的核算单位, 0-天、1-小时
String hsdw = Util . null2String ( holidayItem . get ( "hsdw" ) ) ;
//假期额度的额度单位, 0-天、1-小时
String eddw = Util . null2String ( jqedInfo . get ( "eddw" ) ) ;
//额度可修次数
String allowLeaveNumStr = Util . null2String ( jqedInfo . get ( "edbxdcxw" ) ) ;
if ( ! "" . equals ( allowLeaveNumStr ) & & waitDealHolidayBalanceList . size ( ) > 0 ) {
//查询请假记录中, 人员id+假期类别id情况下的结果, 遍历每条主表数据下的明细数据中使用了哪些假期余额id
sql = "select a.id,dt2.jqye from uf_jcl_kq_qjjl a left join uf_jcl_kq_qjjl_dt1 dt1 on dt1.mainid = a.id left join uf_jcl_kq_qjjl_dt2 dt2 on dt2.glmxid = dt1.glmxid " +
"where a.jqlx = " + entry . getKey ( ) + " and qjry = " + entry2 . getKey ( ) + " and a.cxqj = 0 and dt1.cxqj = 0 and a.jlzt in (0, 1) and dt1.glmxid is not null" ;
List < Map < String , Object > > leaveList = DbTools . getSqlToList ( sql ) ;
Map < String , Integer > jqyeUseNumInfo = new HashMap < > ( ) ;
List < String > leaveUseList = new ArrayList < > ( ) ;
Integer useNum ;
for ( Map < String , Object > leaveItem : leaveList ) {
String jqyeId = Util . null2String ( leaveItem . get ( "jqye" ) ) ;
if ( ! "" . equals ( jqyeId ) ) {
String leaveInfo = leaveItem . get ( "id" ) . toString ( ) + "_" + jqyeId ;
if ( leaveUseList . size ( ) = = 0 ) {
leaveUseList . add ( leaveInfo ) ;
jqyeUseNumInfo . put ( jqyeId , 1 ) ;
} else if ( ! leaveUseList . contains ( leaveInfo ) ) {
leaveUseList . add ( leaveInfo ) ;
useNum = jqyeUseNumInfo . get ( jqyeId ) ;
jqyeUseNumInfo . put ( jqyeId , useNum = = null ? 1 : + + useNum ) ;
}
}
}
//筛选次数未使用完的假期余额
waitDealHolidayBalanceList = waitDealHolidayBalanceList . stream ( ) . filter ( f - > {
int beforeUseNum = jqyeUseNumInfo . get ( f . get ( "id" ) . toString ( ) ) = = null ? 0 : jqyeUseNumInfo . get ( f . get ( "id" ) . toString ( ) ) ;
return Integer . parseInt ( allowLeaveNumStr ) > beforeUseNum ;
} ) . collect ( Collectors . toList ( ) ) ;
}
//判断是否可预支
String allowAdvance = Util . null2String ( holidayItem . get ( "yxyz" ) ) ;
String advanceSc = Util . null2String ( holidayItem . get ( "zdyzsl" ) ) ;
//遍历可使用的假期余额
for ( Map < String , Object > holidayBalance : waitDealHolidayBalanceList ) {
String jqyeId = Util . null2String ( holidayBalance . get ( "id" ) ) ;
double wxsc = Utils . convertDouble ( holidayBalance . get ( "wxsc" ) ) ;
//如果该条假期余额可以预支,则在原有未休时长基础上增加预支时长
if ( "1" . equals ( allowAdvance ) & & maxYqsxrqMap ! = null & & Util . null2String ( maxYqsxrqMap . get ( "id" ) ) . equals ( jqyeId ) ) {
wxsc = wxsc + Utils . convertDouble ( advanceSc ) ;
}
result . put ( jqyeId , wxsc ) ;
jqyeIdToJqMc . put ( jqyeId , holidayItem . get ( "mc" ) . toString ( ) ) ;
jqyeIdToEmpName . put ( jqyeId , empIdToName . get ( entry2 . getKey ( ) ) ) ;
}
}
}
return result ;
}
}