package com.engine.salary.entity.datacollection.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.datacollection.param.VariableArchiveImportHandleParam; import com.engine.salary.entity.datacollection.po.VariableArchiveItemPO; import com.engine.salary.entity.datacollection.po.VariableArchivePO; import com.engine.salary.entity.datacollection.po.VariableItemPO; import com.engine.salary.entity.taxagent.po.TaxAgentPO; import com.engine.salary.enums.UserStatusEnum; import com.engine.salary.enums.salaryarchive.SalaryArchiveFieldTypeEnum; import com.engine.salary.util.SalaryI18nUtil; import com.engine.salary.util.db.IdGenerator; 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.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * @Description: 浮动薪资档案-excel * @Author: xzy * @Date: 2024-08-08 10:51 */ public class VariableArchiveExcelBO 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 map * @param headers * @param excelComments * @param errorCount * @param importHandleParam * @return */ public static boolean singleRowCheck(List allTodoVariableArchives, Map map, List headers, List> excelComments, int errorCount, VariableArchiveImportHandleParam importHandleParam, User user) { 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 ("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; if (employeeId == null) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + "查找人员失败,请确定姓名、部门、手机号正确且唯一"); excelComments.add(errorMessageMap); isError = true; return isError; } // 个税扣缴义务人 String taxAgentCellVal = Optional.ofNullable(map.get(taxAgentI18n)).orElse("").toString(); map.put("taxAgent", taxAgentCellVal); Optional optionalTaxAgent = importHandleParam.getTaxAgentList().stream().filter(m -> m.getName().equals(taxAgentCellVal)).findFirst(); if (!optionalTaxAgent.isPresent()) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + "个税扣缴义务人不存在,或不在权限范围内"); excelComments.add(errorMessageMap); isError = true; return isError; } Long taxAgentId = optionalTaxAgent.get().getId(); map.put("taxAgentId", taxAgentId); // 用于初始化导入数据校验 map.put("employeeId", employeeId); String repeatKey = optionalTaxAgent.get().getId() + "-" + employeeId.toString(); if (allTodoVariableArchives.contains(repeatKey)) { Map errorMessageMap = Maps.newHashMap(); errorMessageMap.put("message", rowindex + "存在重复数据"); excelComments.add(errorMessageMap); isError = true; return isError; } else { allTodoVariableArchives.add(repeatKey); } // 构建薪资档案 VariableArchivePO finalVariableArchive = buildVariableArchive(employeeId, taxAgentId, importHandleParam); map.put("variableArchiveId", finalVariableArchive.getId()); List needDelArchiveItemIds = new ArrayList<>(); 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 isNotEmpty = StringUtils.isNotEmpty(cellVal); // 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); isError = true; } } else { // 浮动薪资项目数据 if (!isError) { Optional optionalVariableItem = importHandleParam.getVariableItems().stream().filter(e -> Util.formatMultiLang(e.getName(), String.valueOf(user.getLanguage())).equals(key)).findFirst(); if (optionalVariableItem.isPresent()) { VariableItemPO variableItemPO = optionalVariableItem.get(); // 数值类型判断 boolean isNotNumber = variableItemPO.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); isError = true; } Long variableItemId = variableItemPO.getId(); // 已生效 List effectiveList = Optional.ofNullable(importHandleParam.getEffectiveItemListMap().get(finalVariableArchive.getId() + "-" + variableItemId)).orElse(Lists.newArrayList()); // 先删除后新增 needDelArchiveItemIds.addAll(effectiveList.stream().map(VariableArchiveItemPO::getId).collect(Collectors.toList())); // 导入时不需要处理的项目 boolean isInitNull = CollectionUtils.isEmpty(effectiveList) && StringUtils.isEmpty(cellVal); if (!isError && !isInitNull && StringUtils.isNotBlank(cellVal)) { importHandleParam.getVariableArchiveItemSaves().add(VariableArchiveItemPO.builder() .id(IdGenerator.generate()) .employeeId(finalVariableArchive.getEmployeeId()) .variableArchiveId(finalVariableArchive.getId()) .variableItemId(variableItemId) .itemValue(cellVal) .creator(importHandleParam.getCurrentEmployeeId()) .createTime(importHandleParam.getNowTime()) .updateTime(importHandleParam.getNowTime()) .deleteType(NumberUtils.INTEGER_ZERO) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .build()); } } } } } // 如果当前校验行没问题,修改起始发薪日期和最终发薪日期等 if (isError) { // 将前面添加好的数据给过滤掉 importHandleParam.setVariableArchiveSaves(importHandleParam.getVariableArchiveSaves().stream().filter(f -> !finalVariableArchive.getId().equals(f.getId())).collect(Collectors.toList())); importHandleParam.setVariableArchiveItemSaves(importHandleParam.getVariableArchiveItemSaves().stream().filter(f -> !finalVariableArchive.getId().equals(f.getVariableArchiveId())).collect(Collectors.toList())); } else { importHandleParam.getVariableArchiveItemDelSalaryItemIds().addAll(needDelArchiveItemIds); } return isError; } /** * 构建浮动薪资档案对象 * * @param employeeId * @param taxAgentId * @param importHandleParam * @return */ public static VariableArchivePO buildVariableArchive(Long employeeId, Long taxAgentId, VariableArchiveImportHandleParam importHandleParam) { VariableArchivePO variableArchivePO = importHandleParam.getVariableArchivesMap().get(taxAgentId + "-" + employeeId); if (variableArchivePO == null) { // 新增浮动档案 variableArchivePO = VariableArchivePO.builder() .id(IdGenerator.generate()) .employeeId(employeeId) .taxAgentId(taxAgentId) .salaryMonth(importHandleParam.getSalaryMonthDate()) .createTime(importHandleParam.getNowTime()) .updateTime(importHandleParam.getNowTime()) .creator(importHandleParam.getCurrentEmployeeId()) .deleteType(NumberUtils.INTEGER_ZERO) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .build(); importHandleParam.getVariableArchiveSaves().add(variableArchivePO); } return variableArchivePO; } @Override public String toString() { return "SalaryArchiveExcelBO{}"; } }