package com.engine.salary.entity.salaryarchive.bo; import com.engine.core.impl.Service; import com.engine.salary.constant.SalaryArchiveConstant; import com.engine.salary.constant.SalaryDefaultTenantConstant; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveInitImportDTO; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveInitImportSameDTO; import com.engine.salary.entity.salaryarchive.dto.SalaryItemAdjustValidDTO; import com.engine.salary.entity.salaryarchive.param.SalaryArchiveImportHandleParam; import com.engine.salary.entity.salaryarchive.po.SalaryArchiveItemPO; import com.engine.salary.entity.salaryarchive.po.SalaryArchivePO; import com.engine.salary.entity.salaryitem.po.SalaryItemPO; import com.engine.salary.entity.salarysob.param.SalarySobRangeSaveParam; import com.engine.salary.entity.taxagent.dto.TaxAgentManageRangeEmployeeDTO; import com.engine.salary.entity.taxagent.param.TaxAgentManageRangeSaveParam; import com.engine.salary.entity.taxagent.param.TaxAgentRangeSaveParam; import com.engine.salary.enums.UserStatusEnum; import com.engine.salary.enums.salaryarchive.*; import com.engine.salary.enums.salarysob.SalaryEmployeeStatusEnum; import com.engine.salary.enums.salarysob.TargetTypeEnum; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryI18nUtil; import com.engine.salary.util.db.IdGenerator; import com.engine.salary.util.excel.ExcelComment; import com.google.common.base.Joiner; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import weaver.general.Util; import weaver.hrm.User; import java.time.LocalDate; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * @Description: 薪资档案-excel * @Author: wangxiangzhong * @Date: 2021-11-03 10:51 */ public class SalaryArchiveExcelBO extends Service { public static String userNameI18n; public static String departmentI18n; public static String jobNumI18n; public static String hrStatusI18n; public static String repeatMsg; public static String taxAgentI18n; public static String taxAgentRangeMsg; public static String empRepeatMsg; public static String notEmptyI18n; public static String incomeCategoryI18n; public static String salarySobI18n; public static String effectiveTimeI18n; public static String payStartDateI18n; public static String payEndDateI18n; public static String adjustReasonI18n; public static String listTypeErrMsg; public static String taxAgentNoExist; public static String incomeCategoryNoExist; public static String currSalarySobI18n; public static String noExist; public static String effectiveTimeErr; public static String adjustReasonNoExist; public static String dateErr; public static String payStartUnableAfterEnd; public static String salaryItemNoBeforeCurrentEffectiveTime; public static String salaryItemAdjustNoSame; public static String salaryItemAdjustNoSameIneffective; public static String salaryArchiveErr; public static String numberErr; /** * 初始化i18n */ public static void initI18n() { userNameI18n = SalaryI18nUtil.getI18nLabel(85429, "姓名"); departmentI18n = SalaryI18nUtil.getI18nLabel(86185, "部门"); jobNumI18n = SalaryI18nUtil.getI18nLabel(86317, "工号"); hrStatusI18n = SalaryI18nUtil.getI18nLabel(109332, "人事状态"); repeatMsg = "[" + Joiner.on(",").join(new List[]{Arrays.asList(userNameI18n, departmentI18n, jobNumI18n, hrStatusI18n)}) + "]"; taxAgentI18n = SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"); taxAgentRangeMsg = SalaryI18nUtil.getI18nLabel(132633, "该员工不在该个税扣缴义务人的人员范围中") + "," + SalaryI18nUtil.getI18nLabel(127308, "请检查") + repeatMsg; empRepeatMsg = SalaryI18nUtil.getI18nLabel(121899, "员工信息重复,请检查") + repeatMsg; notEmptyI18n = SalaryI18nUtil.getI18nLabel(100577, "不能为空"); incomeCategoryI18n = SalaryI18nUtil.getI18nLabel(121908, "收入所得项目"); salarySobI18n = SalaryI18nUtil.getI18nLabel(87889, "薪资账套"); effectiveTimeI18n = SalaryI18nUtil.getI18nLabel(85904, "生效日期"); payStartDateI18n = SalaryI18nUtil.getI18nLabel(109527, "起始发薪日期"); payEndDateI18n = SalaryI18nUtil.getI18nLabel(109329, "最后发薪日期"); adjustReasonI18n = SalaryI18nUtil.getI18nLabel(85431, "调整原因"); listTypeErrMsg = SalaryI18nUtil.getI18nLabel(115527, "该条数据不符合当前列表导入要求或其他列表存在该档案,不可导入"); taxAgentNoExist = SalaryI18nUtil.getI18nLabel(100545, "个税扣缴义务人不存在"); incomeCategoryNoExist = SalaryI18nUtil.getI18nLabel(121923, "收入所得项目不存在"); currSalarySobI18n = SalaryI18nUtil.getI18nLabel(127213, "该收入所得项目"); noExist = SalaryI18nUtil.getI18nLabel(127236, "不存在"); effectiveTimeErr = SalaryI18nUtil.getI18nLabel(102497, "生效日期错误或格式不正确,正确格式示例为'2022-01-01'、'2022/1/1'"); adjustReasonNoExist = SalaryI18nUtil.getI18nLabel(100591, "调整原因不存在"); dateErr = SalaryI18nUtil.getI18nLabel(109819, "日期错误或格式不正确,正确格式示例为'2022-01-01'、'2022/1/1'"); payStartUnableAfterEnd = SalaryI18nUtil.getI18nLabel(109214, "起始发薪日期不可晚于最后发薪日"); salaryItemNoBeforeCurrentEffectiveTime = SalaryI18nUtil.getI18nLabel(100429, "生效日期不可早于当前已生效的调整日期"); salaryItemAdjustNoSame = SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同"); salaryItemAdjustNoSameIneffective = SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同"); salaryArchiveErr = SalaryI18nUtil.getI18nLabel(101723, "该员工的薪资档案记录有误,请检查"); numberErr = SalaryI18nUtil.getI18nLabel(100581, "请输入数字"); } /** * 检查导入参数 * * @param message * @param params * @return */ public static String handleCheckParams(Map message, Map params) { String errorMsg = ""; String listType = Optional.ofNullable(params.get("listType")).orElse("").toString(); String importType = Optional.ofNullable(params.get("importType")).orElse("").toString(); if (params == null) { errorMsg = SalaryI18nUtil.getI18nLabel(100582, "参数必传"); } else if (StringUtils.isEmpty(listType)) { errorMsg = // SalaryI18nUtil.getI18nLabel( 100592, "导入类型必传") + "," + SalaryI18nUtil.getI18nLabel(109712, "列表类型必传"); } else { Optional optionalListType = Arrays.stream(SalaryArchiveListTypeEnum.values()).filter(e -> e.getValue().equals(listType)).findFirst(); if (optionalListType.isPresent()) { // 定薪列表导入有调薪导入和初始化导入 if (optionalListType.get().getValue().equals(SalaryArchiveListTypeEnum.FIXED.getValue())) { Optional optional = Arrays.stream(SalaryArchiveImportTypeEnum.values()).filter(e -> e.getValue().equals(params.get("importType").toString())).findFirst(); if (!optional.isPresent()) { errorMsg = SalaryI18nUtil.getI18nLabel(100593, "导入类型不正确"); } else { // message.setDataType(message.getDataType() // + "-" + SalaryI18nUtil.getI18nLabel( optionalListType.get().getLabelId(), optionalListType.get().getDefaultLabel()) // + "-" + SalaryI18nUtil.getI18nLabel( optional.get().getLabelId(), optional.get().getDefaultLabel())); } } else { // message.setDataType(message.getDataType() // + "-" + SalaryI18nUtil.getI18nLabel( optionalListType.get().getLabelId(), optionalListType.get().getDefaultLabel())); } } else { errorMsg = SalaryI18nUtil.getI18nLabel(109716, "列表类型不正确"); } } return errorMsg; } /** * 检查导入列 * * @param importHandleParam * @param headers * @return */ public static String handleCheckHeaders(SalaryArchiveImportHandleParam importHandleParam, Map message, List headers) { List headerList = headers; List mustHeaders = Lists.newArrayList(); if (!importHandleParam.isProcess()) { //流程中可以使用人员id mustHeaders.add(userNameI18n); } mustHeaders.add(taxAgentI18n); // mustHeaders.add(incomeCategoryI18n); // mustHeaders.add(salarySobI18n); if (importHandleParam.isPendingList()) { mustHeaders.add(payStartDateI18n); mustHeaders.add(payEndDateI18n); } else if (importHandleParam.isFixedList()) { if (importHandleParam.isInit()) { mustHeaders.add(payStartDateI18n); mustHeaders.add(payEndDateI18n); mustHeaders.add(effectiveTimeI18n); } else if (importHandleParam.isSalaryItemAdjust()) { mustHeaders.add(adjustReasonI18n); mustHeaders.add(effectiveTimeI18n); } } else if (importHandleParam.isSuspendList()) { mustHeaders.add(payEndDateI18n); } // 缺少的必须列 List lackHeaders = mustHeaders.stream().filter(item -> !headerList.contains(item)).collect(Collectors.toList()); String checkHeaderI18n = SalaryI18nUtil.getI18nLabel(101850, "缺少如下列,请检查:"); return CollectionUtils.isNotEmpty(lackHeaders) ? checkHeaderI18n + Joiner.on(",").join((Iterable) lackHeaders) : ""; } /** * 创建excel单元格注释 * * @param excelComments * @param commentData * @param startRowIndex * @param endRowIndex * @param startColIndex * @param endColIndex */ public static void createExcelComment(List excelComments, String commentData, int startRowIndex, int endRowIndex, int startColIndex, int endColIndex) { ExcelComment excelComment = new ExcelComment(); // 起始行,结束行,起始列,结束列 // excelComment.setCommentSheet(new Integer[]{startRowIndex, endRowIndex, startColIndex, endColIndex}); // excelComment.setCommentRange(new Integer[]{startRowIndex, endRowIndex, startColIndex, endColIndex}); // excelComment.setCommentData(commentData); excelComments.add(excelComment); } /** * 初始化导入数据校验 * 说明:如果一个人的多条记录中有一个错那么就全部弄到错误文档中 * * @param isError * @param rowNo * @param map * @param excelComments * @param errorCount * @param successCount * @param errorData * @param initImportData * @param importHandleParam * @return */ public static Map validInitImportData(boolean isError, int rowNo, Map map, List> excelComments, int errorCount, int successCount, List> errorData, List initImportData, SalaryArchiveImportHandleParam importHandleParam) { Long employeeId = Long.valueOf(Optional.ofNullable(map.get("employeeId")).orElse("0").toString()); Long taxAgentId = Long.valueOf(Optional.ofNullable(map.get("taxAgentId")).orElse("0").toString()); Map validMap = new HashMap<>(); validMap.put("errorCount", errorCount); validMap.put("successCount", successCount); if (employeeId.equals(0L) || taxAgentId.equals(0L)) { return validMap; } Optional optionalInitImport = initImportData.stream().filter(f -> f.getEmployeeId().equals(employeeId) && f.getTaxAgentId().equals(taxAgentId)).findFirst(); AtomicInteger finalErrorCount = new AtomicInteger(errorCount); AtomicInteger finalSuccessCount = new AtomicInteger(successCount); if (optionalInitImport.isPresent()) { SalaryArchiveInitImportDTO initImport = optionalInitImport.get(); List sames = initImport.getSames(); sames.add(SalaryArchiveInitImportSameDTO.builder() .isError(isError) .rowNo(rowNo) .row(map) .build()); Optional optionalSame = sames.stream().filter(SalaryArchiveInitImportSameDTO::isError).findFirst(); // 只要是其中一行有错误 if (optionalSame.isPresent()) { sames.forEach(e -> { if (!e.isError()) { e.setError(Boolean.TRUE); Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", "第" + (e.getRowNo() + 1) + "行" + salaryArchiveErr); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, salaryArchiveErr, finalErrorCount.get() + 1, finalErrorCount.get() + 1, 0, 0); finalErrorCount.addAndGet(1); errorData.add(e.getRow()); finalSuccessCount.addAndGet(-1); } }); // 如果到目前为止都没错的话,则相互之间检验调整记录 } else { int nums = sames.size(); // 1.生效时间不可重复 List effectiveTimeList = sames.stream().map(m -> Optional.ofNullable(m.getRow().get("effectiveTime")).orElse("").toString()).distinct().collect(Collectors.toList()); // 2.薪资项目共同决定是否重复 List rowSameList = sames.stream().map(m -> { Map row = m.getRow(); return Optional.ofNullable(row.get("salaryItemVal")).orElse("").toString(); }).distinct().collect(Collectors.toList()); if (effectiveTimeList.size() != nums || rowSameList.size() != nums) { sames.forEach(e -> { if (!e.isError()) { e.setError(Boolean.TRUE); Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", "第" + (e.getRowNo() + 1) + "行" + salaryArchiveErr); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, salaryArchiveErr, finalErrorCount.get() + 1, finalErrorCount.get() + 1, 0, 0); finalErrorCount.addAndGet(1); errorData.add(e.getRow()); finalSuccessCount.addAndGet(-1); } }); } } initImport.setSames(sames); } else { SalaryArchiveInitImportDTO initImport = new SalaryArchiveInitImportDTO(); initImport.setEmployeeId(employeeId); initImport.setTaxAgentId(taxAgentId); List sames = Lists.newArrayList(); sames.add(SalaryArchiveInitImportSameDTO.builder() .isError(isError) .rowNo(rowNo) .row(map) .build()); initImport.setSames(sames); initImportData.add(initImport); } // 如果出现错误 if (isError || errorCount != finalErrorCount.get() || successCount != finalSuccessCount.get()) { validMap.put("errorCount", finalErrorCount.get()); validMap.put("successCount", finalSuccessCount.get()); // 将前面添加好的数据给过滤掉 List salaryArchiveIds = importHandleParam.getSalaryArchiveSaves().stream().filter(f -> f.getEmployeeId().equals(employeeId) && f.getTaxAgentId().equals(taxAgentId)).map(SalaryArchivePO::getId).collect(Collectors.toList()); importHandleParam.setSalaryArchiveSaves(importHandleParam.getSalaryArchiveSaves().stream().filter(f -> !salaryArchiveIds.contains(f.getId())).collect(Collectors.toList())); importHandleParam.setSalaryArchiveItemSaves(importHandleParam.getSalaryArchiveItemSaves().stream().filter(f -> !salaryArchiveIds.contains(f.getSalaryArchiveId())).collect(Collectors.toList())); } return validMap; } /** * 校验单行数据 * * @param allTodoSalaryArchives * @param map * @param headers * @param effectiveTimeIndex * @param excelComments * @param errorCount * @param importHandleParam * @return */ public static boolean singleRowCheck(List allTodoSalaryArchives, Map map, List headers, int effectiveTimeIndex, List> excelComments, int errorCount, SalaryArchiveImportHandleParam importHandleParam, User user) { //是否是流程 boolean process = importHandleParam.isProcess(); boolean isError = false; String rowindex = "第" + map.get("index") + "行"; // 1.姓名 String userName = Optional.ofNullable(map.get(userNameI18n)).orElse("").toString(); String deparmentName = Optional.ofNullable(map.get(departmentI18n)).orElse("").toString(); String mobileName = Optional.ofNullable(map.get("手机号")).orElse("").toString(); String workcode = Optional.ofNullable(map.get("工号")).orElse("").toString(); String idNo = Optional.ofNullable(map.get("证件号码")).orElse("").toString(); String validType = importHandleParam.getEmpValidType(); List emps = new ArrayList<>(); //外部人员 if (importHandleParam.isExtEmp()) { emps = importHandleParam.getEmployees().stream().filter(e -> (StringUtils.isBlank(userName) || Objects.equals(e.getUsername(), userName)) && (StringUtils.isBlank(deparmentName) || Objects.equals(e.getDepartmentName(), deparmentName)) && (StringUtils.isBlank(mobileName) || Objects.equals(e.getMobile(), mobileName))).collect(Collectors.toList()); } else { if ("0".equals(validType)) { //“0”代表姓名+部门+手机号的匹配原则,“1”代表工号为唯一匹配原则 emps = importHandleParam.getEmployees().stream().filter(e -> (StringUtils.isBlank(userName) || Objects.equals(e.getUsername(), userName)) && (StringUtils.isBlank(deparmentName) || Objects.equals(e.getDepartmentName(), deparmentName)) && (StringUtils.isBlank(mobileName) || Objects.equals(e.getMobile(), mobileName))).collect(Collectors.toList()); } else if ("1".equals(validType)) { emps = importHandleParam.getEmployees().stream().filter(e -> (StringUtils.isBlank(workcode) || Objects.equals(e.getWorkcode(), workcode))) .collect(Collectors.toList()); } else if ("2".equals(validType)) { emps = importHandleParam.getEmployees().stream().filter(e -> (StringUtils.isBlank(idNo) || Objects.equals(e.getIdNo(), idNo))) .collect(Collectors.toList()); } } List employeeSameIds = new ArrayList<>(); if (CollectionUtils.isNotEmpty(emps) && emps.size() > 1) { employeeSameIds = emps.stream().filter(e -> UserStatusEnum.getNormalStatus().contains(e.getStatus())).map(DataCollectionEmployee::getEmployeeId).collect(Collectors.toList()); } if (CollectionUtils.isNotEmpty(emps) && emps.size() == 1) { employeeSameIds = emps.stream().map(DataCollectionEmployee::getEmployeeId).collect(Collectors.toList()); } Long employeeId = CollectionUtils.isNotEmpty(employeeSameIds) && employeeSameIds.size() == 1 && employeeSameIds.get(0) > 0 ? employeeSameIds.get(0) : null; //员工id 流程使用 String empId = Optional.ofNullable(map.get("员工id")).orElse("").toString(); if (StringUtils.isNotBlank(empId)) { employeeSameIds.clear(); employeeSameIds.add(Long.valueOf(empId)); employeeId = Long.valueOf(empId); } if (employeeId == null) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + "查找人员失败,请确定姓名、部门、手机号正确且唯一"); excelComments.add(errorMessageMap); isError = true; return isError; } // 用于初始化导入数据校验 map.put("employeeId", employeeId); // String incomeCategoryCellVal = Optional.ofNullable(map.get(incomeCategoryI18n)).orElse("").toString(); // Integer incomeCategory = SalaryArchiveBO.getIncomeCategoryValueByLabel(incomeCategoryCellVal, importHandleParam.getCurrentEmployeeId(), importHandleParam.getTenantKey()); // 薪资账套 // String salarySobCellVal = Optional.ofNullable(map.get(salarySobI18n)).orElse("").toString(); // 2.生效日期 String effectiveTimeCellVal = Optional.ofNullable(map.get(effectiveTimeI18n)).orElse("").toString().replaceAll(" 00:00:00", ""); // 免得失败后,会追加 00:00:00 map.put(effectiveTimeI18n, effectiveTimeCellVal); map.put("effectiveTime", effectiveTimeCellVal); Date effectiveTime = SalaryDateUtil.checkDay(effectiveTimeCellVal) ? SalaryDateUtil.dateStrToLocalDate(effectiveTimeCellVal) : null; // 3.个税扣缴义务人 String taxAgentCellVal = Optional.ofNullable(map.get(taxAgentI18n)).orElse("").toString(); // 用于初始化导入的同一个人的记录校验 map.put("taxAgent", taxAgentCellVal); Optional optionalTaxAgent = importHandleParam.getTaxAgentList().stream().filter(m -> m.getTaxAgentName().equals(taxAgentCellVal)).findFirst(); Long taxAgentId = optionalTaxAgent.map(TaxAgentManageRangeEmployeeDTO::getTaxAgentId).orElse(null); List finalEmployeeSameIds = employeeSameIds; if (!optionalTaxAgent.isPresent()) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + "个税扣缴义务人不存在"); excelComments.add(errorMessageMap); isError = true; return isError; } Optional optionalTaxAgentEmp = optionalTaxAgent.get().getEmployeeList().stream().filter(f -> finalEmployeeSameIds.contains(f.getEmployeeId())).findFirst(); if (!optionalTaxAgentEmp.isPresent()) { if (process) { //定薪流程中自动将人员添加进个税扣缴义务人中 TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam taxAgentSubAdminRangeTargetParam = new TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam(); taxAgentSubAdminRangeTargetParam.setTargetId(employeeId); taxAgentSubAdminRangeTargetParam.setTargetType(TargetTypeEnum.EMPLOYEE); TaxAgentRangeSaveParam taxAgentRangeSaveParam = new TaxAgentRangeSaveParam(); taxAgentRangeSaveParam.setTaxAgentId(taxAgentId); taxAgentRangeSaveParam.setIncludeType(1); taxAgentRangeSaveParam.setEmployeeStatus(Arrays.asList("0", "1", "2", "3", "4", "5", "6")); taxAgentRangeSaveParam.setTargetParams(Collections.singletonList(taxAgentSubAdminRangeTargetParam)); taxAgentRangeSaveParam.setSync(true); importHandleParam.setTaxAgentRanges(Collections.singletonList(taxAgentRangeSaveParam)); } // else { // Map errorMessageMap = Maps.newHashMap(); // errorMessageMap.put("message", rowindex + taxAgentRangeMsg); // excelComments.add(errorMessageMap); //// SalaryArchiveExcelBO.createExcelComment(excelComments, taxAgentRangeMsg, errorCount + 1, errorCount + 1, 0, 0); // isError = true; // return isError; // } } else { employeeId = optionalTaxAgentEmp.get().getEmployeeId(); // 除了定薪中的初始化,其他导入存在相同的取第一条 if (employeeId != null && taxAgentId != null && allTodoSalaryArchives.contains(employeeId + "-" + taxAgentId) && !importHandleParam.isInit()) { return isError; } if (employeeId != null && taxAgentId != null) { allTodoSalaryArchives.add(employeeId + "-" + taxAgentId); } } // 用于初始化导入重复记录判错 ===start map.put("employeeId", employeeId); map.put("taxAgentId", taxAgentId); // 用于初始化导入重复记录判错 ===end // 4.调整原因[薪资项目] String adjustReason = SalaryArchiveItemAdjustReasonEnum.getValueByDefaultLabel(Optional.ofNullable(map.get(adjustReasonI18n)).orElse("").toString()); // 5.起始发薪日期 String payStartDateCellVal = Optional.ofNullable(map.get(payStartDateI18n)).orElse("").toString().replaceAll(" 00:00:00", ""); // 免得失败后,会追加 00:00:00 map.put(payStartDateI18n, payStartDateCellVal); map.put("payStartDate", payStartDateCellVal); Date payStartDate = SalaryDateUtil.checkDay(payStartDateCellVal) ? SalaryDateUtil.dateStrToLocalDate(payStartDateCellVal) : null; //生效日期默认取起始发薪日期 if (effectiveTime == null) { effectiveTime = payStartDate; } // 6.最后发薪日期 String payEndDateCellVal = Optional.ofNullable(map.get(payEndDateI18n)).orElse("").toString().replaceAll(" 00:00:00", ""); // 免得失败后,会追加 00:00:00 map.put(payEndDateI18n, payEndDateCellVal); map.put("payEndDate", payEndDateCellVal); Date payEndDate = SalaryDateUtil.checkDay(payEndDateCellVal) ? SalaryDateUtil.dateStrToLocalDate(payEndDateCellVal) : null; // 构建薪资档案 SalaryArchivePO finalSalaryArchive = buildSalaryArchive(employeeId, taxAgentId, importHandleParam); // 不满足构建条件 if (finalSalaryArchive == null) { // SalaryI18nUtil.getI18nLabel( 100579, "姓名错误,系统内不存在该姓名") // SalaryI18nUtil.getI18nLabel( 101653, "该人员的薪资档案不存在,请先初始化" Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + listTypeErrMsg); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, listTypeErrMsg, errorCount + 1, errorCount + 1, 0, 0); isError = true; return isError; } else { map.put("salaryArchiveId", finalSalaryArchive.getId()); } for (int j = 0; j < headers.size(); j++) { String header = headers.get(j); Object key = header; if (key == null) { continue; } String cellVal = Optional.ofNullable(map.get(key.toString())).orElse("").toString(); // 必填判空 boolean isEmpty = StringUtils.isEmpty(cellVal) && ((userNameI18n.equals(key.toString()) && !process) || taxAgentI18n.equals(key.toString()) || incomeCategoryI18n.equals(key.toString()) || salarySobI18n.equals(key.toString()) // 定薪列表初始化导入必填: 起始发薪日期、生效日期 || ((payStartDateI18n.equals(key.toString()) || effectiveTimeI18n.equals(key.toString())) && importHandleParam.isInit()) // 定薪列表调薪必填: 调整原因、生效日期 || ((adjustReasonI18n.equals(key.toString()) || effectiveTimeI18n.equals(key.toString())) && importHandleParam.isSalaryItemAdjust()) // 待停薪必填:最后发薪日期 || (payEndDateI18n.equals(key.toString()) && importHandleParam.isSuspendList())); boolean isNotEmpty = StringUtils.isNotEmpty(cellVal); // 判空 if (isEmpty) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + header + notEmptyI18n); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, notEmptyI18n, errorCount + 1, errorCount + 1, j, j); isError = true; } // 1.姓名列处理 if (isNotEmpty && userNameI18n.equals(key.toString())) { if (CollectionUtils.isEmpty(employeeSameIds) || employeeSameIds.size() > 1) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + header + empRepeatMsg); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, empRepeatMsg, errorCount + 1, errorCount + 1, j, j); isError = true; } // 2.个税扣缴义务人列处理 } else if (isNotEmpty && taxAgentI18n.equals(key.toString())) { if (taxAgentId == null) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + header + taxAgentNoExist); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, taxAgentNoExist, errorCount + 1, errorCount + 1, j, j); isError = true; } // 收入所得项目 } // else if (isNotEmpty && incomeCategoryI18n.equals(key.toString())) { // if (incomeCategory == null) { // SalaryArchiveExcelBO.createExcelComment(excelComments, incomeCategoryNoExist, errorCount + 1, errorCount + 1, j, j); // isError = true; // } else { // finalSalaryArchive.setIncomeCategory(incomeCategory); // } // 薪资账套 // } // else if (isNotEmpty && salarySobI18n.equals(key.toString())) { // List salarySobNames = Arrays.stream(salarySobCellVal.split(",")).distinct().collect(Collectors.toList()); // List salarySobIds = Lists.newArrayList(); // importHandleParam.getSalarySobList().forEach(sob -> { // List incomeCategorys = StringUtils.isEmpty(sob.getIncomeCategory()) ? Lists.newArrayList() : JsonUtil.parseList(sob.getIncomeCategory(), Integer.class); // if (salarySobNames.contains(sob.getName()) && incomeCategory != null && incomeCategorys.contains(incomeCategory)) { // salarySobIds.add(sob.getId()); // salarySobNames.remove(sob.getName()); // } // }); // if (CollectionUtils.isNotEmpty(salarySobNames)) { // SalaryArchiveExcelBO.createExcelComment(excelComments, currSalarySobI18n + (StringUtils.isEmpty(incomeCategoryCellVal) ? "" : "[" + incomeCategoryCellVal + "]") + ": " + salarySobI18n + "[" + Joiner.on(",").join(salarySobNames) + "]" + noExist, errorCount + 1, errorCount + 1, j, j); // isError = true; // } else { // finalSalaryArchive.setIncomeCategory(incomeCategory); // importHandleParam.getSalaryArchiveSobSaves().addAll(SalaryArchiveBO.buildSalaryArchiveSob(finalSalaryArchive.getId(), salarySobIds, importHandleParam.getNowTime(), importHandleParam.getCurrentEmployeeId(), importHandleParam.getTenantKey())); // } // 3.生效时间处理(定薪的调薪\定薪的初始化) // } else if (isNotEmpty && effectiveTimeI18n.equals(key.toString()) && effectiveTime == null && importHandleParam.isFixedList()) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + header + effectiveTimeErr); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, effectiveTimeErr, errorCount + 1, errorCount + 1, j, j); isError = true; // 4.调整原因列(定薪的调薪) } else if (isNotEmpty && adjustReasonI18n.equals(key.toString()) && StringUtils.isEmpty(adjustReason) && importHandleParam.isSalaryItemAdjust()) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + header + adjustReasonNoExist); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, adjustReasonNoExist, errorCount + 1, errorCount + 1, j, j); isError = true; // 5.起始发薪日期处理(定薪的初始化\待定新) } else if (isNotEmpty && payStartDateI18n.equals(key.toString()) && (importHandleParam.isInit() || importHandleParam.isPendingList())) { if (payStartDate == null) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + header + dateErr); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, dateErr, errorCount + 1, errorCount + 1, j, j); isError = true; } // 正确的话,并且定薪或待定薪的档案存在 if (payStartDate != null) { if (payEndDate != null || finalSalaryArchive.getPayEndDate() != null) { Date payEndDateTemp = payEndDate != null ? payEndDate : (finalSalaryArchive.getPayEndDate() != null ? finalSalaryArchive.getPayEndDate() : null); // todo 1.定薪的允许编辑,若已存在已归档的核算数据则不可编辑 if (payEndDateTemp != null && payStartDate.after(payEndDateTemp)) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + header + payStartUnableAfterEnd); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, payStartUnableAfterEnd, errorCount + 1, errorCount + 1, j, j); isError = true; } } // 2.待停薪只能不允许编辑起始发薪日期 if (!importHandleParam.isSuspendList() && !isError) { finalSalaryArchive.setPayStartDate(payStartDate); } } // 6.最后发薪日期处理(待定薪\定薪的初始化\待停薪) } else if (payEndDateI18n.equals(key.toString()) && !importHandleParam.isSalaryItemAdjust()) { if (isNotEmpty) { if (payEndDate == null) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + header + dateErr); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, dateErr, errorCount + 1, errorCount + 1, j, j); isError = true; } if (payEndDate != null) { if (payStartDate != null || finalSalaryArchive.getPayStartDate() != null) { Date payStartDateTemp = payStartDate != null ? payStartDate : (finalSalaryArchive.getPayStartDate() != null ? finalSalaryArchive.getPayStartDate() : null); // todo 1.定薪的允许编辑,若已存在已归档的核算数据则不可编辑 // 2.待停薪只能不允许编辑起始发薪日期 if (importHandleParam.isSuspendList()) { payStartDateTemp = finalSalaryArchive.getPayStartDate(); } if (payStartDateTemp != null && payStartDateTemp.after(payEndDate)) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + header + payStartUnableAfterEnd); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, payStartUnableAfterEnd, errorCount + 1, errorCount + 1, j, j); isError = true; } } if (!isError) { finalSalaryArchive.setPayEndDate(payEndDate); } } } else { finalSalaryArchive.setPayEndDate(null); } // 7.薪资项目列处理(待定薪\定薪的初始化\定薪的调薪) } else { isError = handleSalaryItem(isError, effectiveTimeIndex, excelComments, errorCount, j, effectiveTime, finalSalaryArchive, adjustReason, importHandleParam, key.toString(), cellVal, map, user); } } //账套关联 Long finalEmployeeId = employeeId; String sobIds = Optional.ofNullable(map.get("薪资账套ids")).orElse("").toString(); List salarySobRangeSaveParams = new ArrayList<>(); if (StringUtils.isNotBlank(sobIds)) { salarySobRangeSaveParams = Arrays.stream(sobIds.split(",")).map(Long::valueOf).map(sobId -> { SalarySobRangeSaveParam.SalarySobRangeTargetParam salarySobRangeTargetParam = new SalarySobRangeSaveParam.SalarySobRangeTargetParam(); salarySobRangeTargetParam.setTargetId(finalEmployeeId); salarySobRangeTargetParam.setTargetType(TargetTypeEnum.EMPLOYEE); salarySobRangeTargetParam.setEmployeeStatus(SalaryEmployeeStatusEnum.values()); SalarySobRangeSaveParam sobRangeSaveParam = new SalarySobRangeSaveParam(); sobRangeSaveParam.setSalarySobId(sobId); sobRangeSaveParam.setTargetParams(Collections.singletonList(salarySobRangeTargetParam)); sobRangeSaveParam.setIncludeType(1); sobRangeSaveParam.setEmployeeStatus(SalaryEmployeeStatusEnum.values()); return sobRangeSaveParam; }).collect(Collectors.toList()); } // 如果当前校验行没问题,修改起始发薪日期和最终发薪日期等 if (!isError) { Optional optionalUpdate = importHandleParam.getSalaryArchiveUpdates().stream().filter(f -> f.getId().equals(finalSalaryArchive.getId())).findFirst(); boolean unEnable = finalSalaryArchive.getPayStartDate() != null && finalSalaryArchive.getPayEndDate() != null && finalSalaryArchive.getPayStartDate().after(finalSalaryArchive.getPayEndDate()); if (optionalUpdate.isPresent() && !unEnable) { List updates = importHandleParam.getSalaryArchiveUpdates().stream().filter(f -> !f.getId().equals(finalSalaryArchive.getId())).collect(Collectors.toList()); updates.add(finalSalaryArchive); importHandleParam.setSalaryArchiveUpdates(updates); } Optional optionalSave = importHandleParam.getSalaryArchiveSaves().stream().filter(f -> f.getId().equals(finalSalaryArchive.getId())).findFirst(); if (optionalSave.isPresent() && !unEnable) { List saves = importHandleParam.getSalaryArchiveSaves().stream().filter(f -> !f.getId().equals(finalSalaryArchive.getId())).collect(Collectors.toList()); saves.add(finalSalaryArchive); importHandleParam.setSalaryArchiveSaves(saves); } //保存账套关联 importHandleParam.setSalaryArchiveSobSaves(salarySobRangeSaveParams); } else { // 将前面添加好的数据给过滤掉 importHandleParam.setSalaryArchiveSaves(importHandleParam.getSalaryArchiveSaves().stream().filter(f -> !finalSalaryArchive.getId().equals(f.getId())).collect(Collectors.toList())); importHandleParam.setSalaryArchiveUpdates(importHandleParam.getSalaryArchiveUpdates().stream().filter(f -> !finalSalaryArchive.getId().equals(f.getId())).collect(Collectors.toList())); importHandleParam.setSalaryArchiveItemDelSalaryItemIds(importHandleParam.getSalaryArchiveItemDelSalaryItemIds().stream().filter(f -> !finalSalaryArchive.getId().equals(f)).collect(Collectors.toList())); importHandleParam.setSalaryArchiveItemSaves(importHandleParam.getSalaryArchiveItemSaves().stream().filter(f -> !finalSalaryArchive.getId().equals(f.getSalaryArchiveId())).collect(Collectors.toList())); // importHandleParam.setSalaryArchiveSobSaves(importHandleParam.getSalaryArchiveSobSaves().stream().filter(f -> !finalSalaryArchive.getId().equals(f.getSalaryArchiveId())).collect(Collectors.toList())); } return isError; } /** * 字符串转日期 * 兼容/和- * * @param effectiveTime * @return */ public static LocalDate dateStrToLocalDate(String effectiveTime) { LocalDate localDate = null; try { if (effectiveTime.contains("/")) { String[] strs = effectiveTime.split("/"); localDate = LocalDate.of(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), Integer.parseInt(strs[2])); } else if (effectiveTime.contains("-")) { String[] strs = effectiveTime.replaceAll("-0", "-").split("-"); // localDate = LocalDate.parse(effectiveTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 月份日期超过最大会被改为最大 localDate = LocalDate.of(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), Integer.parseInt(strs[2])); } } catch (Exception e) { } return localDate; } /** * 构建薪资档案对象 * * @param employeeId * @param taxAgentId * @param importHandleParam * @return */ public static SalaryArchivePO buildSalaryArchive(Long employeeId, Long taxAgentId, SalaryArchiveImportHandleParam importHandleParam) { SalaryArchivePO salaryArchive = importHandleParam.getSalaryArchivesMap().get(employeeId + "-" + taxAgentId); if (salaryArchive != null) { // 修改档案 SalaryArchivePO sa = salaryArchive; boolean isEnabled = // 待定薪导入 (sa.getRunStatus().equals(SalaryArchiveStatusEnum.PENDING.getValue()) && importHandleParam.isPendingList()) // 调薪导入 || ((sa.getRunStatus().equals(SalaryArchiveStatusEnum.FIXED.getValue()) || sa.getRunStatus().equals(SalaryArchiveStatusEnum.SUSPEND.getValue())) && importHandleParam.isFixedList() && !importHandleParam.isInit()) // 初始化导入 || importHandleParam.isInit() // 待停薪导入 || ((sa.getRunStatus().equals(SalaryArchiveStatusEnum.FIXED.getValue()) || sa.getRunStatus().equals(SalaryArchiveStatusEnum.SUSPEND.getValue())) && importHandleParam.isSuspendList()); if (isEnabled) { if (importHandleParam.isInit() && (importHandleParam.getKeepStatus() == null || importHandleParam.getKeepStatus().equals(Boolean.FALSE))) { sa.setRunStatus(SalaryArchiveStatusEnum.FIXED.getValue()); } // sa.setModifier(importHandleParam.getCurrentEmployeeId()); salaryArchive = sa; importHandleParam.getSalaryArchiveUpdates().add(salaryArchive); } } else if (employeeId != null && taxAgentId != null && importHandleParam.isInit()) { // 新增档案 salaryArchive = SalaryArchivePO.builder() .id(IdGenerator.generate()) .employeeId(employeeId) .taxAgentId(taxAgentId) .runStatus(SalaryArchiveStatusEnum.FIXED.getValue()) .createTime(importHandleParam.getNowTime()) .updateTime(importHandleParam.getNowTime()) .creator(importHandleParam.getCurrentEmployeeId()) // .modifier(importHandleParam.getCurrentEmployeeId()) .deleteType(NumberUtils.INTEGER_ZERO) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .employeeType(importHandleParam.isExtEmp() ? 1 : 0) .build(); // 定薪action 保持状态为待定薪 if (importHandleParam.isInit() && importHandleParam.getKeepStatus() != null && importHandleParam.getKeepStatus().equals(Boolean.TRUE)) { salaryArchive.setRunStatus(SalaryArchiveStatusEnum.PENDING.getValue()); } importHandleParam.getSalaryArchiveSaves().add(salaryArchive); } return salaryArchive; } /** * 薪资项目处理 * * @param isError * @param effectiveTimeIndex * @param excelComments * @param errorCount * @param j * @param effectiveTime * @param finalSalaryArchive * @param salaryItemAdjustReason * @param importHandleParam * @param key * @param cellVal * @param map * @return */ public static boolean handleSalaryItem(boolean isError, int effectiveTimeIndex, List> excelComments, int errorCount, int j, Date effectiveTime, SalaryArchivePO finalSalaryArchive, String salaryItemAdjustReason, SalaryArchiveImportHandleParam importHandleParam, String key, String cellVal, Map map, User user) { String rowindex = "第" + map.get("index") + "行"; // 薪资项目数据 if (isError || importHandleParam.isSuspendList() || (importHandleParam.isSalaryItemAdjust() && effectiveTime == null) || finalSalaryArchive == null) { return isError; } Optional optionalSalaryItem = importHandleParam.getSalaryItems().stream().filter(e -> Util.formatMultiLang(e.getName(), String.valueOf(user.getLanguage())).equals(key)).findFirst(); // 可以处理薪资项目的条件:有薪资项目+待定薪列表+定薪列表(调薪和初始化导入) boolean isEnable = optionalSalaryItem.isPresent() && (importHandleParam.isPendingList() || importHandleParam.isInit() || importHandleParam.isSalaryItemAdjust()); if (isEnable) { SalaryItemPO salaryItemPO = optionalSalaryItem.get(); // 数值类型判断 boolean isNotNumber = salaryItemPO.getDataType().equals(SalaryArchiveFieldTypeEnum.NUMBER.getValue()) && StringUtils.isNotEmpty(cellVal) && !Pattern.matches(SalaryArchiveConstant.NUMBER_REGEX, cellVal); if (isNotNumber) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + key + numberErr); excelComments.add(errorMessageMap); // SalaryArchiveExcelBO.createExcelComment(excelComments, numberErr, errorCount + 1, errorCount + 1, j, j); isError = true; return isError; } Long salaryItemId = salaryItemPO.getId(); // 已生效 List effectiveList = Optional.ofNullable(importHandleParam.getEffectiveItemListMap().get(finalSalaryArchive.getId() + "-" + salaryItemId)).orElse(Lists.newArrayList()); // 当前已生效 SalaryArchiveItemPO effectiveSalaryItem = CollectionUtils.isNotEmpty(effectiveList) && effectiveList.size() > 0 ? effectiveList.get(0) : null; // 当前已生效的前一次调整 SalaryArchiveItemPO effectiveBeforeSalaryItem = CollectionUtils.isNotEmpty(effectiveList) && effectiveList.size() > 1 ? effectiveList.get(1) : null; // 未生效 List ineffectiveItemList = importHandleParam.getIneffectiveItemListMap().get(finalSalaryArchive.getId() + "-" + salaryItemId); SalaryArchiveItemPO ineffectiveSalaryItem = CollectionUtils.isEmpty(ineffectiveItemList) ? null : ineffectiveItemList.get(0); // 待定薪和初始化:先删除后新增 if (importHandleParam.isPendingList() || importHandleParam.isInit()) { // 已经生效的 importHandleParam.getSalaryArchiveItemDelSalaryItemIds().addAll(effectiveList.stream().map(SalaryArchiveItemPO::getId).collect(Collectors.toList())); if (ineffectiveSalaryItem != null) { importHandleParam.getSalaryArchiveItemDelSalaryItemIds().add(ineffectiveSalaryItem.getId()); } // 定薪列表调薪 } else if (importHandleParam.isSalaryItemAdjust()) { SalaryItemAdjustValidDTO salaryItemAdjustValid = SalaryArchiveItemBO.handleSalaryItemAdjustValid(effectiveSalaryItem, effectiveBeforeSalaryItem, ineffectiveSalaryItem, effectiveTime, importHandleParam.getToday(), cellVal, importHandleParam.getSalaryArchiveItemDelSalaryItemIds()); if (salaryItemAdjustValid.isBefore()) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + key + salaryItemNoBeforeCurrentEffectiveTime); excelComments.add(errorMessageMap); isError = true; } else if (salaryItemAdjustValid.isSame()) { // Map errorMessageMap = Maps.newHashMap(); // errorMessageMap.put("message", rowindex + key + salaryItemAdjustNoSame); // excelComments.add(errorMessageMap); // isError = true; //调整前后相同的值都不做处理 cellVal = ""; } else if (salaryItemAdjustValid.isSameIneffective()) { // Map errorMessageMap = Maps.newHashMap(); // errorMessageMap.put("message", rowindex + key + salaryItemAdjustNoSameIneffective); // excelComments.add(errorMessageMap); // isError = true; //调整前后相同的值都不做处理 cellVal = ""; } } // 导入时不需要处理的薪资项目 boolean isInitNull = CollectionUtils.isEmpty(effectiveList) && CollectionUtils.isEmpty(ineffectiveItemList) && StringUtils.isEmpty(cellVal); if (!isError && !isInitNull && StringUtils.isNotBlank(cellVal) && (importHandleParam.isPendingList() || importHandleParam.isInit() || importHandleParam.isSalaryItemAdjust())) { importHandleParam.getSalaryArchiveItemSaves().add(SalaryArchiveItemPO.builder() .id(IdGenerator.generate()) .salaryArchiveId(finalSalaryArchive.getId()) .employeeId(finalSalaryArchive.getEmployeeId()) .effectiveTime(effectiveTime == null ? new Date() : effectiveTime) // .adjustWay(SalaryArchiveAdjustWayEnum.IMPORT.getValue()) .adjustReason(StringUtils.isEmpty(salaryItemAdjustReason) ? SalaryArchiveItemAdjustReasonEnum.INIT.getValue() : salaryItemAdjustReason) .salaryItemId(salaryItemId) .itemValue(cellVal) .description(importHandleParam.getDescription() == null ? "" : importHandleParam.getDescription()) .operator(importHandleParam.getCurrentEmployeeId()) .operateTime(importHandleParam.getNowTime()) .createTime(importHandleParam.getNowTime()) .updateTime(importHandleParam.getNowTime()) .creator(importHandleParam.getCurrentEmployeeId()) .deleteType(NumberUtils.INTEGER_ZERO) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .build()); } // 用于初始化导入,同一个人的多行记录之间的薪资项目是否调整 map.put("salaryItemVal", Optional.ofNullable(map.get("salaryItemVal")).orElse("").toString() + salaryItemId + cellVal); } return isError; } @Override public String toString() { return "SalaryArchiveExcelBO{}"; } }