考勤-出差流程,明细数据生成功能

zm_dev
sy 9 months ago
parent d2b2a22be0
commit 5b1ee79780

@ -107,7 +107,7 @@ public class ExcelExportImportServiceImpl extends Service implements ExcelExport
List<WeaTableColumn> list = new ArrayList<>();
if (columnInfo != null && columnInfo.size() > 0) {
for (Map<String, Object> columnItem : columnInfo) {
list.add(new WeaTableColumn("150px", Util.null2String(columnItem.get("title")), Util.null2String(columnItem.get("dataIndex"))));
list.add(new WeaTableColumn("150px", Util.null2String(columnItem.get("context")), Util.null2String(columnItem.get("dataIndex"))));
}
}
return list;

@ -4,4 +4,11 @@ import java.util.Map;
public interface BusinessTripsApplyService {
Map<String, Object> getBusinessTripsApplyList(Map<String, Object> params);
/**
*
* @param params
*/
Map<String, Object> generateBusinessTripsList(Map<String, Object> params);
}

@ -458,7 +458,6 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic
: String.valueOf(qjscByAccount));
simpleLeaveDetailList.add(simpleLeaveDetailItem);
}
simpleLeaveDetailList.add(simpleLeaveDetailItem);
} else if (leaveMode.equals(AskAndEvctionWayEnum.ALLDAY.getKey()) && !restDateList.contains(leaveDate)) {
simpleLeaveDetailItem = new HashMap<>();
//组装初步的请假明细数据
@ -645,7 +644,7 @@ public class AskForLeaveServiceImpl extends Service implements AskForLeaveServic
}
totalLeaveDuration = totalLeaveDuration + leaveDuration;
}
//减去编辑已使用时长
//已编辑明细中已使用时长
Double checkItemEditedUseSc = editedUseJqlxWithEmp.getOrDefault(checkItemId + "_" + empId, (double) 0);
Double firstItemEditedUseSc = editedUseJqlxWithEmp.getOrDefault(firstItemId + "_" + empId, (double) 0);
// totalLeaveDuration = Utils.subtract(totalLeaveDuration, checkItemEditedUseSc == null ? 0 : checkItemEditedUseSc);

@ -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;
}
}

Loading…
Cancel
Save