package com.engine.salary.service.impl; import com.cloudstore.dev.api.util.Util_DataCache; import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; import com.engine.hrmelog.entity.dto.LoggerContext; import com.engine.salary.biz.*; import com.engine.salary.common.LocalDateRange; import com.engine.salary.component.WeaTableColumnGroup; import com.engine.salary.config.SalaryElogConfig; import com.engine.salary.constant.SalaryDefaultTenantConstant; import com.engine.salary.constant.SalaryItemConstant; import com.engine.salary.entity.datacollection.AddUpSituation; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.salaryarchive.bo.SalaryArchiveBO; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveListDTO; import com.engine.salary.entity.salaryarchive.param.*; import com.engine.salary.entity.salaryarchive.po.SalaryArchiveDimissionPO; import com.engine.salary.entity.salaryarchive.po.SalaryArchiveItemPO; import com.engine.salary.entity.salaryarchive.po.SalaryArchivePO; import com.engine.salary.entity.salaryarchive.po.SalaryArchiveTaxAgentPO; import com.engine.salary.entity.salaryitem.po.SalaryItemPO; import com.engine.salary.entity.taxagent.dto.TaxAgentEmployeeDTO; import com.engine.salary.entity.taxagent.dto.TaxAgentManageRangeEmployeeDTO; import com.engine.salary.entity.taxagent.po.TaxAgentEmpChangePO; import com.engine.salary.entity.taxagent.po.TaxAgentPO; import com.engine.salary.enums.OperateTypeEnum; import com.engine.salary.enums.UserStatusEnum; import com.engine.salary.enums.datacollection.UseEmployeeTypeEnum; import com.engine.salary.enums.salaryarchive.*; import com.engine.salary.enums.salaryitem.SalaryDataTypeEnum; import com.engine.salary.enums.taxagent.TaxAgentEmpChangeModuleEnum; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.mapper.archive.SalaryArchiveItemMapper; import com.engine.salary.mapper.archive.SalaryArchiveMapper; import com.engine.salary.service.*; import com.engine.salary.sys.constant.SalarySysConstant; import com.engine.salary.sys.entity.po.SalarySysConfPO; import com.engine.salary.sys.entity.vo.OrderRuleVO; import com.engine.salary.sys.enums.OpenEnum; import com.engine.salary.sys.enums.SalaryAcctEmployeeRuleEnum; import com.engine.salary.sys.service.SalarySysConfService; import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.SalaryI18nUtil; import com.engine.salary.util.db.IdGenerator; import com.engine.salary.util.db.MapperProxyFactory; import com.engine.salary.util.excel.ExcelParseHelper; import com.engine.salary.util.excel.ExcelSupport; import com.engine.salary.util.excel.ExcelUtilPlus; import com.engine.salary.util.page.PageInfo; import com.engine.salary.util.page.SalaryPageUtil; import com.engine.salary.util.valid.ValidUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.time.DateUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.util.IOUtils; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.BeanUtils; import org.springframework.transaction.annotation.Transactional; import weaver.file.ImageFileManager; import weaver.general.Util; import weaver.hrm.User; import java.io.InputStream; import java.math.BigDecimal; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; import java.util.stream.Collectors; import static com.engine.salary.util.excel.ExcelSupport.EXCEL_TYPE_XLSX; /** * 薪资档案 *

Copyright: Copyright (c) 2022

*

Company: 泛微软件

* * @author qiantao * @version 1.0 **/ @Slf4j public class SalaryArchiveServiceImpl extends Service implements SalaryArchiveService { private SalaryArchiveBiz salaryArchiveMapper = new SalaryArchiveBiz(); private SalaryArchiveItemBiz salaryArchiveItemMapper = new SalaryArchiveItemBiz(); private SalaryArchiveTaxAgentBiz salaryArchiveTaxAgentMapper = new SalaryArchiveTaxAgentBiz(); private SalaryArchiveDimissionBiz salaryArchiveDimissionMapper = new SalaryArchiveDimissionBiz(); private SalaryItemBiz salaryItemMapper = new SalaryItemBiz(); private TaxAgentService getTaxAgentService(User user) { return ServiceUtil.getService(TaxAgentServiceImpl.class, user); } private SalaryArchiveMapper getSalaryArchiveMapper() { return MapperProxyFactory.getProxy(SalaryArchiveMapper.class); } private SalaryArchiveItemMapper getSalaryArchiveItemMapper() { return MapperProxyFactory.getProxy(SalaryArchiveItemMapper.class); } private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) { return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user); } private SalarySysConfService getSalarySysConfService(User user) { return ServiceUtil.getService(SalarySysConfServiceImpl.class, user); } private SalaryEmployeeService getSalaryEmployeeService(User user) { return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user); } private TaxAgentEmpChangeService getTaxAgentEmpChangeService(User user) { return ServiceUtil.getService(TaxAgentEmpChangeServiceImpl.class, user); } private SalaryArchiveItemService getSalaryArchiveItemService(User user) { return ServiceUtil.getService(SalaryArchiveItemServiceImpl.class, user); } public SalarySobService getSalarySobService(User user) { return ServiceUtil.getService(SalarySobServiceImpl.class, user); } @Override public SalaryArchivePO getById(Long salaryArchiveId) { return salaryArchiveMapper.getById(salaryArchiveId); } @Override public List listSome(SalaryArchivePO po) { Collection ids = po.getIds(); if (CollectionUtils.isNotEmpty(ids)) { List list = new ArrayList<>(); List> partition = Lists.partition((List) ids, 1000); partition.forEach(idss -> { po.setIds(idss); list.addAll(getSalaryArchiveMapper().listSome(po)); }); return list; } Collection employeeIds = po.getEmployeeIds(); if (CollectionUtils.isNotEmpty(employeeIds)) { List list = new ArrayList<>(); List> partition = Lists.partition((List) employeeIds, 1000); partition.forEach(emps -> { po.setEmployeeIds(emps); list.addAll(getSalaryArchiveMapper().listSome(po)); }); return list; } // 获取薪资档案数据 return getSalaryArchiveMapper().listSome(po); } @Override public List getSalaryArchiveList(SalaryArchiveQueryParam queryParam) { if (queryParam.isExtSalaryArchiveList()) { return getSalaryArchiveMapper().listExtSalaryArchive(queryParam); } if (StringUtils.isNotBlank(queryParam.getPayStartDateStartDateStr())) { queryParam.setPayStartDateStartDate(SalaryDateUtil.stringToDate(queryParam.getPayStartDateStartDateStr())); } if (Objects.nonNull(queryParam.getPayStartDateEndDateStr())) { queryParam.setPayStartDateEndDate(SalaryDateUtil.stringToDate(queryParam.getPayStartDateEndDateStr())); } if (StringUtils.isNotBlank(queryParam.getPayEndDateStartDateStr())) { queryParam.setPayEndDateStartDate(SalaryDateUtil.stringToDate(queryParam.getPayEndDateStartDateStr())); } if (Objects.nonNull(queryParam.getPayEndDateEndDateStr())) { queryParam.setPayEndDateEndDate(SalaryDateUtil.stringToDate(queryParam.getPayEndDateEndDateStr())); } List list = getSalaryArchiveMapper().list(queryParam); // 过滤调薪日期 if (queryParam.getAdjustSalaryStartDate() != null || queryParam.getAdjustSalaryEndDate() != null) { List salaryArchiveIds = list.stream().map(SalaryArchiveListDTO::getId).collect(Collectors.toList()); LocalDateRange dateRange = LocalDateRange.builder().fromDate(queryParam.getAdjustSalaryStartDate()).endDate(queryParam.getAdjustSalaryEndDate()).build(); List salaryArchiveItemPOList = getSalaryArchiveItemService(user).listByArchiveIdAndEffectiveTime(salaryArchiveIds, dateRange); List archiveIds = salaryArchiveItemPOList.stream().map(SalaryArchiveItemPO::getSalaryArchiveId).distinct().collect(Collectors.toList()); list = list.stream().filter(dto -> archiveIds.contains(dto.getId())).collect(Collectors.toList()); } return SalaryI18nUtil.i18nList(list); } @Override public PageInfo listPage(SalaryArchiveQueryParam queryParam) { long currentEmployeeId = user.getUID(); /** * 异步处理档案数据 */ String handleable = Util.null2String(Util_DataCache.getObjVal("salaryArchiveHandleable")); if ((StringUtils.isBlank(handleable) || OpenEnum.OPEN.getValue().equals(handleable)) && !queryParam.isExtSalaryArchiveList()) { new Thread() { public void run() { Util_DataCache.setObjVal("salaryArchiveHandleable", "0"); // 1.历史数据处理 handleHistory(currentEmployeeId); // 2.待停薪自动处理 handleSuspendData(currentEmployeeId); // 3.增量数据处理 // handleChangeData(currentEmployeeId); Util_DataCache.setObjVal("salaryArchiveHandleable", "1"); } }.start(); } Boolean needAuth = getTaxAgentService(user).isNeedAuth(currentEmployeeId); //排序配置 OrderRuleVO orderRule = getSalarySysConfService(user).orderRule(); queryParam.setOrderRule(orderRule); List list = getSalaryArchiveList(queryParam); list = list.stream() //过滤档案状态 .filter(dto -> { if (StringUtils.isNotBlank(queryParam.getArchiveStatus())) { return StringUtils.equals(queryParam.getArchiveStatus(), dto.getArchiveStatus()); } return true; }) .collect(Collectors.toList()); if (needAuth) { Boolean adminEnable = getTaxAgentService(user).isAdminEnable(currentEmployeeId); //不是管理员看不到数据,返回空 if (!adminEnable) { PageInfo pageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), SalaryArchiveListDTO.class); return pageInfo; } // 获取作为管理员的所有个税扣缴义务人列表 Collection taxAgentPOS = getTaxAgentService(user).listAllTaxAgentsAsAdmin(currentEmployeeId); Set taxAgentIds = SalaryEntityUtil.properties(taxAgentPOS, TaxAgentPO::getId); list = list.stream().filter(dto -> taxAgentIds.contains(dto.getTaxAgentId())).collect(Collectors.toList()); } PageInfo pageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), SalaryArchiveListDTO.class); pageInfo.setTotal(list.size()); pageInfo.setList(SalaryPageUtil.subList(queryParam.getCurrent(), queryParam.getPageSize(), list)); return pageInfo; } /** * 1、员工的人事状态属性从在职变成非在职,且在【发薪员工】里,则自动进入【待停薪】; * 2、若维护了最后发薪日大于当前日期,会自动清除该员工的待办数据; * 3、个税扣缴义务人发生调整的发薪员工自动进入【待停薪】; *

* 1.【发薪员工】中,员工的人事状态属性从在职变成非在职,则自动进入【待停薪】; * 2.【定薪员工】中,如果维护了最后发薪日且大于今天的,自动清除待停薪,如果小于等于今天的则自动进入待停薪 * * @param currentEmployeeId */ @Transactional(rollbackFor = Exception.class) public void handleSuspendData(Long currentEmployeeId) { List personnelStatuss = new ArrayList() {{ add("4"); add("5"); add("6"); }}; // 1.定薪员工非在职 if (CollectionUtils.isNotEmpty(personnelStatuss)) { SalaryArchiveQueryParam queryParam = SalaryArchiveQueryParam.builder() // 离职 .personnelStatuss(personnelStatuss) // 定薪列表 .runStatusList(Collections.singletonList(SalaryArchiveStatusEnum.FIXED.getValue())) .build(); List noNormalList = getSalaryArchiveList(queryParam); if (CollectionUtils.isNotEmpty(noNormalList)) { List idList = noNormalList.stream().map(SalaryArchiveListDTO::getId).collect(Collectors.toList()); List> partition = Lists.partition(idList, 999); partition.forEach(part -> getSalaryArchiveMapper().updateRunStatusByIdsAndPayEndDate(SalaryArchivePO.builder().ids(part).runStatus(SalaryArchiveStatusEnum.SUSPEND.getValue()).build()) ); } } Date today = new Date(); // 2.定薪员工维护了最后发薪日,且大于今天的,自动清除待停薪 getSalaryArchiveMapper().updateFixed(SalaryArchivePO.builder().payEndDate(today).build()); // 3.定薪员工维护了最后发薪日,且小于等于今天的,自动进入待停薪 getSalaryArchiveMapper().updateSuspend(SalaryArchivePO.builder().payEndDate(today).build()); } /** * 处理增量数据 * * @param currentEmployeeId */ public void handleChangeData(Long currentEmployeeId) { // 所有增量人员列表 List taxAgentEmpChangeList = getTaxAgentEmpChangeService(user).listAllByModule(TaxAgentEmpChangeModuleEnum.SALARY_ARCHIVE); if (CollectionUtils.isEmpty(taxAgentEmpChangeList)) { return; } // 当前可以管辖的人员 Collection taxAgentList = new ArrayList<>(); if (currentEmployeeId != 1L) { taxAgentList = getTaxAgentService(user).listAllTaxAgents(currentEmployeeId); Collection finalTaxAgentList = taxAgentList; taxAgentEmpChangeList = taxAgentEmpChangeList.stream().filter(f -> finalTaxAgentList.stream().anyMatch(e -> e.getId().equals(f.getTaxAgentId()))).collect(Collectors.toList()); if (CollectionUtils.isEmpty(taxAgentEmpChangeList)) { return; } } // 所有档案数据 List salaryArchiveList = getSalaryArchiveMapper().listAll(); // 获取所有可被引用的薪资项目 List salaryItems = salaryItemMapper.getCanAdjustSalaryItems(); Collection salaryItemIds = salaryItems.stream().map(SalaryItemPO::getId).collect(Collectors.toList()); // 获取薪资档案所对应的当前生效的薪资项目数据 List salaryArchiveItemList = getCurrentEffectiveItemList(Lists.newArrayList(), salaryItemIds); /** 增量处理 start ***/ SalaryArchiveBO.ChangeData changeData = SalaryArchiveBO.buildChangeData(taxAgentEmpChangeList, salaryArchiveList, salaryArchiveItemList, currentEmployeeId); // 批量修改薪资档案 if (CollectionUtils.isNotEmpty(changeData.getSalaryArchiveUpdateTodoList())) { salaryArchiveMapper.batchUpdate(changeData.getSalaryArchiveUpdateTodoList()); } // 批量新增薪资档案 if (CollectionUtils.isNotEmpty(changeData.getSalaryArchiveAddTodoList())) { salaryArchiveMapper.batchInsert(changeData.getSalaryArchiveAddTodoList()); } // 落库处理薪资项目 if (CollectionUtils.isNotEmpty(changeData.getSalaryArchiveItemAddTodos())) { salaryArchiveItemMapper.batchInsert(changeData.getSalaryArchiveItemAddTodos(), user); } // 删除增量数据 if (CollectionUtils.isNotEmpty(changeData.getChangeIds())) { getTaxAgentEmpChangeService(user).deleleByIds(changeData.getChangeIds()); } /** 增量处理 end ***/ } @Override public void deleteSalaryArchive(Collection salaryArchiveIds) { if (CollectionUtils.isEmpty(salaryArchiveIds)) { throw new SalaryRunTimeException("薪资档案参数为空!"); } SalarySysConfPO canDelete = getSalarySysConfService(user).getOneByCode(SalarySysConstant.SALARY_ARCHIVE_DELETE); if (Objects.isNull(canDelete) || StringUtils.equals(canDelete.getConfValue(), "0")) { throw new SalaryRunTimeException("不允许删除薪资档案,请先开启删除档案规则配置!"); } List salaryArchiveList = getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().ids(salaryArchiveIds).build()); //查询当前登录人员管理的个税扣缴义务人 List canDeleteTaxAgentIds = getTaxAgentService(user).listAllTaxAgentsAsAdmin((long) user.getUID()) .stream().map(TaxAgentPO::getId).collect(Collectors.toList()); boolean err = salaryArchiveList.stream().anyMatch(po -> !canDeleteTaxAgentIds.contains(po.getTaxAgentId())); if (CollectionUtils.isEmpty(salaryArchiveList) || err) { throw new SalaryRunTimeException("薪资档案不存在,或没有权限删除该薪资档案!"); } Optional fixedList = salaryArchiveList.stream().filter(archive -> !StringUtils.equals(archive.getRunStatus(), SalaryArchiveStatusEnum.PENDING.getValue()) && !StringUtils.equals(archive.getRunStatus(), SalaryArchiveStatusEnum.STOP_FROM_PENDING.getValue())).findFirst(); if (fixedList.isPresent()) { throw new SalaryRunTimeException("发薪员工、待停薪员工、停薪_来自待停薪,无法删除薪资档案!"); } List deleteIds = salaryArchiveList.stream().map(SalaryArchivePO::getId).collect(Collectors.toList()); // 删除薪资档案及档案项目 if (CollectionUtils.isNotEmpty(deleteIds)) { getSalaryArchiveMapper().deleteByIds(deleteIds); getSalaryArchiveItemMapper().deleteBySalaryArchiveId(deleteIds); } } @Override public List list(SalaryArchiveQueryParam queryParam) { long currentEmployeeId = user.getUID(); //排序配置 OrderRuleVO orderRule = getSalarySysConfService(user).orderRule(); queryParam.setOrderRule(orderRule); Boolean needAuth = getTaxAgentService(user).isNeedAuth(currentEmployeeId); if (needAuth) { Boolean adminEnable = getTaxAgentService(user).isAdminEnable(currentEmployeeId); //不是管理员看不到数据,返回空 if (!adminEnable) { return new ArrayList<>(); } //获取管理的人员范围 List taxAgentEmployeeDTOS = getTaxAgentService(user).listTaxAgentAndEmployee(currentEmployeeId); Set employeeId = SalaryEntityUtil.properties(taxAgentEmployeeDTOS, TaxAgentEmployeeDTO::getEmployeeId); Collection taxAgentPOS = getTaxAgentService(user).listAllTaxAgentsAsAdmin(currentEmployeeId); Set taxAgentIds = SalaryEntityUtil.properties(taxAgentPOS, TaxAgentPO::getId); //获取所有薪资档案 List list = getSalaryArchiveList(queryParam); List finalAllArchive = list.stream().filter(dto -> employeeId.contains(dto.getEmployeeId()) && taxAgentIds.contains(dto.getTaxAgentId())).collect(Collectors.toList()); return finalAllArchive; } else { return getSalaryArchiveList(queryParam); } } /** * 获取薪资档案对应的当前生效的薪资项目 * * @param salaryArchivesIds * @return */ @Override public List getCurrentEffectiveItemList(Collection salaryArchivesIds, Collection salaryItemIds) { if (CollectionUtils.isEmpty(salaryItemIds)) { return Collections.EMPTY_LIST; } List salaryArchiveItems = salaryArchiveItemMapper.getCurrentEffectiveItemList(SalaryArchiveItemQueryParam.builder().salaryArchivesIds(salaryArchivesIds).salaryItemIds(salaryItemIds).effectiveTime(new Date()).build()); return salaryArchiveItems.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getSalaryArchiveId() + "-" + f.getSalaryItemId()))), ArrayList::new)); } /** * 获取薪资档案对应的当前生效的个税扣缴义务人 * * @param salaryArchivesIds * @return */ @Override public List getCurrentEffectiveTaxAgentList(Collection salaryArchivesIds) { if (CollectionUtils.isEmpty(salaryArchivesIds)) { return Collections.EMPTY_LIST; } List salaryArchiveTaxAgents = salaryArchiveTaxAgentMapper.listByParam(SalaryArchiveTaxAgentQueryParam.builder().salaryArchivesIds(salaryArchivesIds).effectiveTime(new Date()).build()); return salaryArchiveTaxAgents.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SalaryArchiveTaxAgentPO::getSalaryArchiveId))), ArrayList::new)); } /** * 构建薪资档案数据 * * @param salaryArchives * @param taxAgentLists * @param salaryItems * @param isPage * @return */ @Override public List> buildSalaryArchiveData(Collection salaryArchives, Collection taxAgentLists, List salaryItems, Boolean isPage) { // 分页用于表格展示,否则用于导出 Collection ids = isPage ? salaryArchives.stream().map(SalaryArchiveListDTO::getId).collect(Collectors.toList()) : CollectionUtils.emptyCollection(); List salaryItemIds = salaryItems.stream().map(SalaryItemPO::getId).collect(Collectors.toList()); // 1.获取薪资档案所对应的当前生效的薪资项目数据 List salaryArchiveItemList = Collections.emptyList(); if (CollectionUtils.isNotEmpty(ids) && CollectionUtils.isNotEmpty(salaryItemIds) || !isPage) { salaryArchiveItemList = getCurrentEffectiveItemList(ids, salaryItemIds); } List finalSalaryArchiveItemList = salaryArchiveItemList; List> salaryArchiveItemData = salaryArchives.stream().map(m -> { Map map = Maps.newHashMap(); map.put("salaryArchiveId", m.getId()); map.put("archiveStatus", m.getArchiveStatus()); List salaryArchiveItemValuelList = finalSalaryArchiveItemList.stream().filter(i -> i.getSalaryArchiveId().equals(m.getId())).collect(Collectors.toList()); salaryArchiveItemValuelList.forEach(i -> { map.put(i.getSalaryItemId() + SalaryItemConstant.DYNAMIC_SUFFIX, i.getItemValue()); }); return map; }).collect(Collectors.toList()); //2.获取薪资档案所对应的当前生效的个税扣缴义务人列表 // List taxAgentList = getCurrentEffectiveTaxAgentList(ids); // List> taxAgentData = taxAgentList.stream().map(m -> { // Map map = Maps.newHashMap(); // map.put("salaryArchiveId", m.getSalaryArchiveId()); // map.put("taxAgentId", m.getTaxAgentId()); // Optional optional = taxAgentLists.stream().filter(f -> f.getId().equals(m.getTaxAgentId())).findFirst(); // map.put("taxAgentName", optional.isPresent() ? optional.get().getName() : ""); // map.put("taxAgentEffectiveTime", m.getEffectiveTime()); // return map; // }).collect(Collectors.toList()); Map longTaxAgentPOMap = SalaryEntityUtil.convert2Map(taxAgentLists, TaxAgentPO::getId); // 3.组装数据 List> listMaps = new ArrayList<>(); salaryArchives.forEach(e -> { e.setEmployeeStatus(NumberUtils.isCreatable(e.getEmployeeStatus()) ? UserStatusEnum.getDefaultLabelByValue(Integer.parseInt(e.getEmployeeStatus())) : ""); Map map = new LinkedHashMap<>(); map.put("id", e.getId()); map.put("username", e.getUsername()); map.put("employeeId", e.getEmployeeId()); // Optional> optionalTaxAgent = taxAgentData.stream().filter(f -> f.get("salaryArchiveId").toString().equals(e.getId().toString())).findFirst(); TaxAgentPO taxAgentPO = longTaxAgentPOMap.get(e.getTaxAgentId()); map.put("taxAgentName", Optional.ofNullable(taxAgentPO).map(TaxAgentPO::getName).orElse("")); map.put("taxAgentId", Optional.ofNullable(taxAgentPO).map(TaxAgentPO::getId).orElse(0L)); // map.put("taxAgentEffectiveTime", optionalTaxAgent.isPresent() ? optionalTaxAgent.get().get("taxAgentEffectiveTime") : ""); map.put("subcompanyName", e.getSubcompanyName()); map.put("departmentName", e.getDepartmentName()); map.put("mobile", e.getMobile()); map.put("workcode", e.getWorkcode()); map.put("idNo", e.getIdNo()); map.put("employeeStatus", e.getEmployeeStatus()); map.put("payStartDate", SalaryDateUtil.getFormatLocalDate(e.getPayStartDate())); map.put("payEndDate", SalaryDateUtil.getFormatLocalDate(e.getPayEndDate())); map.put("companystartdate", e.getCompanystartdate()); map.put("dismissdate", e.getDismissdate()); // 薪资项目动态 Optional> optionalItem = salaryArchiveItemData.stream().filter(f -> f.get("salaryArchiveId").toString().equals(e.getId().toString())).findFirst(); optionalItem.ifPresent(map::putAll); listMaps.add(map); }); return listMaps; } @Override public XSSFWorkbook exportList(SalaryArchiveQueryParam queryParam) { long employeeId = user.getUID(); // 1.工作簿名称 String sheetName = SalaryI18nUtil.getI18nLabel(85368, "薪资档案"); // 获取所有可被引用的薪资项目 List salaryItems = salaryItemMapper.getCanAdjustSalaryItems(); Object[] header = { new WeaTableColumnGroup("150px", SalaryI18nUtil.getI18nLabel(85429, "姓名"), "", "", 0), new WeaTableColumnGroup("150px", SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"), "", "", 0), new WeaTableColumnGroup("150px", SalaryI18nUtil.getI18nLabel(86185, "部门"), "", "", 0), new WeaTableColumnGroup("150px", SalaryI18nUtil.getI18nLabel(86176, "工号"), "", "", 0), new WeaTableColumnGroup("150px", SalaryI18nUtil.getI18nLabel(86186, "手机号"), "", "", 0), new WeaTableColumnGroup("150px", SalaryI18nUtil.getI18nLabel(86186, "证件号码"), "", "", 0), new WeaTableColumnGroup("150px", SalaryI18nUtil.getI18nLabel(15890, "员工状态"), "", "", 0), new WeaTableColumnGroup("150px", SalaryI18nUtil.getI18nLabel(91075, "起始发薪日期"), "", "", 0), new WeaTableColumnGroup("150px", SalaryI18nUtil.getI18nLabel(91075, "最后发薪日期"), "", "", 0) }; // 2.表头 List headerList = new ArrayList<>(Arrays.asList(header)); for (SalaryItemPO salaryItem : salaryItems) { headerList.add(new WeaTableColumnGroup("150px", salaryItem.getName(), "", "", salaryItem.getPattern())); } // 获取所有个税扣缴义务人 Collection taxAgentList = getTaxAgentService(user).listAll(); //获取管理的人员范围 List taxAgentEmployeeDTOS = getTaxAgentService(user).listTaxAgentAndEmployeeTree(employeeId); Map> taxAgentEmployeesMap = SalaryEntityUtil.convert2Map(taxAgentEmployeeDTOS, TaxAgentManageRangeEmployeeDTO::getTaxAgentId, TaxAgentManageRangeEmployeeDTO::getEmployeeList); //排序配置 OrderRuleVO orderRule = getSalarySysConfService(user).orderRule(); queryParam.setOrderRule(orderRule); Collection salaryArchives = getSalaryArchiveList(queryParam); //分权 Boolean needAuth = getTaxAgentService(user).isNeedAuth(employeeId); if (needAuth) { Boolean adminEnable = getTaxAgentService(user).isAdminEnable(employeeId); if (!adminEnable) { salaryArchives = new ArrayList<>(); } else { Collection taxAgentPOS = getTaxAgentService(user).listAllTaxAgentsAsAdmin((long) user.getUID()); Set taxAgentIds = SalaryEntityUtil.properties(taxAgentPOS, TaxAgentPO::getId); //获取管理扣缴单位薪资档案 salaryArchives = salaryArchives.stream().filter(dto -> taxAgentIds.contains(dto.getTaxAgentId())).collect(Collectors.toList()); //过滤档案状态 if (StringUtils.isNotBlank(queryParam.getArchiveStatus())) { //过滤档案状态 salaryArchives = salaryArchives.stream().filter(dto -> StringUtils.equals(queryParam.getArchiveStatus(), dto.getArchiveStatus())).collect(Collectors.toList()); } } } List> listMaps = buildSalaryArchiveData(salaryArchives, taxAgentList, salaryItems, Boolean.FALSE); // 组装数据 List> rows = new ArrayList<>(); rows.add(headerList); listMaps.forEach(e -> { List row = new ArrayList<>(); row.add(Util.null2String(e.get("username"))); row.add(Util.null2String(e.get("taxAgentName"))); row.add(Util.null2String(e.get("departmentName"))); row.add(Util.null2String(e.get("workcode"))); row.add(Util.null2String(e.get("mobile"))); row.add(Util.null2String(e.get("idNo"))); row.add(Util.null2String(e.get("employeeStatus"))); row.add(Util.null2String(e.get("payStartDate"))); row.add(Util.null2String(e.get("payEndDate"))); // 薪资项目数据 for (SalaryItemPO salaryItem : salaryItems) { try { if (salaryItem.getDataType().equals(SalaryDataTypeEnum.NUMBER.getValue())) { row.add(new BigDecimal(e.containsKey(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) ? (e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) == null ? "" : e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX).toString()) : "")); } else { row.add(e.containsKey(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) ? (e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) == null ? "" : e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX).toString()) : ""); } } catch (Exception ex) { row.add(e.containsKey(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) ? (e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) == null ? "" : e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX).toString()) : ""); } } rows.add(row); }); // 3.表数据 // return ExcelUtil.genWorkbookV2(rows, sheetName); // 记录日志 String statusStr = StringUtils.join(queryParam.getRunStatusList().stream().map(status -> SalaryArchiveStatusEnum.parseByValue(status).getDefaultLabel()).collect(Collectors.toList()), ","); String name = SalaryI18nUtil.getI18nLabel(0, "导出"); LoggerContext loggerContext = new LoggerContext<>(); loggerContext.setTargetName(SalaryI18nUtil.getI18nLabel(0, "薪资档案 ") + statusStr); loggerContext.setOperateType(OperateTypeEnum.EXCEL_EXPORT.getValue()); loggerContext.setOperateTypeName(name); loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "薪资档案") + "-" + name); loggerContext.setUser(user); SalaryElogConfig.salaryArchiveLoggerTemplate.write(loggerContext); return ExcelUtilPlus.genWorkbookV2WithPattern(rows, sheetName, false); } @Override public String savePaySet(SalaryArchiveSetPaySaveParam saveParam) { long currentEmployeeId = user.getUID(); if (saveParam.getStatus() == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109201, "状态不能为空")); } Boolean enableStatus = saveParam.getStatus().equals(SalaryArchiveStatusEnum.PENDING) || saveParam.getStatus().equals(SalaryArchiveStatusEnum.FIXED) || saveParam.getStatus().equals(SalaryArchiveStatusEnum.SUSPEND); if (!enableStatus) { return StringUtils.EMPTY; } if (saveParam.getSalaryArchiveId() == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100425, "薪资档案id不能为空")); } SalaryArchivePO salaryArchive = getById(saveParam.getSalaryArchiveId()); if (salaryArchive == null) { throw new SalaryRunTimeException(String.format(SalaryI18nUtil.getI18nLabel(100463, "薪资档案不存在") + "[id:%s]", saveParam.getSalaryArchiveId())); } SalaryArchivePO oldSalaryArchive = new SalaryArchivePO(); BeanUtils.copyProperties(salaryArchive, oldSalaryArchive); List oldList = Collections.singletonList(oldSalaryArchive); // 收入所得项目 // boolean checkIncomeCategory = saveParam.getIncomeCategory() == null || StringUtils.isEmpty(SalaryArchiveBO.getIncomeCategoryByValue(saveParam.getIncomeCategory())); // if (checkIncomeCategory) { // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(122085, "收入所得项目不能为空或不存在")); // } else { // salaryArchive.setIncomeCategory(saveParam.getIncomeCategory()); // } // 薪资账套 // if (CollectionUtils.isEmpty(saveParam.getSalarySobIds())) { // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(122217, "薪资账套不能为空")); // } // 待定薪 if (saveParam.getStatus().equals(SalaryArchiveStatusEnum.PENDING)) { if (saveParam.getPayStartDate() == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109202, "起始发薪日期不能为空")); } // 起薪日期:新人入职默认为:入职日期;返聘人员默认为:返聘开始日期;调整个税扣缴义务人:不默认日期 salaryArchive.setPayStartDate(saveParam.getPayStartDate()); if (saveParam.getPayEndDate() != null) { if (saveParam.getPayStartDate().after(saveParam.getPayEndDate())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109214, "起始发薪日期不可晚于最后发薪日")); } } salaryArchive.setPayEndDate(saveParam.getPayEndDate()); // 处理薪资项目 if (CollectionUtils.isNotEmpty(saveParam.getSalaryArchiveItems())) { // 获取所有可被引用的薪资项目 List salaryItems = getSalaryArchiveItemService(user).getCanAdjustSalaryItems(); Collection salaryItemIds = salaryItems.stream().map(SalaryItemPO::getId).collect(Collectors.toList()); // 待处理薪资项目 List salaryArchiveItems = saveParam.getSalaryArchiveItems().stream().filter(e -> salaryItemIds.contains(e.getSalaryItemId())).collect(Collectors.toList()); List salaryItemExistIds = salaryArchiveItems.stream().map(SalaryArchiveItemDetailSaveParam::getSalaryItemId).collect(Collectors.toList()); // 获取薪资档案所对应的当前生效的薪资项目数据 List salaryArchiveItemCurrentList = getSalaryArchiveItemService(user).getCurrentEffectiveItemList(Collections.singletonList(saveParam.getSalaryArchiveId()), salaryItemExistIds); List salaryArchiveItemAddTodos = Lists.newArrayList(); List salaryArchiveItemDelTodoIds = Lists.newArrayList(); Date now = new Date(); salaryArchiveItems.forEach(f -> { Optional optional = salaryItems.stream().filter(i -> i.getId().equals(f.getSalaryItemId())).findFirst(); if (optional.isPresent()) { SalaryItemPO salaryItemPO = optional.get(); boolean isNotNumber = salaryItemPO.getDataType().equals(SalaryArchiveFieldTypeEnum.NUMBER.getValue()) && StringUtils.isNotEmpty(f.getAdjustValue()) && !Pattern.matches(SalaryEntityUtil.NUMBER_REGEX, f.getAdjustValue()); if (isNotNumber) { throw new SalaryRunTimeException(salaryItemPO.getName() + ":" + SalaryI18nUtil.getI18nLabel(100581, "请输入数字")); } } Optional optionalSAI = salaryArchiveItemCurrentList.stream().filter(c -> c.getSalaryArchiveId().equals(saveParam.getSalaryArchiveId()) && c.getSalaryItemId().equals(f.getSalaryItemId()) ).findFirst(); if (StringUtils.isNotEmpty(f.getAdjustValue())) { salaryArchiveItemAddTodos.add(SalaryArchiveItemPO.builder() .id(IdGenerator.generate()) .salaryArchiveId(salaryArchive.getId()) .employeeId(salaryArchive.getEmployeeId()) .effectiveTime(saveParam.getPayStartDate()) .adjustReason(SalaryArchiveItemAdjustReasonEnum.INIT.getValue()) .salaryItemId(f.getSalaryItemId()) .itemValue(f.getAdjustValue()) .description("") .operator(currentEmployeeId) .operateTime(now) .createTime(now) .updateTime(now) .creator(currentEmployeeId) .deleteType(NumberUtils.INTEGER_ZERO) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .build()); } optionalSAI.ifPresent(salaryArchiveItemPO -> salaryArchiveItemDelTodoIds.add(salaryArchiveItemPO.getId())); }); // 落库处理薪资档案项目数据 if (CollectionUtils.isNotEmpty(salaryArchiveItemAddTodos)) { salaryArchiveItemMapper.batchInsert(salaryArchiveItemAddTodos, user); } if (CollectionUtils.isNotEmpty(salaryArchiveItemDelTodoIds)) { salaryArchiveItemMapper.deleteBatchIds(salaryArchiveItemDelTodoIds); } } // 定薪 } else if (saveParam.getStatus().equals(SalaryArchiveStatusEnum.FIXED)) { if (saveParam.getPayStartDate() == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109202, "起始发薪日期不能为空")); } salaryArchive.setPayStartDate(saveParam.getPayStartDate()); if (saveParam.getPayEndDate() != null) { if (saveParam.getPayStartDate().after(saveParam.getPayEndDate())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109214, "起始发薪日期不可晚于最后发薪日")); } } salaryArchive.setPayEndDate(saveParam.getPayEndDate()); //如果是非系统人员,需要将起始发薪日期初始化 if (Objects.equals(salaryArchive.getEmployeeType(), 1)) { salaryArchive.setRunStatus(SalaryArchiveStatusEnum.FIXED.getValue()); } // 待停薪 } else if (saveParam.getStatus().equals(SalaryArchiveStatusEnum.SUSPEND)) { if (saveParam.getPayEndDate() == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109203, "最后发薪日期不能为空")); } if (saveParam.getPayStartDate().after(saveParam.getPayEndDate())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109214, "起始发薪日期不可晚于最后发薪日")); } salaryArchive.setPayEndDate(saveParam.getPayEndDate()); } salaryArchive.setUpdateTime(new Date()); getSalaryArchiveMapper().update(salaryArchive); // List salarySobList = getSalarySobList(currentEmployeeId, currentTenantKey); // List salarySobIds = salarySobList.stream().map(SalarySobPO::getId).filter(id -> saveParam.getSalarySobIds().contains(id)).collect(Collectors.toList()); // List salaryArchiveSobSaveList = SalaryArchiveBO.buildSalaryArchiveSob(salaryArchive.getId(), salarySobIds, LocalDateTime.now()); // this.salaryArchiveSobService.saveBatchBySalaryArchiveIdsAndSaves(Collections.singletonList(salaryArchive.getId()), salaryArchiveSobSaveList, currentTenantKey); // 记录日志 List newList = Collections.singletonList(this.getById(salaryArchive.getId())); String operatedesc = SalaryI18nUtil.getI18nLabel(0, "发薪设置"); recordLog(oldList, newList, operatedesc); return StringUtils.EMPTY; } /** * 记录日志 * * @param oldSalaryArchiveList * @param newSalaryArchiveList * @param operatedesc */ private void recordLog(List oldSalaryArchiveList, List newSalaryArchiveList, String operatedesc) { if (CollectionUtils.isEmpty(oldSalaryArchiveList) || CollectionUtils.isEmpty(oldSalaryArchiveList)) { return; } List updateEmpIds = newSalaryArchiveList.stream().map(SalaryArchivePO::getEmployeeId).distinct().collect(Collectors.toList()); List employeeList = getSalaryEmployeeService(user).listByIds(updateEmpIds); Map empMap = SalaryEntityUtil.convert2Map(employeeList, DataCollectionEmployee::getEmployeeId, DataCollectionEmployee::getUsername); // 获取所有个税扣缴义务人 Collection taxAgents = getTaxAgentService(user).listAll(); Map taxAgentMap = SalaryEntityUtil.convert2Map(taxAgents, TaxAgentPO::getId, TaxAgentPO::getName); String bar = "-"; oldSalaryArchiveList.forEach(e -> { LoggerContext loggerContext = new LoggerContext(); loggerContext.setUser(user); loggerContext.setTargetId(String.valueOf(e.getId())); loggerContext.setTargetName( Optional.ofNullable(taxAgentMap.get(e.getTaxAgentId())).orElse(StringUtils.EMPTY) + bar + Optional.ofNullable(empMap.get(e.getEmployeeId())).orElse(StringUtils.EMPTY) ); loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue()); loggerContext.setOperateTypeName(operatedesc); loggerContext.setOperatedesc(operatedesc); loggerContext.setOldValues(e); Optional optionalNew = newSalaryArchiveList.stream().filter(n -> n.getId().equals(e.getId())).findFirst(); loggerContext.setNewValues(optionalNew.isPresent() ? optionalNew.get() : null); SalaryElogConfig.salaryArchiveLoggerTemplate.write(loggerContext); }); } @Override public List dimissionSets() { return salaryArchiveDimissionMapper.dimissionSets(); } @Override public String saveDimissionSet(SalaryArchiveDimissionSaveParam saveParam) { Date now = new Date(); List dimissionSets = dimissionSets(); if (CollectionUtils.isNotEmpty(dimissionSets)) { SalaryArchiveDimissionPO po = dimissionSets.get(0); po.setDimissionTimeInterval(saveParam.getDimissionTimeInterval().getValue()); po.setUpdateTime(now); salaryArchiveDimissionMapper.updateById(po); } else { salaryArchiveDimissionMapper.insert(SalaryArchiveDimissionPO.builder().dimissionTimeInterval(saveParam.getDimissionTimeInterval().getValue()).createTime(now).updateTime(now).creator((long) user.getUID()).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build()); } return StringUtils.EMPTY; } @Override public List getSalaryArchiveData(LocalDateRange localDateRange, Collection employeeIds, Long taxAgentId) { return getSalaryArchiveData(localDateRange, employeeIds, taxAgentId, Boolean.FALSE); } @Override public List getSalaryArchiveTaxAgentData(LocalDateRange localDateRange, Collection employeeIds, Long taxAgentId) { return getSalaryArchiveData(localDateRange, employeeIds, taxAgentId, Boolean.TRUE); } /** * 根据日期范围和人员获取薪资档案数据 * * @param localDateRange * @param employeeIds * @param isOnlyTaxAgent * @return */ private List getSalaryArchiveData(LocalDateRange localDateRange, Collection employeeIds, Long taxAgentId, boolean isOnlyTaxAgent) { // 获取核算人员规则 List statusList = Collections.emptyList(); SalarySysConfPO employeeRule = getSalarySysConfService(user).getOneByCode(SalarySysConstant.SALARY_ACCT_EMPLOYEE_RULE); if (Objects.isNull(employeeRule) || StringUtils.equals(employeeRule.getConfValue(), SalaryAcctEmployeeRuleEnum.BYPAYENDTIME.getValue())) { // 默认包含停薪列表 statusList = Arrays.asList(SalaryArchiveStatusEnum.FIXED.getValue(), SalaryArchiveStatusEnum.SUSPEND.getValue(), SalaryArchiveStatusEnum.STOP_FROM_SUSPEND.getValue()); } else { // 仅包含发薪、待定薪 statusList = Arrays.asList(SalaryArchiveStatusEnum.FIXED.getValue(), SalaryArchiveStatusEnum.SUSPEND.getValue()); } // 获取薪资档案数据 List salaryArchiveList = listSome(SalaryArchivePO.builder().runStatusList(statusList).employeeIds(employeeIds).taxAgentId(taxAgentId).build()); List allEmployeeIds = salaryArchiveList.stream().map(SalaryArchivePO::getEmployeeId).distinct().collect(Collectors.toList()); // 获取所有可被引用的薪资项目 List salaryItems = salaryItemMapper.getCanAdjustSalaryItems(); Collection salaryItemIds = salaryItems.stream().map(SalaryItemPO::getId).collect(Collectors.toList()); // 获取薪资项目调整数据,isOnlyTaxAgent为true时不需要薪资项目数据 List salaryArchiveItemDataList = isOnlyTaxAgent || CollectionUtils.isEmpty(salaryItemIds) ? Lists.newArrayList() : salaryArchiveItemMapper.listByParam(SalaryArchiveItemQueryParam.builder().salaryItemIds(salaryItemIds).employeeIds(employeeIds).effectiveTime(localDateRange.getEndDate()).build()); return SalaryArchiveBO.buildSalaryArchiveData(salaryArchiveList, salaryArchiveItemDataList, localDateRange, allEmployeeIds, isOnlyTaxAgent); } @Override public void stopSalary(SalaryArchiveStopParam stopSalaryParam) { ValidUtil.doValidator(stopSalaryParam); stopSalaryParam.setPayEndDate(SalaryDateUtil.stringToDate(stopSalaryParam.getPayEndDateStr())); SalaryArchivePO po = getSalaryArchiveMapper().getById(stopSalaryParam.getSalaryArchiveId()); if (po == null) { throw new SalaryRunTimeException("未找到薪资档案"); } Date payStartDate = po.getPayStartDate(); Date payEndDate = stopSalaryParam.getPayEndDate(); if (payEndDate.before(payStartDate)) { throw new SalaryRunTimeException("最后缴纳日期应大于起始缴纳日期"); } po.setPayEndDate(payEndDate); po.setUpdateTime(new Date()); getSalaryArchiveMapper().update(po); } @Override public Map preview(SalaryArchiveImportHandleParam param) { //1、参数校验 vaildImportParam(param); Map map = new HashMap<>(); InputStream fileInputStream = null; try { fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId())); Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX); List headers = ExcelSupport.getSheetHeader(sheet, 0); map.put("headers", headers); map.put("list", ExcelParseHelper.parse2List(sheet, 1)); return map; } finally { IOUtils.closeQuietly(fileInputStream); } } private void vaildImportParam(SalaryArchiveImportHandleParam param) { String imageId = param.getImageId(); if (StringUtils.isBlank(imageId)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100593, "文件id为空")); } if (param.getListType() == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109712, "列表类型必传")); } else { // 定薪列表导入有调薪导入和初始化导入 if (param.getListType().equals(SalaryArchiveListTypeEnum.FIXED.getValue())) { Optional optional = Arrays.stream(SalaryArchiveImportTypeEnum.values()) .filter(e -> StringUtils.isNotEmpty(param.getImportType()) && e.getValue().equals(param.getImportType())).findFirst(); if (!optional.isPresent()) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100593, "导入类型不正确")); } } } } private List getEffectiveTaxAgentList() { Date truncate = DateUtils.truncate(new Date(), Calendar.DATE); return salaryArchiveTaxAgentMapper.getEffectiveTaxAgentList(SalaryArchiveTaxAgentQueryParam.builder().effectiveTime(truncate).build()); } private List getIneffectiveTaxAgentList() { Date truncate = DateUtils.truncate(new Date(), Calendar.DATE); return salaryArchiveTaxAgentMapper.getIneffectiveTaxAgentList(SalaryArchiveTaxAgentQueryParam.builder().effectiveTime(truncate).build()); } /** * 处理历史数据 * 下回发版可删除 */ public void handleHistory(Long currentEmployeeId) { // 待定薪没设置过的默认为正常工资薪金所得 // new LambdaUpdateChainWrapper<>(salaryArchiveMapper) // .eq(SalaryArchivePO::getDeleteType, 0) // .eq(SalaryArchivePO::getTenantKey, tenantKey) // .eq(SalaryArchivePO::getRunStatus, SalaryArchiveStatusEnum.PENDING.getValue()) // .isNull(SalaryArchivePO::getIncomeCategory) // .set(SalaryArchivePO::getIncomeCategory, IncomeCategoryEnum.WAGES_AND_SALARIES.getValue()) // .update(); //历史档案默认为发薪员工 List historyData = getSalaryArchiveMapper().getStatusIsNullData(); List ids = SalaryEntityUtil.properties(historyData, SalaryArchivePO::getId, Collectors.toList()); List> partIds = Lists.partition(ids, 999); for (List part : partIds) { getSalaryArchiveMapper().updateStatus(SalaryArchivePO.builder().ids(part).runStatus(SalaryArchiveStatusEnum.FIXED.getValue()).build()); } //处理个税扣缴义务人为空 List salaryArchives = getSalaryArchiveMapper().getHistoryData(); if (CollectionUtils.isEmpty(salaryArchives)) { return; } Date today = new Date(); List salaryArchiveTaxAgents = getEffectiveTaxAgentList(); List salaryArchiveItems = salaryArchiveItemMapper.getEffectiveSalaryItems(SalaryArchiveItemQueryParam.builder().effectiveTime(today).build()); List salaryArchiveDelIds = salaryArchives.stream().map(SalaryArchivePO::getId).collect(Collectors.toList()); List salaryArchiveTaxAgentDelIds = salaryArchiveTaxAgents.stream().map(SalaryArchiveTaxAgentPO::getId).collect(Collectors.toList()); List salaryArchiveItemDelIds = salaryArchiveItems.stream().map(SalaryArchiveItemPO::getId).collect(Collectors.toList()); List salaryArchiveAddList = Lists.newArrayList(); List salaryArchiveItemAddList = Lists.newArrayList(); Date endDate = today; for (SalaryArchivePO sa : salaryArchives) { List saTaxAgents = salaryArchiveTaxAgents.stream().filter(t -> t.getSalaryArchiveId().equals(sa.getId())).collect(Collectors.toList()); // 去重获取最新生效的个税口角义务人列表 saTaxAgents = saTaxAgents.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getSalaryArchiveId() + "-" + f.getTaxAgentId()))), ArrayList::new)); List saItemList = salaryArchiveItems.stream().filter(i -> i.getSalaryArchiveId().equals(sa.getId())).collect(Collectors.toList()); for (SalaryArchiveTaxAgentPO st : saTaxAgents) { Date finalEndDate = endDate; List saItems = saItemList.stream().filter(si -> !si.getEffectiveTime().after(finalEndDate)).collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getSalaryArchiveId() + "-" + f.getSalaryItemId()))), ArrayList::new)); SalaryArchivePO newSA = SalaryArchivePO.builder().id(IdGenerator.generate()).employeeId(sa.getEmployeeId()).taxAgentId(st.getTaxAgentId()).payStartDate(st.getEffectiveTime()) // .runStatus(SalaryArchiveStatusEnum.FIXED.getValue()) // .modifier(0L) .createTime(today).updateTime(today).creator(currentEmployeeId).deleteType(NumberUtils.INTEGER_ZERO).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build(); salaryArchiveAddList.add(newSA); saItems.forEach(sf -> { salaryArchiveItemAddList.add(SalaryArchiveItemPO.builder().salaryArchiveId(newSA.getId()).employeeId(newSA.getEmployeeId()).effectiveTime(sf.getEffectiveTime()).adjustReason(sf.getAdjustReason()).salaryItemId(sf.getSalaryItemId()).itemValue(sf.getItemValue()).description(sf.getDescription()) // 不用设置操作人 .operator(currentEmployeeId).operateTime(today).createTime(today).updateTime(today).creator(currentEmployeeId).deleteType(NumberUtils.INTEGER_ZERO).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build()); }); // endDate = st.getEffectiveTime(); } } // 逻辑删除历史数据 List> partition = Lists.partition(salaryArchiveDelIds, 999); for (List part : partition) { salaryArchiveMapper.batchDeleteHistoryData(SalaryArchivePO.builder().ids(part).build()); } List> partitionTA = Lists.partition(salaryArchiveTaxAgentDelIds, 999); for (List part : partitionTA) { salaryArchiveTaxAgentMapper.batchDeleteHistoryData(SalaryArchiveTaxAgentPO.builder().ids(part).build()); } List> partitionItem = Lists.partition(salaryArchiveItemDelIds, 999); for (List part : partitionItem) { salaryArchiveItemMapper.batchDeleteHistoryData(SalaryArchiveItemPO.builder().ids(part).build()); } // 新增迁移数据 if (CollectionUtils.isNotEmpty(salaryArchiveAddList)) { this.salaryArchiveMapper.batchInsert(salaryArchiveAddList); } if (CollectionUtils.isNotEmpty(salaryArchiveItemAddList)) { this.salaryArchiveItemMapper.batchInsert(salaryArchiveItemAddList, user); } log.info("处理历史数据结束==============="); } @Override public Map selectSalaryArchiveColumns(SalaryArchiveImportTypeEnum salaryArchiveImportTypeEnum) { HashMap map = Maps.newHashMap(); //类型为档案初始化 boolean isInit = salaryArchiveImportTypeEnum.getValue().equals(SalaryArchiveImportTypeEnum.INIT.getValue()); //类型为调整个税扣缴义务人 boolean isTaxAgentAdjust = salaryArchiveImportTypeEnum.getValue().equals(SalaryArchiveImportTypeEnum.TAXAGENTADJUST.getValue()); //类型为调薪 boolean isSalaryItemAdjust = salaryArchiveImportTypeEnum.getValue().equals(SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getValue()); //固定列 map.put(SalaryI18nUtil.getI18nLabel(85429, "姓名"), "username"); map.put(SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"), "taxAgentName"); map.put(SalaryI18nUtil.getI18nLabel(85904, "生效日期"), "taxAgentEffectiveTime"); map.put(SalaryI18nUtil.getI18nLabel(86185, "部门"), "departmentName"); map.put(SalaryI18nUtil.getI18nLabel(86186, "手机号"), "mobile"); map.put(SalaryI18nUtil.getI18nLabel(91075, "员工状态"), "employeeStatus"); List salaryItems = salaryItemMapper.getCanAdjustSalaryItems(); if (isTaxAgentAdjust || isSalaryItemAdjust) { map.put(SalaryI18nUtil.getI18nLabel(85431, "调整原因"), "adjustReason"); } //动态列 // 获取所有可被引用的薪资项目 if (isInit || isSalaryItemAdjust) { for (SalaryItemPO salaryItem : salaryItems) { map.put(salaryItem.getName(), salaryItem.getCode()); } } return map; } @Override public Map queryTabTotal() { long currentEmployeeId = user.getUID(); // tab页签数量 Map result = new HashMap<>(); Boolean needAuth = getTaxAgentService(user).isNeedAuth(currentEmployeeId); //获取管理的人员范围 List taxAgentEmployeeDTOS = getTaxAgentService(user).listTaxAgentAndEmployeeTree(currentEmployeeId); Map> taxAgentEmployeesMap = SalaryEntityUtil.convert2Map(taxAgentEmployeeDTOS, TaxAgentManageRangeEmployeeDTO::getTaxAgentId, TaxAgentManageRangeEmployeeDTO::getEmployeeList); List list = new ArrayList<>(); if (needAuth) { // 获取作为管理员的所有个税扣缴义务人列表 Collection taxAgentPOS = getTaxAgentService(user).listAllTaxAgentsAsAdmin(currentEmployeeId); Set taxAgentIds = SalaryEntityUtil.properties(taxAgentPOS, TaxAgentPO::getId); //获取所有薪资档案 List archiveListDTOS = getSalaryArchiveMapper().listAll(); list = archiveListDTOS.stream().filter(dto -> taxAgentIds.contains(dto.getTaxAgentId())).collect(Collectors.toList()); Boolean adminEnable = getTaxAgentService(user).isAdminEnable(currentEmployeeId); //不是管理员看不到数据,返回空 if (!adminEnable) { list = new ArrayList<>(); } } else { list = getSalaryArchiveMapper().listAll(); } long pendingTotal = 0L; long fixedTotal = 0L; long suspendTotal = 0L; long stopTotal = 0L; long extTotal = 0L; for (SalaryArchivePO sa : list) { Integer employeeType = sa.getEmployeeType(); if (employeeType == null || employeeType == 0) { if (sa.getRunStatus().equals(SalaryArchiveStatusEnum.PENDING.getValue())) { pendingTotal += 1; } else if (sa.getRunStatus().equals(SalaryArchiveStatusEnum.FIXED.getValue()) || sa.getRunStatus().equals(SalaryArchiveStatusEnum.SUSPEND.getValue())) { fixedTotal += 1; if (sa.getRunStatus().equals(SalaryArchiveStatusEnum.SUSPEND.getValue())) { suspendTotal += 1; } } else if (sa.getRunStatus().equals(SalaryArchiveStatusEnum.STOP_FROM_PENDING.getValue()) || sa.getRunStatus().equals(SalaryArchiveStatusEnum.STOP_FROM_SUSPEND.getValue())) { stopTotal += 1; } } else { extTotal += 1; } } result.put(SalaryArchiveListTypeEnum.PENDING.getValue(), pendingTotal); result.put(SalaryArchiveListTypeEnum.FIXED.getValue(), fixedTotal); result.put(SalaryArchiveListTypeEnum.SUSPEND.getValue(), suspendTotal); result.put(SalaryArchiveListTypeEnum.STOP.getValue(), stopTotal); result.put(SalaryArchiveListTypeEnum.EXT.getValue(), extTotal); return result; } @Override public String deletePendingTodo(Collection ids) { if (CollectionUtils.isEmpty(ids)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误")); } List oldList = listSome(SalaryArchivePO.builder() .ids(ids) .runStatus(SalaryArchiveStatusEnum.PENDING.getValue()) .build()); if (CollectionUtils.isEmpty(oldList)) { return StringUtils.EMPTY; } // 从待定薪到停薪 getSalaryArchiveMapper().deletePendingTodo(ids); // 记录日志 List newList = getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().ids(ids).build()); String operatedesc = SalaryI18nUtil.getI18nLabel(0, "删除待办"); recordLog(oldList, newList, operatedesc); return StringUtils.EMPTY; } @Override public Map gotoFixed(Collection ids) { if (CollectionUtils.isEmpty(ids)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(145969, "没有可以操作的记录")); } List salaryArchiveList = listSome(SalaryArchivePO.builder().ids(ids).runStatus(SalaryArchiveStatusEnum.PENDING.getValue()).build()); if (CollectionUtils.isEmpty(salaryArchiveList)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(145969, "档案不存在!")); } List unableList = salaryArchiveList.stream().filter(f -> f.getPayStartDate() == null).collect(Collectors.toList()); int total = ids.size(); int errorCount = unableList.size(); // 单个设为定薪的失败提示 if (total == 1 && errorCount > 0) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109197, "请先维护起始发薪日期")); } // 从待定薪到定薪 List> partition = Lists.partition((List) ids, 1000); partition.forEach(getSalaryArchiveMapper()::gotoFixed); // 记录日志 List newList = getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().ids(ids).build()); String operateDesc = SalaryI18nUtil.getI18nLabel(0, "设为发薪员工"); recordLog(salaryArchiveList, newList, operateDesc); // 获取所有可被引用的薪资项目 List salaryItemIds = getSalaryArchiveItemService(user).getCanAdjustSalaryItems().stream().map(SalaryItemPO::getId).collect(Collectors.toList()); List currentEffectiveItemList = getSalaryArchiveItemService(user).getCurrentEffectiveItemListIngoreValue(ids, salaryItemIds) .stream() .peek(e -> { Optional salaryArchive = salaryArchiveList.stream().filter(sa -> sa.getId().equals(e.getSalaryArchiveId())).findFirst(); if (salaryArchive.isPresent()) { e.setAdjustReason(SalaryArchiveItemAdjustReasonEnum.INIT.getValue()); e.setEffectiveTime(salaryArchive.get().getPayStartDate()); } }).collect(Collectors.toList()); // 更新薪资项目的生效日期 List> partitions = Lists.partition(currentEffectiveItemList, 100); partitions.forEach(list -> getSalaryArchiveItemMapper().batchUpdate(list)); Map resultMap = new HashMap<>(2); String resultMsg = SalaryI18nUtil.getI18nLabel(94620, "操作成功"); String resultType = "success"; // 批量设为定薪提示 if (total > 1) { resultMsg = SalaryI18nUtil.getI18nLabel(134807, "成功条数") + ": " + (total - errorCount) + "; " + SalaryI18nUtil.getI18nLabel(134808, "失败条数") + ": " + (errorCount) + (errorCount > 0 ? ", " + SalaryI18nUtil.getI18nLabel(109197, "请先维护起始发薪日期") : ""); resultType = errorCount > 0 ? "info" : resultType; } resultMap.put("type", resultType); resultMap.put("msg", resultMsg); return resultMap; } @Override public Map allGotoFixed(SalaryArchiveQueryParam queryParam) { queryParam.setRunStatusList(Arrays.asList(SalaryArchiveStatusEnum.PENDING.getValue())); List salaryArchiveIds = this.list(queryParam) .stream().map(SalaryArchiveListDTO::getId).collect(Collectors.toList()); return this.gotoFixed(salaryArchiveIds); } @Override public Map gotoStop(Collection ids) { if (CollectionUtils.isEmpty(ids)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(145969, "没有可以操作的记录")); } List oldList = listSome(SalaryArchivePO.builder() .ids(ids) .runStatus(SalaryArchiveStatusEnum.SUSPEND.getValue()) .build()); if (CollectionUtils.isEmpty(oldList)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(145969, "档案不存在!")); } List unableList = oldList.stream().filter(f -> f.getPayEndDate() == null).collect(Collectors.toList()); int total = ids.size(); int errorCount = unableList.size(); // 单个设为定薪的失败提示 if (total == 1 && errorCount > 0) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(109196, "请先维护最后发薪日期")); } // 从待停薪到停薪 getSalaryArchiveMapper().gotoStop(ids); // 记录日志 List newList = getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().ids(ids).build()); String operatedesc = SalaryI18nUtil.getI18nLabel(0, "停薪"); recordLog(oldList, newList, operatedesc); Map resultMap = new HashMap<>(2); String resultMsg = SalaryI18nUtil.getI18nLabel(94620, "操作成功"); String resultType = "success"; // 批量设为定薪提示 if (total > 1) { resultMsg = SalaryI18nUtil.getI18nLabel(134807, "成功条数") + ": " + (total - errorCount) + "; " + SalaryI18nUtil.getI18nLabel(134808, "失败条数") + ": " + (errorCount) + (errorCount > 0 ? ", " + SalaryI18nUtil.getI18nLabel(109196, "请先维护最后发薪日期") : ""); resultType = errorCount > 0 ? "info" : resultType; } resultMap.put("type", resultType); resultMap.put("msg", resultMsg); return resultMap; } @Override public Map allGotoStop(SalaryArchiveQueryParam queryParam) { queryParam.setRunStatusList(Arrays.asList(SalaryArchiveStatusEnum.SUSPEND.getValue())); List salaryArchiveIds = this.list(queryParam) .stream().map(SalaryArchiveListDTO::getId).collect(Collectors.toList()); return this.gotoStop(salaryArchiveIds); } @Override public String deleteSuspendTodo(Collection ids) { if (org.springframework.util.CollectionUtils.isEmpty(ids)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误")); } // List oldList = listSome(SalaryArchivePO.builder() // .ids(ids) // .runStatus(SalaryArchiveStatusEnum.SUSPEND.getValue()) // .build()); // List unableList = oldList.stream().filter(f -> Objects.nonNull(f.getPayEndDate()) && !f.getPayEndDate().after(new Date())).collect(Collectors.toList()); // if (CollectionUtils.isNotEmpty(unableList)) { // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(115789, "最后发薪日必须晚于今天")); // } // // // 从待停薪到定薪 // getSalaryArchiveMapper().deleteSuspendTodo(ids); // return StringUtils.EMPTY; // 获取所有个税扣缴义务人 // Collection taxAgentList = getTaxAgentService(user).listTaxAgentAndEmployeeTree(Long.valueOf(user.getUID())); Collection taxAgentList = getTaxAgentService(user).listTaxAgentAndEmployeeTree(); // 获取删除待停薪信息 List list = getSalaryArchiveMapper().list(SalaryArchiveQueryParam.builder().ids(ids).build()); if (list.size() != ids.size()) { throw new SalaryRunTimeException("薪资档案不存在,删除失败!"); } Set employeeStatus = list.stream().map(SalaryArchiveListDTO::getEmployeeStatus).collect(Collectors.toSet()); if (employeeStatus.contains("5")) { throw new SalaryRunTimeException("离职人员无法删除待办"); } Map taxAgentMap = SalaryEntityUtil.convert2Map(taxAgentList, TaxAgentManageRangeEmployeeDTO::getTaxAgentId); // 判断删除待停薪代办的人是否在个税扣缴义务人的人员范围中 for (SalaryArchiveListDTO dto : list) { TaxAgentManageRangeEmployeeDTO taxAgentManageRangeEmployeeDTO = taxAgentMap.get(dto.getTaxAgentId()); if (Objects.nonNull(taxAgentManageRangeEmployeeDTO)) { boolean canDelete = taxAgentManageRangeEmployeeDTO.getEmployeeList().stream() .map(TaxAgentManageRangeEmployeeDTO.TaxAgentEmployee::getEmployeeId) .anyMatch(id -> Objects.equals(id, dto.getEmployeeId())); if (!canDelete) { throw new SalaryRunTimeException("个税扣缴义务人不存在或不在权限范围内,删除失败!"); } } else { throw new SalaryRunTimeException("个税扣缴义务人不存在或不在权限范围内,删除失败!"); } } // 删除最后发薪日期,设置状态为发薪 if (CollectionUtils.isNotEmpty(list)) { List salaryArchiveIds = list.stream().map(SalaryArchiveListDTO::getId).collect(Collectors.toList()); getSalaryArchiveMapper().deleteSuspendTodo(salaryArchiveIds); // 记录日志 List oldList = getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().ids(salaryArchiveIds).build()); List newList = getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().ids(ids).build()); String operatedesc = SalaryI18nUtil.getI18nLabel(0, "删除待办"); recordLog(oldList, newList, operatedesc); } return StringUtils.EMPTY; } @Override public String cancelStop(Collection ids) { if (org.springframework.util.CollectionUtils.isEmpty(ids)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误")); } List oldList = listSome( SalaryArchivePO.builder() .ids(ids) .runStatusList(Arrays.asList(SalaryArchiveStatusEnum.STOP_FROM_PENDING.getValue(), SalaryArchiveStatusEnum.STOP_FROM_SUSPEND.getValue())) .build()); if (CollectionUtils.isEmpty(oldList)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(145969, "档案不存在!")); } List taxAgentManageRangeEmployees = getTaxAgentService(user).listAllTaxAgentAndEmployee(); List oldPendingList = oldList.stream().filter(f -> f.getRunStatus().equals(SalaryArchiveStatusEnum.STOP_FROM_PENDING.getValue())).collect(Collectors.toList()); boolean isNotExist = oldPendingList.stream().anyMatch(te -> taxAgentManageRangeEmployees.stream().noneMatch(p -> p.getEmployeeId() != null && p.getEmployeeId().equals(te.getEmployeeId()) && p.getTaxAgentId().equals(te.getTaxAgentId()))); if (isNotExist) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(116196, "不在当前个税扣缴义人的人员范围中,不可取消停薪")); } // 从停薪到待定薪 getSalaryArchiveMapper().gotoPendingFromStop(ids); // 从停薪到定薪 getSalaryArchiveMapper().gotoFixedFromStop(ids); // 记录日志 List newList = getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().ids(ids).build()); String operatedesc = SalaryI18nUtil.getI18nLabel(0, "取消停薪"); recordLog(oldList, newList, operatedesc); return StringUtils.EMPTY; } @Override public Map handleRepeatData() { Map result = new HashMap<>(); //获取所有薪资档案 List list = getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().runStatus(SalaryArchiveStatusEnum.PENDING.getValue()).build()); AtomicInteger num = new AtomicInteger(); if (CollectionUtils.isNotEmpty(list)) { Map> maps = SalaryEntityUtil.group2Map(list, k -> k.getTaxAgentId() + "-" + k.getEmployeeId()); maps.forEach((key, pos) -> { if (pos.size() > 1) { for (int i = 1; i < pos.size(); i++) { SalaryArchivePO salaryArchivePO = pos.get(i); getSalaryArchiveMapper().delete(salaryArchivePO); num.getAndIncrement(); } } }); } result.put("共处理", num.get()); return result; } @Override public List listPayEndDateIsNull(List employeeIds) { if (CollectionUtils.isEmpty(employeeIds)) { return Collections.emptyList(); } return getSalaryArchiveMapper().listPayEndDateIsNull(employeeIds); } @Override public List listByRunStatus(List list) { return getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().runStatusList(list).build()); } /** * 同步所有档案起始发薪日期变为入职日期 * * @return */ @Override public String syncPayStartDate() { List employeeList = getSalaryEmployeeService(user).listAll(UseEmployeeTypeEnum.ALL); Map empPayStartDateMap = SalaryEntityUtil.convert2Map(employeeList, DataCollectionEmployee::getEmployeeId, DataCollectionEmployee::getCompanystartdate); List list = getSalaryArchiveMapper().listAll(); List archives = list.stream() .peek(archive -> { String payStartDate = empPayStartDateMap.getOrDefault(archive.getEmployeeId(), ""); if (SalaryDateUtil.checkDay(payStartDate)) { archive.setPayStartDate(SalaryDateUtil.dateStrToLocalDate(payStartDate)); } }) .collect(Collectors.toList()); salaryArchiveMapper.batchUpdate(archives); return "执行完毕"; } @Override public List listPayStartDateIsNull(String runStatus) { if (StringUtils.isBlank(runStatus)) { return Collections.emptyList(); } return getSalaryArchiveMapper().listPayStartDateIsNull(runStatus); } }