考勤-批量请假,明细表1数据生成按钮接口、批量请假流程节点action开发

zm_dev
sy 10 months ago
parent 94a0df2a17
commit eb6d761f4e

@ -0,0 +1,90 @@
package com.engine.attendance.workflow.action.askforleave;
import com.engine.common.util.CommonUtil;
import com.engine.common.util.DbTools;
import com.engine.common.util.Utils;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author: sy
* @Description: -
* @Date: 2024/6/28
**/
@Slf4j
public class BatchAskForLeaveWorkFlowArchivingAction implements Action {
@Override
public String execute(RequestInfo requestInfo) {
// 流程表单主表数据
HashMap<String,String> mainTableData = CommonUtil.getMainTableInfo(requestInfo);
log.debug("mainTableData : [{}]",mainTableData);
// 流程表单明细表1数据
List<Map<String, String>> detailTableData = CommonUtil.getDetailTableInfo(requestInfo,0);
log.debug("detailTableData : [{}]",detailTableData);
//流程表单明细表2数据
List<Map<String, String>> detailTable2 = CommonUtil.getDetailTableInfo(requestInfo,1);
log.debug("detailTableData : [{}]",detailTable2);
//第一笔开始时间
String firstStartDate = detailTableData.get(0).get("ksrq");
String sql = "select id,jqid,sxrq,ktsc,yxsc,wxsc,yqsxrq,ztsc from uf_jcl_kq_jqye where and sxrq<=? and yqsxrq>=? order by sxrq";
List<Map<String,Object>> holidayBalanceList = DbTools.getSqlToList(sql,firstStartDate,firstStartDate);
Map<String,Object> holidayBalanceMap = holidayBalanceList.stream().collect(Collectors.toMap(e->e.get("id").toString(), e->e));
try {
if (detailTable2.size() > 0) {
Map<String,Object> balanceMap = Maps.newHashMap();
for (Map<String, String> data : detailTable2){
String jqye = Util.null2String(data.get("jqye"));
double sysc = Double.valueOf(data.get("sysc").toString());
double havedSysc= balanceMap.get(jqye) ==null?0:Double.valueOf(balanceMap.get(jqye).toString());
sysc = Utils.add(sysc,havedSysc);
balanceMap.put(jqye,sysc);
}
for (Map.Entry<String,Object> entry:balanceMap.entrySet()){
String id = entry.getKey();
double ztsc = Double.valueOf(entry.getValue().toString());
Map<String,Object> map = (Map<String,Object>)holidayBalanceMap.get(id);
double havedztsc = Util.null2String(map.get("ztsc")).equals("") ? 0 : Double.valueOf(map.get("ztsc").toString());
double havedyxsc = Util.null2String(map.get("yxsc")).equals("") ? 0 : Double.valueOf(map.get("yxsc").toString());
double updatedztsc = Utils.subtract(havedztsc,ztsc);
double updatedwxsc = Utils.add(havedyxsc,ztsc);
String updateSql = "update uf_jcl_kq_jqye set yxsc=?,ztsc=? where id=?";
if (!DbTools.update(updateSql,updatedwxsc,updatedztsc,id)){
//更新假期余额失败
String message = "更新假期余额失败";
log.error(message);
requestInfo.getRequestManager().setMessageid("11111" + requestInfo.getRequestid() + "22222");
requestInfo.getRequestManager().setMessagecontent(message);
return Action.FAILURE_AND_CONTINUE;
}
}
}
}catch (Exception e){
log.error("AskForLeaveWorkFlowSubmitAction error : [{}]",e);
return Action.FAILURE_AND_CONTINUE;
}
return Action.SUCCESS;
}
}

@ -0,0 +1,134 @@
package com.engine.attendance.workflow.action.askforleave;
import com.engine.attendance.enums.AccountingUnitEnum;
import com.engine.attendance.enums.CheckBoxEnum;
import com.engine.attendance.workflow.enums.AskAndEvctionWayEnum;
import com.engine.common.util.CommonUtil;
import com.engine.common.util.DateUtil;
import com.engine.common.util.DbTools;
import com.engine.common.util.Utils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Author: sy
* @Description: -
* @Date: 2024/6/28
**/
@Slf4j
public class BatchAskForLeaveWorkFlowSubmitAction implements Action {
@Override
public String execute(RequestInfo requestInfo) {
String requestid = requestInfo.getRequestid();
try {
// 流程表单主表数据
HashMap<String, String> mainTableData = CommonUtil.getMainTableInfo(requestInfo);
log.info("mainTableData : [{}]", mainTableData);
// 流程表单明细表1数据
List<Map<String, String>> detailTableData = CommonUtil.getDetailTableInfo(requestInfo, 0);
log.info("detailTableData : [{}]", detailTableData);
String detail2TableName = requestInfo.getDetailTableInfo().getDetailTable()[1].getTableDBName();
log.info("detail2TableName : [{}]", detail2TableName);
//第一笔开始时间
String firstStartDate = detailTableData.get(0).get("ksrq");
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("jqlx"))));
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);
if (holidayBalanceList.size() > 0) {
holidayBalanceMap.putAll(holidayBalanceList.stream().collect(Collectors.toMap(e -> e.get("id").toString(), e -> e)));
}
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
for (Map<String, String> detailData : entry.getValue()) {
String jqyeInfoStr = Util.null2String(detailData.get("id"));
List<String> jqyeInfoList = Arrays.asList(jqyeInfoStr.split(","));
for (String jqyeInfo : jqyeInfoList) {
Map<String, Object> detail2Map = Maps.newHashMap();
detail2Map.put("glmxid", detailData.get("id"));
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]);
}
detailTable2.add(detail2Map);
}
}
}
}
//明细表2有数据时更新明细表2入库并且更新假期余额表
//更新流程明细表2
String delteSql = "delete from " + detail2TableName + " where mainid=?";
DbTools.update(delteSql, requestid);
if (detailTable2.size() > 0 && !CommonUtil.insertBatch(detailTable2, detail2TableName)) {
//更新流程明细表2失败
String message = "更新流程明细表2失败";
log.error(message);
requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
requestInfo.getRequestManager().setMessagecontent(message);
return Action.FAILURE_AND_CONTINUE;
}
//更新假期余额在途时长
Map<String, Object> balanceMap = Maps.newHashMap();
for (Map<String, Object> data : detailTable2) {
String jqye = Util.null2String(data.get("jqye"));
double sysc = Double.valueOf(data.get("sysc").toString());
double havedSysc = balanceMap.get(jqye) == null ? 0 : Double.valueOf(balanceMap.get(jqye).toString());
sysc = Utils.add(sysc, havedSysc);
balanceMap.put(jqye, sysc);
}
log.info("balanceMap : [{}]",balanceMap);
for (Map.Entry<String, Object> entry : balanceMap.entrySet()) {
String id = entry.getKey();
double ztsc = Double.valueOf(entry.getValue().toString());
Map<String, Object> map = (Map<String, Object>) holidayBalanceMap.get(id);
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);
String updateSql = "update uf_jcl_kq_jqye set wxsc=?,ztsc=? where id=?";
if (!DbTools.update(updateSql, havedwxsc, updatedztsc, id)) {
//更新假期余额失败
String message = "更新假期余额失败";
log.error(message);
requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
requestInfo.getRequestManager().setMessagecontent(message);
return Action.FAILURE_AND_CONTINUE;
}
}
////////////////////////////
}catch (Exception e){
log.error("AskForLeaveWorkFlowSubmitAction error : [{}]",e);
return Action.FAILURE_AND_CONTINUE;
}
return Action.SUCCESS;
}
}

@ -1,5 +1,6 @@
package com.engine.attendance.workflow.service;
import java.text.ParseException;
import java.util.Map;
public interface AskForLeaveService {
@ -13,4 +14,11 @@ public interface AskForLeaveService {
* @return
*/
Map<String, Object> getRestDayInterval(Map<String, Object> params);
/**
* -
* @param params
*/
Map<String, Object> generateLeaveInfoList(Map<String, Object> params) throws ParseException;
}

@ -1,28 +1,33 @@
package com.engine.attendance.workflow.service.impl;
import com.engine.attendance.component.persongroup.service.SchedulingResultsService;
import com.engine.attendance.component.persongroup.service.impl.SchedulingResultsServiceImpl;
import com.engine.attendance.enums.AccountingUnitEnum;
import com.engine.attendance.enums.CheckBoxEnum;
import com.engine.attendance.enums.DateTypeEnum;
import com.engine.attendance.workflow.cmd.GetAskForLeaveRecordListCmd;
import com.engine.attendance.workflow.cmd.GetKqCycleTimeIntervalCmd;
import com.engine.attendance.workflow.cmd.GetRestDayIntervalCmd;
import com.engine.attendance.workflow.enums.AskAndEvctionWayEnum;
import com.engine.attendance.workflow.service.AskForLeaveService;
import com.engine.attendance.workflow.service.MakeUpClockInService;
import com.engine.common.exception.AttendanceRunTimeException;
import com.engine.common.util.DateUtil;
import com.engine.common.util.DbTools;
import com.engine.common.util.*;
import com.engine.core.impl.Service;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;
import java.text.ParseException;
import java.time.ZoneOffset;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class AskForLeaveServiceImpl extends Service implements AskForLeaveService {
private SchedulingResultsService schedulingResultsService = ServiceUtil.getService(SchedulingResultsServiceImpl.class);
private MakeUpClockInService makeUpClockInService = ServiceUtil.getService(MakeUpClockInServiceImpl.class);
@Override
public Map<String, Object> getUesdHolidayItem(Map<String, Object> params) {
@ -128,4 +133,602 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic
}
return commandExecutor.execute(new GetRestDayIntervalCmd(params,user));
}
/**
* -
* @param params
* @return
*/
@Override
public Map<String, Object> generateLeaveInfoList(Map<String, Object> params) throws ParseException {
Map<String,Object> resultMap = Maps.newHashMap();
List<String> errorMessage = new ArrayList<>();
// 流程表单主表数据
Map<String,String> mainTableData = (Map<String,String>)params.get("mainTableData");
// 流程表单明细表1数据
List<Map<String, String>> detailTableData = (List<Map<String, String>>)params.get("detailTableData");
//需要校验假期额度的假期类型
List<String> checkAmountJqIdList = CommonUtil.getJqInfoWithAmount();
//已编辑内容中的假期额度使用信息
Map<String, Double> editedUseJqed = new HashMap<>();
//已编辑内容中的假期类型使用时长_人员信息
Map<String, Double> editedUseJqlxWithEmp = new HashMap<>();
//假期余额时长已用完的假期余额id
List<String> unableUseJqyeIdList = new ArrayList<>();
//记录已编辑的请假记录,<人员id-请假类型-日期, 请假时长>
Map<String, String> editedLeaveInfo = new HashMap<>();
//处理明细表1数据生成之前编辑内容中已使用的假期额度信息
if (detailTableData != null && detailTableData.size() > 0){
for (Map<String, String> detailItem : detailTableData) {
double detailSc = "".equals(Util.null2String(detailItem.get("qjsc"))) ? 0 : Double.parseDouble(Util.null2String(detailItem.get("qjsc")));
String leaveType = Util.null2String(detailItem.get("qjlx"));
String empId = Util.null2String(detailItem.get("qjr"));
editedUseJqlxWithEmp.merge(leaveType + "_" + empId, detailSc, Double::sum);
String jqye = Util.null2String(detailItem.get("jqye"));
if ("".equals(jqye)) {
continue;
} else if (jqye.contains(",")) {
List<String> jqyeIds = Arrays.asList(jqye.split(","));
for (int i = 0; i < jqyeIds.size(); i++ ) {
//假期余额id会用下划线“_”拼接上该假期余额记录被使用的时长
String jqyeIdStr = jqyeIds.get(i);
String[] jqyeInfo = jqyeIdStr.split("_");
String jqyeId = jqyeInfo[0];
double qjsc = Double.parseDouble(jqyeInfo[1]);
editedUseJqed.merge(jqyeId, qjsc, Double::sum);
//最后一个id前的jqye的id都属于额度已使用完的记录到已用完假期余额id集合中
if (i < jqyeIds.size() - 1) {
unableUseJqyeIdList.add(jqyeId);
}
}
} else {
String[] jqyeInfo = jqye.split("_");
String jqyeId = jqyeInfo[0];
double qjsc = Double.parseDouble(jqyeInfo[1]);
editedUseJqed.merge(jqyeId, qjsc, Double::sum);
}
}
editedLeaveInfo = detailTableData.stream()
.collect(Collectors.toMap(e-> Util.null2String(e.get("qjr")) + "_" + Util.null2String(e.get("qjlx")) + "_" + Util.null2String(e.get("ksrq")),
e->Util.null2String(e.get("qjsc"))));
}
//处理主表数据
String qjr = Util.null2String(mainTableData.get("qjr"));
//请假人姓名映射
Map<String, String> empIdToName = new HashMap<>();
//请假人员列表
List<String> leaveEmpIdList = new ArrayList<>();
if (!"".equals(qjr)) {
leaveEmpIdList = Arrays.asList(qjr.split(","));
String sql = "select id, lastname from hrmresource where id in (" + qjr + ")";
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 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 leaveMode = Util.null2String(mainTableData.get("cxjqj"));
String leaveType = Util.null2String(mainTableData.get("jqlx"));
String leaveDuration = Util.null2String(mainTableData.get("qjsc"));
//获取填写的请假类型关联的考勤项目
String sql = "select id,mc,hsdw,hsl,jcbyxsyqjb,yxsydjb,qzsyyxjb,zdycbcndfgzsd,zdycrqqjndxxb from uf_jcl_kq_kqxm where id=?";
Map<String,Object> holidayItem = DbTools.getSqlToMap(sql,leaveType);
//判断是否需要自动移除时间区间内的非工作时长、自动移除日期区间内的休息日
boolean removeNonWorkTimeRange = "1".equals(Util.null2String(holidayItem.get("zdycbcndfgzsd")));
boolean removeNonWorkDayRange = "1".equals(Util.null2String(holidayItem.get("zdycrqqjndxxb")));
//判断考勤项目是否需要强制使用“优先使用项目”
boolean useFirstItemSign = CheckBoxEnum.CHECKED.getKey().equals(holidayItem.get("qzsyyxjb")) && CheckBoxEnum.CHECKED.getKey().equals(holidayItem.get("jcbyxsyqjb"));
Map<String,Object> holidayPriorityItem = useFirstItemSign ? DbTools.getSqlToMap(sql,holidayItem.get("yxsydjb")) : null;
//遍历人员、日期,生成人员+日期+请假时长的请假信息
//获取请假日期集合
List<String> leaveDateList = DateUtil.getDatesBetween(startDate, endDate);
//请假人的请假区间内每一天的日期类型信息
Map<String, List<String>> restDayInfo = removeNonWorkDayRange ? getRestDayWithEmpId(leaveEmpIdList, leaveType, startDate, endDate) : null;
//请假人的请假区间内的排班结果
Map<String, List<Map<String, Object>>> scheduleInfoMap = (removeNonWorkDayRange || removeNonWorkTimeRange) ? getScheduleInfoWithEmpId(leaveEmpIdList, startDate, endDate) : null;
//实际需要请假的日期集合
List<String> realLeaveDateList;
//收集未关联假期余额的请假明细数据
List<Map<String, String>> simpleLeaveDetailList = new ArrayList<>();
//收集已关联假期余额的请假明细数据
List<Map<String, String>> completeLeaveDetailList = new ArrayList<>();
Map<String, String> simpleLeaveDetailItem;
for (String leaveEmpId : leaveEmpIdList) {
//需要自动移除日期区间内的休息日时,去除请假日期区间中的休息日
List<Map<String, Object>> scheduleInfoList = new ArrayList<>();
Map<String, String> dateToBcxxMap = new HashMap<>();
if (removeNonWorkDayRange || removeNonWorkTimeRange) {
scheduleInfoList = scheduleInfoMap.get(leaveEmpId);
dateToBcxxMap = scheduleInfoList.stream().collect(Collectors.toMap(e->Util.null2String(e.get("bcrq")),e->Util.null2String(e.get("bcxx"))));
}
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 = leaveDateList.stream().filter(f -> !allDateListFromSchedule.contains(f)).collect(Collectors.toList());
//企业日历中人员对应日期的休息日
List<String> restDateList = restDayInfo.get(leaveEmpId);
//筛选排班信息无法辨别的日期,依靠企业日历的日期信息
restDateList = restDateList.stream().filter(nonSetDateListFromSchedule::contains).collect(Collectors.toList());
List<String> finalRestDateList = restDateList;
realLeaveDateList = leaveDateList.stream().filter(f -> !finalRestDateList.contains(f) && !restDateListFromSchedule.contains(f)).collect(Collectors.toList());
} else {
realLeaveDateList = leaveDateList;
}
for (String leaveDate : realLeaveDateList) {
//请假方式为“指定时间区间”时
if (leaveMode.equals(AskAndEvctionWayEnum.TIME_INTERVAL.getKey())) {
simpleLeaveDetailItem = new HashMap<>();
//组装初步的请假明细数据
simpleLeaveDetailItem.put("qjr", leaveEmpId);
simpleLeaveDetailItem.put("ksrq", leaveDate);
simpleLeaveDetailItem.put("jsrq", leaveDate);
simpleLeaveDetailItem.put("kssj", startTime);
simpleLeaveDetailItem.put("jssj", endTime);
//获取班次id
String bcId = Util.null2String(dateToBcxxMap.get(leaveDate)).split("-")[0];
//需要自动移除时间区间内的非工作时长,且请假方式为“指定时间区间”时,去除当前明细中开始时间、结束时间之间的非工作时长
if (removeNonWorkTimeRange && !"".equals(bcId)) {
//查询班次明细
sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + bcId;
List<Map<String, Object>> bcDetailData = DbTools.getSqlToList(sql);
//获取移除后的分钟数
int scMinutes = Utils.removeRestTime(leaveDate + " " + startTime, leaveDate + " " + endTime, bcDetailData, leaveDate);
//组装初步的请假时长
simpleLeaveDetailItem.put("qjsc", String.format("%.2f", scMinutes / 60.0));
} else {
//组装初步的请假时长
simpleLeaveDetailItem.put("qjsc", leaveDuration);
}
simpleLeaveDetailList.add(simpleLeaveDetailItem);
} else if (leaveMode.equals(AskAndEvctionWayEnum.HOUR.getKey())) {
simpleLeaveDetailItem = new HashMap<>();
//组装初步的请假明细数据
simpleLeaveDetailItem.put("qjr", leaveEmpId);
simpleLeaveDetailItem.put("ksrq", leaveDate);
simpleLeaveDetailItem.put("jsrq", leaveDate);
simpleLeaveDetailItem.put("qjsc", leaveDuration);
simpleLeaveDetailList.add(simpleLeaveDetailItem);
} else if (leaveMode.equals(AskAndEvctionWayEnum.ALLDAY.getKey())) {
simpleLeaveDetailItem = new HashMap<>();
//组装初步的请假明细数据
simpleLeaveDetailItem.put("qjr", leaveEmpId);
simpleLeaveDetailItem.put("ksrq", leaveDate);
simpleLeaveDetailItem.put("jsrq", leaveDate);
simpleLeaveDetailItem.put("qtj", "1");
simpleLeaveDetailList.add(simpleLeaveDetailItem);
} else if (leaveMode.equals(AskAndEvctionWayEnum.HALFDAY.getKey())) {
simpleLeaveDetailItem = new HashMap<>();
//组装初步的请假明细数据
simpleLeaveDetailItem.put("qjr", leaveEmpId);
simpleLeaveDetailItem.put("ksrq", leaveDate);
simpleLeaveDetailItem.put("jsrq", leaveDate);
simpleLeaveDetailItem.put("btj", "1");
simpleLeaveDetailList.add(simpleLeaveDetailItem);
}
}
}
//按照人员id分组处理请假明细信息关联假期余额数据
Map<String, List<Map<String, String>>> leaveDetailGroupByEmp = simpleLeaveDetailList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("qjr"))));
for(Map.Entry<String,List<Map<String,String>>> entry : leaveDetailGroupByEmp.entrySet()) {
//校验该人员的考勤周期是否正常
boolean kqCycleAllow = kqCycleCheck(entry.getKey(), entry.getValue(), errorMessage, empIdToName.get(entry.getKey()));
if (!kqCycleAllow) {
continue;
}
//1-收集使用勾选的关联的可使用的余额才能够生成请假明细可使用的条件为a-满足最小使用时长b-满足使用次数上限c-存在未休时长
List<Map<String, Object>> canUseCheckJqyeInfo = collectUsableHolidayBalance(unableUseJqyeIdList, editedUseJqed, leaveType, startDate, entry.getKey());
List<Map<String,String>> detailListItem = new ArrayList<>();
//判断考勤项目是否需要强制使用“优先使用项目”
if (useFirstItemSign) {
//2-收集优先使用的项目关联的可使用的余额才能够生成请假明细可使用的条件为a-满足最小使用时长b-满足使用次数上限c-存在未休时长
List<Map<String, Object>> canUseFirstJqyeInfo = collectUsableHolidayBalance(unableUseJqyeIdList, editedUseJqed, holidayPriorityItem.get("id").toString(), startDate, entry.getKey());
detailListItem = matchHolidayBalance(editedLeaveInfo, checkAmountJqIdList, errorMessage, entry.getKey(), empIdToName.get(entry.getKey()), canUseCheckJqyeInfo, canUseFirstJqyeInfo, editedUseJqed, editedUseJqlxWithEmp, entry.getValue(), leaveType, holidayPriorityItem.get("id").toString());
} else {
detailListItem = matchHolidayBalance(editedLeaveInfo, checkAmountJqIdList, errorMessage, entry.getKey(), empIdToName.get(entry.getKey()), canUseCheckJqyeInfo, null, editedUseJqed, editedUseJqlxWithEmp, entry.getValue(), leaveType, null);
}
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);
}
return resultMap;
}
private boolean kqCycleCheck(String qjry, List<Map<String, String>> detailTableData, List<String> errorMessage, String empName) {
/**
*
*/
Map<String, Object> params = Maps.newHashMap();
params.put("userId",qjry);
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");
List<Map<String,Object>> dateList = (List<Map<String,Object>>)dataMap.get("dataList");
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;
}
private List<Map<String, String>> matchHolidayBalance(Map<String, String> editedLeaveInfo, List<String> checkAmountJqIdList, List<String> errorMessage, String empId, String empName,
List<Map<String, Object>> canUseCheckJqyeInfo, List<Map<String, Object>> canUseFirstJqyeInfo, Map<String, Double> editedUseJqed,
Map<String, Double> editedUseJqlxWithEmp,List<Map<String, String>> leaveDetailList, String checkItemId, String firstItemId) {
List<Map<String, String>> result = new ArrayList<>();
//记录分配假期余额的结果
boolean matchResultSign = true;
//此次遍历请假总时长
double totalLeaveDuration = 0;
for (Map<String, String> detailData : leaveDetailList) {
String qtj = Util.null2String(detailData.get("qtj"));
String btj = Util.null2String(detailData.get("btj"));
//请假时间
double leaveDuration = 0;
if (qtj.equals(CheckBoxEnum.CHECKED.getKey())) {
//全天默认8小时
leaveDuration = 8;
} else if (btj.equals(CheckBoxEnum.CHECKED.getKey())) {
//半天默认4小时
leaveDuration = 4;
} else{
leaveDuration = Double.parseDouble(Util.null2String(detailData.get("qjsc")));
}
totalLeaveDuration = totalLeaveDuration + leaveDuration;
}
//减去编辑已使用时长
Double checkItemEditedUseSc = editedUseJqlxWithEmp.get(checkItemId + "_" + empId);
Double firstItemEditedUseSc = editedUseJqlxWithEmp.get(firstItemId + "_" + empId);
totalLeaveDuration = Utils.subtract(totalLeaveDuration, checkItemEditedUseSc == null ? 0 : checkItemEditedUseSc);
totalLeaveDuration = Utils.subtract(totalLeaveDuration, firstItemEditedUseSc == null ? 0 : firstItemEditedUseSc);
//如果总时长为0则退出
if (totalLeaveDuration <= 0) {
return result;
}
Map<String, Double> leaveDurationMap = new HashMap<>();
leaveDurationMap.put("totalLeaveDuration", totalLeaveDuration);
//默认存在优先使用项目时长
boolean firstItemHaveDuration = true;
//优先使用的假期类型项目是否不需要校验假期余额的额度
boolean firstItemNonCheck = firstItemId != null && !checkAmountJqIdList.contains(firstItemId);
//勾选的假期类型项目是否不需要校验假期余额的额度
boolean checkItemNonCheck = !checkAmountJqIdList.contains(checkItemId);
//遍历关联请假余额id和假期类型id
for (Map<String, String> detailData : leaveDetailList) {
String ksrq = Util.null2String(detailData.get("ksrq"));
String qtj = Util.null2String(detailData.get("qtj"));
String btj = Util.null2String(detailData.get("btj"));
//请假时间
double leaveDuration = 0;
if (qtj.equals(CheckBoxEnum.CHECKED.getKey())) {
//全天默认8小时
leaveDuration = 8;
} else if (btj.equals(CheckBoxEnum.CHECKED.getKey())) {
//半天默认4小时
leaveDuration = 4;
} else{
leaveDuration = Double.parseDouble(Util.null2String(detailData.get("qjsc")));
}
log.info("leaveDuration : [{}]", leaveDuration);
//优先使用的的请假项目是否已被编辑
double firstItemEditedDetailSc = editedLeaveInfo.get(empId + "_" + firstItemId + "_" + ksrq) == null ? 0 : Double.parseDouble(editedLeaveInfo.get(empId + "_" + firstItemId + "_" + ksrq));
boolean firstItemEditedDetail = editedLeaveInfo.get(empId + "_" + firstItemId + "_" + ksrq) != null;
//勾选的请假项目是否已被编辑
double checkItemEditedDetailSc = editedLeaveInfo.get(empId + "_" + checkItemId + "_" + ksrq) == null ? 0 : Double.parseDouble(editedLeaveInfo.get(empId + "_" + checkItemId + "_" + ksrq));
boolean checkItemEditedDetail = editedLeaveInfo.get(empId + "_" + checkItemId + "_" + ksrq) != null || (firstItemEditedDetail && firstItemEditedDetailSc - leaveDuration >= 0);
if (checkItemEditedDetail) {
leaveDuration = Utils.subtract(leaveDuration, firstItemEditedDetailSc);
leaveDuration = Utils.subtract(leaveDuration, checkItemEditedDetailSc);
if (leaveDuration <= 0) {
continue;
}
}
//存在优先使用假期类型时,且该假期类型不需要进行额度校验
if (firstItemNonCheck && !firstItemEditedDetail) {
detailData.put("qjlx", firstItemId);
detailData.put("qjsc", String.valueOf(leaveDuration));
result.add(detailData);
continue;
}
//不存在优先使用假期类型时,勾选的假期类型不需要进行额度校验
if (firstItemId == null && checkItemNonCheck && !checkItemEditedDetail) {
detailData.put("qjlx", checkItemId);
detailData.put("qjsc", String.valueOf(leaveDuration));
result.add(detailData);
continue;
}
leaveDurationMap.put("leaveDuration", leaveDuration);
//存在优先使用假期类型时,但是需要进行额度校验
if (canUseFirstJqyeInfo != null && canUseFirstJqyeInfo.size() > 0 && firstItemHaveDuration && !firstItemEditedDetail) {
dealLeaveDetailWithJqyeInfo(detailData, canUseFirstJqyeInfo, editedUseJqed, leaveDurationMap, ksrq, firstItemId, result);
if (leaveDurationMap.get("leaveDuration") == 0) {
//如果同假期类型出现多假期余额拼接配置一条请假明细时,请假明细的时长需要重新设置下
//请假明细初始要求时长已配置完成则赋值为初始请假时长,否则为初始时长-剩余未配置时长
if (Util.null2String(detailData.get("jqye")).contains(",")) {
detailData.put("qjsc", String.valueOf(leaveDuration));
}
continue;
} else {
firstItemHaveDuration = false;
if (Util.null2String(detailData.get("jqye")).contains(",")) {
detailData.put("qjsc", String.valueOf(leaveDuration - leaveDurationMap.get("leaveDuration")));
}
}
}
if (!"".equals(Util.null2String(detailData.get("qjlx")))) {
result.add(new HashMap<>(detailData));
detailData.remove("qjlx");
detailData.remove("qjsc");
detailData.remove("jqye");
}
//不存在优先使用假期类型,或者优先使用假期类型关联的假期余额用完时
//勾选的假期类型不需要进行额度校验
if (checkItemNonCheck && !checkItemEditedDetail) {
detailData.put("qjlx", checkItemId);
detailData.put("qjsc", String.valueOf(leaveDurationMap.get("leaveDuration")));
result.add(detailData);
continue;
}
//勾选的假期类型需要进行额度校验
if (!checkItemEditedDetail) {
dealLeaveDetailWithJqyeInfo(detailData, canUseCheckJqyeInfo, editedUseJqed, leaveDurationMap, ksrq, checkItemId, result);
}
if (leaveDurationMap.get("leaveDuration") > 0) {
//假期余额不足
String message = empName + "假期余额不足!";
errorMessage.add(message);
matchResultSign = false;
break;
}
}
return matchResultSign ? result : new ArrayList<>();
}
private void dealLeaveDetailWithJqyeInfo(Map<String, String> detailData, List<Map<String, Object>> canUseJqyeInfo,
Map<String, Double> editedUseJqed, Map<String, Double> leaveDurationMap,
String ksrq, String itemId, List<Map<String, String>> result) {
double totalLeaveDuration = leaveDurationMap.get("totalLeaveDuration");
double leaveDuration = leaveDurationMap.get("leaveDuration");
//假期类型相关的假期余额记录
List<Map<String, Object>> holidayBalancefilterList = Lists.newArrayList();
for (Map<String, Object> map : canUseJqyeInfo){
if (DateUtil.getTime(map.get("yqsxrq").toString()).compareTo(DateUtil.getTime(ksrq)) >= 0){
holidayBalancefilterList.add(map);
}
}
//使用的假期类型的额度单位
String eddw = Util.null2String(holidayBalancefilterList.get(0).get("eddw"));
int multipleNum = eddw.equals(AccountingUnitEnum.DAY.getKey()) ? 8 : 1;
for (Map<String, Object> holidayBalance : holidayBalancefilterList) {
//1-如果已编辑的请假明细中已有该假期余额id的记录则满足最小使用时长
boolean minLeaveDurationSign = editedUseJqed.get(holidayBalance.get("id").toString()) != null;
//2-如果编辑记录中不存在,则需要判断是否满足最小使用时长
if (!minLeaveDurationSign) {
String minLeaveDuration = Util.null2String(holidayBalance.get("minLeaveDuration"));
minLeaveDurationSign = "".equals(minLeaveDuration) || totalLeaveDuration > Double.parseDouble(minLeaveDuration);
}
//不满足最小使用时长,直接执行下一条
if (!minLeaveDurationSign) {
continue;
}
//额定未休时长
double wxsc = Util.null2String(holidayBalance.get("wxsc")).equals("") ? 0 : Double.valueOf(holidayBalance.get("wxsc").toString());
wxsc = multipleNum * wxsc;
if (leaveDuration > 0 && wxsc > 0) {
detailData.put("qjlx", itemId);
String jqyeId = Util.null2String(detailData.get("jqye"));
if (leaveDuration > wxsc) {
detailData.put("qjsc", String.valueOf(wxsc));
leaveDuration = Utils.subtract(leaveDuration, wxsc);
totalLeaveDuration = Utils.subtract(totalLeaveDuration, wxsc);
if ("".equals(jqyeId)) {
detailData.put("jqye", holidayBalance.get("id").toString() + "_" + wxsc);
} else {
//同一假期类型当一条假期余额记录不足请假时长需求时需要拼接上另一条假期余额记录的id
detailData.put("jqye", jqyeId + "," + holidayBalance.get("id").toString() + "_" + wxsc);
}
wxsc = 0;
} else {
detailData.put("qjsc", String.valueOf(leaveDuration));
wxsc = Utils.subtract(wxsc, leaveDuration);
//可能存在倍数转换
wxsc = Utils.divide(wxsc, multipleNum);
totalLeaveDuration = Utils.subtract(totalLeaveDuration, leaveDuration);
if ("".equals(jqyeId)) {
detailData.put("jqye", holidayBalance.get("id").toString() + "_" + leaveDuration);
} else {
//同一假期类型当一条假期余额记录不足请假时长需求时需要拼接上另一条假期余额记录的id
detailData.put("jqye", jqyeId + "," + holidayBalance.get("id").toString() + "_" + leaveDuration);
}
leaveDuration = 0;
result.add(detailData);
}
holidayBalance.put("wxsc", wxsc);
}
}
leaveDurationMap.put("totalLeaveDuration", totalLeaveDuration);
leaveDurationMap.put("leaveDuration", leaveDuration);
}
/**
* 使
* @param unableUseJqyeIdList 使id
* @param editedUseJqed id使
* @param itemId id
* @param startDate
* @param leaveEmpId
* @return
*/
private List<Map<String, Object>> collectUsableHolidayBalance(List<String> unableUseJqyeIdList, Map<String, Double> editedUseJqed, String itemId, String startDate, String leaveEmpId) {
String sql = "select id,jqid,sxrq,ktsc,yxsc,wxsc,yqsxrq,ztsc from uf_jcl_kq_jqye where ygid=? and jqid=? and sxrq<=? and yqsxrq>=? order by sxrq";
List<Map<String, Object>> holidayBalanceList = DbTools.getSqlToList(sql, leaveEmpId, itemId, startDate, startDate);
//获取假期额度规则中额度可修次数、单次最小休时长、额度单位
String jqedSql = "select eddw, dczskxsc, edbxdcxw from uf_jcl_kq_jqed where jb = ?";
Map<String, Object> jqedInfo = DbTools.getSqlToMap(jqedSql, itemId);
//假期额度的额度单位0-天、1-小时
String eddw = Util.null2String(jqedInfo.get("eddw"));
//单次最小休时长
String minDuration = Util.null2String(jqedInfo.get("dczskxsc"));
Double minLeaveDuration = null;
if (!"".equals(eddw) && !"".equals(minDuration)) {
minLeaveDuration = Double.parseDouble(minDuration);
if (eddw.equals(AccountingUnitEnum.DAY.getKey())) {
minLeaveDuration = minLeaveDuration * 8;
}
}
//额度可修次数
String allowLeaveNumStr = Util.null2String(jqedInfo.get("edbxdcxw"));
if (!"".equals(allowLeaveNumStr) && holidayBalanceList.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 = " + itemId + " and qjry = " + leaveEmpId + " 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 = 0;
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);
}
}
}
//筛选次数未使用完的假期余额
holidayBalanceList = holidayBalanceList.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());
}
//遍历可使用的假期余额,去除已编辑请假明细记录中使用的时长
List<Map<String, Object>> canUseHolidayBalanceList = new ArrayList<>();
for (Map<String, Object> holidayBalance : holidayBalanceList) {
String jqyeId = Util.null2String(holidayBalance.get("id"));
if (!unableUseJqyeIdList.contains(jqyeId)) {
double wxsc = Utils.convertDouble(holidayBalance.get("wxsc"));
double editedUseSc = Utils.convertDouble(editedUseJqed.get(jqyeId));
double realWxsc = wxsc - editedUseSc;
if ((minLeaveDuration == null || wxsc >= minLeaveDuration) && realWxsc > 0) {
holidayBalance.put("wxsc", realWxsc);
holidayBalance.put("minLeaveDuration", minLeaveDuration);
holidayBalance.put("eddw", eddw);
canUseHolidayBalanceList.add(holidayBalance);
}
}
}
return canUseHolidayBalanceList;
}
/**
*
* @param leaveEmpIdList
* @param startDate
* @param endDate
* @return
*/
private Map<String, List<Map<String, Object>>> getScheduleInfoWithEmpId(List<String> leaveEmpIdList, 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 : leaveEmpIdList) {
params.put("pbdx", empId);
Map<String,Object> schedulingResultsMap = schedulingResultsService.queryDataTableActualUse(params);
scheduleInfo.put(empId, (List<Map<String, Object>>) schedulingResultsMap.get("data"));
}
return scheduleInfo;
}
/**
*
* @param leaveEmpIdList
* @param leaveType
* @param startDate
* @param endDate
* @return
*/
private Map<String, List<String>> getRestDayWithEmpId(List<String> leaveEmpIdList, String leaveType, String startDate, String endDate) {
Map<String, List<String>> restDayInfoWithEmpId = new HashMap<>();
Map<String, Object> restDayParam = new HashMap<>();
restDayParam.put("itemId", leaveType);
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 = new HashMap<>();
List<Map<String,Object>> dataList = new ArrayList<>();
List<String> restDateList = new ArrayList<>();
for (String empId : leaveEmpIdList) {
restDayParam.put("userId", empId);
restDayInfo = getRestDayInterval(restDayParam);
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;
}
}

@ -95,4 +95,31 @@ public class AskForLeaveAction {
return ApiReturnTools.error("500","getBusinessTripsApplyList error");
}
}
/**
* -
* @return
*/
@GET
@Path("/generateLeaveInfoList")
@Produces({"text/plain"})
public String generateLeaveInfoList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
try {
Map<String,Object> param = ParamUtil.request2Map(request);
User user = HrmUserVarify.getUser(request, response);
String mainTableDataStr = Util.null2String(param.get("mainTableData"));
String detailTableDataStr = Util.null2String(param.get("detailTableData"));
Gson gson = new Gson();
Map<String,Object> mainTableData = gson.fromJson(mainTableDataStr, (Type) Map.class);
List<Map<String, String>> detailTableData = gson.fromJson(detailTableDataStr, (Type) List.class);
param.put("mainTableData",mainTableData);
param.put("detailTableData",detailTableData);
// return new ResponseResult<Map<String, Object>, Map<String, Object>>(user).run(getAskForLeaveService(user) :: generateLeaveInfoList,param);
return null;
}catch (Exception e){
log.error("sync fund status fail,catch error: [{}]",e);
return ApiReturnTools.error("200","查询失败");
}
}
}

@ -3,11 +3,15 @@ package com.engine.common.util;
import org.apache.commons.lang3.StringUtils;
import weaver.general.TimeUtil;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -355,4 +359,27 @@ public class DateUtil {
public static boolean checkYearMonth(String yearMonth) {
return Pattern.matches(MONTH_REGEX, yearMonth);
}
/**
*
* @param startDateStr
* @param endDateStr
* @return
* @throws ParseException
*/
public static List<String> getDatesBetween(String startDateStr, String endDateStr) throws ParseException {
List<String> dates = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = sdf.parse(startDateStr);
Date endDate = sdf.parse(endDateStr);
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
while (calendar.getTime().before(endDate) || calendar.getTime().equals(endDate)) {
dates.add(sdf.format(calendar.getTime()));
calendar.add(Calendar.DATE, 1);
}
return dates;
}
}

@ -698,6 +698,17 @@ public class Utils<T> {
return new BigDecimal(value1).multiply(new BigDecimal(value2),new MathContext(BigDecimal.ROUND_HALF_UP)).doubleValue();
}
/**
*
* @param value1
* @param value2
* @return
*/
public static double divide(double value1, int value2){
return new BigDecimal(value1).divide(new BigDecimal(value2), 2, RoundingMode.HALF_UP).doubleValue();
}
/**
*
* @param date

Loading…
Cancel
Save