package com.engine.salary.service.impl; import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; import com.engine.salary.cache.SalaryCacheKey; import com.engine.salary.common.LocalDateRange; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.datacollection.dto.AttendQuoteFieldListDTO; import com.engine.salary.entity.salaryacct.bo.SalaryAcctCalculateBO; import com.engine.salary.entity.salaryacct.bo.SalaryAcctCalculatePriorityBO; import com.engine.salary.entity.salaryacct.bo.SalaryAcctResultBO; import com.engine.salary.entity.salaryacct.dto.ConsolidatedTaxDetailDTO; import com.engine.salary.entity.salaryacct.dto.SalaryAcctProgressDTO; import com.engine.salary.entity.salaryacct.dto.SalaryAcctResultDetailDTO; import com.engine.salary.entity.salaryacct.param.SalaryAcctCalculateParam; import com.engine.salary.entity.salaryacct.param.SalaryAcctEmployeeQueryParam; import com.engine.salary.entity.salaryacct.param.SalaryAcctResultQueryParam; import com.engine.salary.entity.salaryacct.param.SalaryAcctResultSaveParam; import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO; import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO; import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO; import com.engine.salary.entity.salaryacct.po.SalaryAcctResultTempPO; import com.engine.salary.entity.salaryformula.ExpressFormula; import com.engine.salary.entity.salaryitem.po.SalaryItemPO; import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO; import com.engine.salary.entity.salarysob.po.SalarySobAdjustRulePO; import com.engine.salary.entity.salarysob.po.SalarySobEmpFieldPO; import com.engine.salary.entity.salarysob.po.SalarySobItemPO; import com.engine.salary.entity.salarysob.po.SalarySobPO; import com.engine.salary.entity.taxagent.po.TaxAgentPO; import com.engine.salary.enums.salaryaccounting.SalaryAcctRecordStatusEnum; import com.engine.salary.enums.salarysob.IncomeCategoryEnum; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.mapper.salaryacct.SalaryAcctResultMapper; import com.engine.salary.service.*; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.SalaryI18nUtil; import com.engine.salary.util.db.MapperProxyFactory; import com.engine.salary.util.page.PageInfo; import com.google.common.collect.Lists; import com.weaver.util.threadPool.ThreadPoolUtil; import com.weaver.util.threadPool.constant.ModulePoolEnum; import com.weaver.util.threadPool.entity.LocalRunnable; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import weaver.hrm.User; import java.math.BigDecimal; import java.util.*; import java.util.concurrent.BlockingDeque; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingDeque; import java.util.stream.Collectors; /** * 薪资核算结果 *

Copyright: Copyright (c) 2022

*

Company: 泛微软件

* * @author qiantao * @version 1.0 **/ @Slf4j public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctResultService { private SalaryAcctResultMapper getSalaryAcctResultMapper() { return MapperProxyFactory.getProxy(SalaryAcctResultMapper.class); } private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) { return (SalaryAcctEmployeeService) ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user); } private SalarySobItemService getSalarySobItemService(User user) { return (SalarySobItemService) ServiceUtil.getService(SalarySobItemServiceImpl.class, user); } private SalaryItemService getSalaryItemService(User user) { return (SalaryItemService) ServiceUtil.getService(SalaryItemServiceImpl.class, user); } private SalarySobEmpFieldService getSalarySobEmpFieldService(User user) { return (SalarySobEmpFieldService) ServiceUtil.getService(SalarySobEmpFieldServiceImpl.class, user); } private SalarySobService getSalarySobService(User user) { return (SalarySobService) ServiceUtil.getService(SalarySobServiceImpl.class, user); } private SalaryAcctRecordService getSalaryAcctRecordService(User user) { return (SalaryAcctRecordService) ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user); } private TaxAgentV2Service getTaxAgentService(User user) { return ServiceUtil.getService(TaxAgentV2ServiceImpl.class, user); } private SalaryEmployeeService getSalaryEmployeeService(User user) { return (SalaryEmployeeService) ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user); } private SalaryFormulaService getSalaryFormulaService(User user) { return (SalaryFormulaService) ServiceUtil.getService(SalaryFormulaServiceImpl.class, user); } private SalarySobAdjustRuleService getSalarySobAdjustRuleService(User user) { return (SalarySobAdjustRuleService) ServiceUtil.getService(SalarySobAdjustRuleServiceImpl.class, user); } private SalaryAcctCalculateService getSalaryAcctCalculateService(User user) { return (SalaryAcctCalculateService) ServiceUtil.getService(SalaryAcctCalculateServiceImpl.class, user); } private SalaryAcctProgressService getSalaryAcctProgressService(User user) { return (SalaryAcctProgressService) ServiceUtil.getService(SalaryAcctProgressServiceImpl.class, user); } private DataSourceTransactionManager dataSourceTransactionManager; private SalaryAcctResultTempService getSalaryAcctResultTempService(User user) { return (SalaryAcctResultTempService) ServiceUtil.getService(SalaryAcctResultTempServiceImpl.class, user); } // private LoggerTemplate salaryAcctRecordLoggerTemplate; private SIAccountService getSIAccountService(User user) { return (SIAccountService) ServiceUtil.getService(SIAccountServiceImpl.class, user); } private AttendQuoteFieldService getAttendQuoteFieldService(User user) { return (AttendQuoteFieldService) ServiceUtil.getService(AttendQuoteFieldServiceImpl.class, user); } private SalaryCheckResultService salaryCheckResultService; @Override public List listBySalaryAcctRecordIds(Collection salaryAcctRecordIds) { if (CollectionUtils.isEmpty(salaryAcctRecordIds)) { return Collections.emptyList(); } return getSalaryAcctResultMapper().listSome(SalaryAcctResultPO.builder().salaryAcctRecordIds(salaryAcctRecordIds).build()); } @Override public List listBySalaryAcctEmployeeId(Long salaryAcctEmployeeId) { return getSalaryAcctResultMapper().listSome(SalaryAcctResultPO.builder().salaryAcctEmpId(salaryAcctEmployeeId).build()); } @Override public List listBySalaryAcctEmployeeIds(Collection salaryAcctEmployeeIds) { if (CollectionUtils.isEmpty(salaryAcctEmployeeIds)) { return Collections.emptyList(); } return getSalaryAcctResultMapper().listSome(SalaryAcctResultPO.builder().salaryAcctEmpIds(salaryAcctEmployeeIds).build()); } @Override public List listBySalaryAcctRecordIdsAndEmployeeIds(Collection salaryAcctRecordIds, Collection employeeIds) { if (CollectionUtils.isEmpty(salaryAcctRecordIds) || CollectionUtils.isEmpty(employeeIds)) { return Collections.emptyList(); } return getSalaryAcctResultMapper().listSome(SalaryAcctResultPO.builder().salaryAcctRecordIds(salaryAcctRecordIds).employeeIds(employeeIds).build()); } @Override public SalaryAcctResultDetailDTO getBySalaryAcctEmployeeId(Long salaryAcctEmployeeId) { // 查询薪资核算人员 SalaryAcctEmployeePO salaryAcctEmployeePO = getSalaryAcctEmployeeService(user).getById(salaryAcctEmployeeId); if (Objects.isNull(salaryAcctEmployeePO)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98831, "薪资核算人员不存在或已被删除")); } // 查询薪资核算所用薪资账套的薪资项目副本 List salarySobItemPOS = getSalarySobItemService(user).listBySalarySobId(salaryAcctEmployeePO.getSalarySobId()); // 查询薪资项目 Set salaryItemIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getSalaryItemId); List salaryItemPOS = getSalaryItemService(user).listByIds(salaryItemIds); // 查询薪资核算所用薪资账套的人员信息字段 List salarySobEmpFieldPOS = getSalarySobEmpFieldService(user).listBySalarySobId(salaryAcctEmployeePO.getSalarySobId()); // 查询人员信息 DataCollectionEmployee simpleEmployee = getSalaryEmployeeService(user).getEmployeeById(salaryAcctEmployeePO.getEmployeeId()); // 查询薪资核算结果 List salaryAcctResultPOS = listBySalaryAcctEmployeeId(salaryAcctEmployeeId); // 查询个税扣缴义务人 TaxAgentPO taxAgent = getTaxAgentService(user).getById(salaryAcctEmployeePO.getTaxAgentId()); // 转换成薪资核算结果详情dto return SalaryAcctResultBO.convert2DetailDTO(simpleEmployee, taxAgent, salaryAcctEmployeePO, salarySobEmpFieldPOS, salarySobItemPOS, salaryItemPOS, salaryAcctResultPOS); } @Override public PageInfo> listPageByParam(SalaryAcctResultQueryParam queryParam) { // 查询薪资核算人员(分页) PageInfo page = getSalaryAcctEmployeeService(user).listPageByResultQueryParam(queryParam); // 查询薪资核算结果 List> data = listBySalaryAcctEmployees(page.getList(), queryParam); // 薪资核算结果的分页结果 PageInfo> resultPage = new PageInfo<>(); resultPage.setList(data); resultPage.setTotal(page.getTotal()); resultPage.setPageNum(page.getPageNum()); resultPage.setPageSize(page.getPageSize()); return resultPage; } @Override public List> listByParam(SalaryAcctResultQueryParam queryParam) { // 查询薪资核算人员 List salaryAcctEmployeePOS = getSalaryAcctEmployeeService(user).listByResultQueryParam(queryParam); // 查询薪资核算结果 return listBySalaryAcctEmployees(salaryAcctEmployeePOS, queryParam); } /** * 根据薪资核算人员查询薪资核算结果 * * @param salaryAcctEmployeePOS 薪资核算人员 * @param queryParam 列表查询条件 * @return */ private List> listBySalaryAcctEmployees(List salaryAcctEmployeePOS, SalaryAcctResultQueryParam queryParam) { if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) { return Collections.emptyList(); } // 查询薪资核算记录 SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(queryParam.getSalaryAcctRecordId()); if (Objects.isNull(salaryAcctRecordPO)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除")); } // 查询薪资核算所用的薪资账套的员工信息字段 List salarySobEmpFieldPOS = getSalarySobEmpFieldService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId()); // 查询薪资核算所用薪资账套的薪资项目 List salarySobItemPOS = getSalarySobItemService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId()); Set salaryItemIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getSalaryItemId); List salaryItemPOS = getSalaryItemService(user).listByIds(salaryItemIds); // 查询薪资核算结果 Set salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId); List salaryAcctResultPOS = listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds); // 查询人员信息 List employeeIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getEmployeeId, Collectors.toList()); List simpleEmployees = getSalaryEmployeeService(user).listByIds(employeeIds); // 查询个税扣缴义务人 Set taxAgentIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getTaxAgentId); List taxAgentPOS = getTaxAgentService(user).listByIds(taxAgentIds); // 判断是否存在合并计税 Set salaryAcctEmployeeIds4ConsolidatedTax; if (StringUtils.isNotEmpty(queryParam.getConsolidatedTaxation())) { // 如果查询条件中含有"合并计税",那么在入参中的salaryAcctEmployeePOS就已经全部都是存在合并计税的人员了(前面已经过滤了),无需再次查询合并计税的人员 salaryAcctEmployeeIds4ConsolidatedTax = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId); } else { // 如果查询条件中没有包含"合并计税",那么就需要查询出存在合并计税的人,标记给前端 SalaryAcctEmployeeQueryParam accEmployeeQueryParam = SalaryAcctEmployeeQueryParam.builder() .salaryAcctRecordId(queryParam.getSalaryAcctRecordId()) .ids(SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId)) .build(); List salaryAcctEmployeePOS4ConsolidatedTax = getSalaryAcctEmployeeService(user).listByParam4ConsolidatedTax(accEmployeeQueryParam); salaryAcctEmployeeIds4ConsolidatedTax = SalaryEntityUtil.properties(salaryAcctEmployeePOS4ConsolidatedTax, SalaryAcctEmployeePO::getId); } // 查询公式详情 Set formulaIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getFormulaId); List expressFormulas = getSalaryFormulaService(user).listExpressFormula(formulaIds); Map expressFormulaMap = SalaryEntityUtil.convert2Map(expressFormulas, ExpressFormula::getId, ExpressFormula::getFormula); Map customParameters = SalaryEntityUtil.convert2Map(salarySobItemPOS, SalarySobItemPO::getSalaryItemId, salarySobItemPO -> { if (salarySobItemPO.getFormulaId() <= 0) { return SalaryI18nUtil.getI18nLabel(92004, "输入/导入"); } return expressFormulaMap.getOrDefault(salarySobItemPO.getFormulaId(), StringUtils.EMPTY); }); // 转换成薪资核算结果列表 return SalaryAcctResultBO .buildTableData(salaryItemPOS, salarySobEmpFieldPOS, simpleEmployees, salaryAcctEmployeePOS, salaryAcctResultPOS, taxAgentPOS, salaryAcctEmployeeIds4ConsolidatedTax, customParameters); } @Override public ConsolidatedTaxDetailDTO getConsolidatedTaxDetail(Long salaryAcctEmployeeId) { // 查询当前的薪资核算人员 SalaryAcctEmployeePO salaryAcctEmployeePO = getSalaryAcctEmployeeService(user).getById(salaryAcctEmployeeId); if (Objects.isNull(salaryAcctEmployeePO)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98831, "薪资核算人员不存在或已被删除")); } // 查询当前的薪资核算人员的个税扣缴义务人 TaxAgentPO taxAgentPO = getTaxAgentService(user).getById(salaryAcctEmployeePO.getTaxAgentId()); // 查询当前的薪资核算人员的人员信息 DataCollectionEmployee simpleEmployee = getSalaryEmployeeService(user).getEmployeeById(salaryAcctEmployeePO.getEmployeeId()); // 查询当前的薪资核算记录 SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(salaryAcctEmployeePO.getSalaryAcctRecordId()); // 查询当前薪资核算记录所用的薪资账套 SalarySobPO salarySobPO = getSalarySobService(user).getById(salaryAcctRecordPO.getSalarySobId()); // 当前薪资核算记录所用的薪资账套的员工信息字段 List salarySobEmpFieldPOS = getSalarySobEmpFieldService(user).listBySalarySobId(salarySobPO.getId()); List salaryAcctRecordPOS = Collections.singletonList(salaryAcctRecordPO); List salaryAcctEmployeePOS = Collections.singletonList(salaryAcctEmployeePO); // 如果当前薪资核算记录所用的薪资账套的薪资类型是工资薪金,代表可能存在合并计税 if (Objects.equals(salarySobPO.getIncomeCategory(), IncomeCategoryEnum.WAGES_AND_SALARIES.getValue())) { // 查询所有薪资类型为工资薪金的账套 List salarySobPOS = getSalarySobService(user).listByIncomeCategory(IncomeCategoryEnum.WAGES_AND_SALARIES); // 查询相同税款所属期内的薪资类型为工资薪金的账套的所有核算记录 Set salarySobIds = SalaryEntityUtil.properties(salarySobPOS, SalarySobPO::getId); LocalDateRange taxCycleDateRange = SalaryDateUtil.localDate2Range(salaryAcctRecordPO.getTaxCycle()); salaryAcctRecordPOS = getSalaryAcctRecordService(user).listBySalarySobIdsAndSalaryMonth(salarySobIds, taxCycleDateRange); // 查询当前薪资核算人员所涉及的合并计税的所有薪资核算人员 Set salaryAcctRecordIds = SalaryEntityUtil.properties(salaryAcctRecordPOS, SalaryAcctRecordPO::getId); salaryAcctEmployeePOS = getSalaryAcctEmployeeService(user).listByRecordIdsAndEmpIdAndTaxAgentId(salaryAcctRecordIds, salaryAcctEmployeePO.getEmployeeId(), salaryAcctEmployeePO.getTaxAgentId()); } // 查询薪资核算人员的薪资核算结果 Set salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId); List salaryAcctResultPOS = listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds); // 查询薪资核算人员所有合并计税的薪资核算记录所用的账套 Set salarySobIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getSalarySobId); List salarySobPOS = getSalarySobService(user).listByIds(salarySobIds); // 查询薪资项目所引用的薪资项目 List salarySobItemPOS = getSalarySobItemService(user).listBySalarySobIds(salarySobIds); // 查询薪资项目 Set salaryItemIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getSalaryItemId); List salaryItemPOS = getSalaryItemService(user).listByIds(salaryItemIds); // 转换成合并计税详情dto return SalaryAcctResultBO.convert2ConsolidatedTaxDetailDTO(simpleEmployee, taxAgentPO, salarySobEmpFieldPOS, salaryItemPOS, salaryAcctEmployeePOS, salarySobPOS, salaryAcctRecordPOS, salaryAcctResultPOS); } @Override public void save(SalaryAcctResultSaveParam saveParam) { // 查询薪资核算人员 SalaryAcctEmployeePO salaryAcctEmployeePO = getSalaryAcctEmployeeService(user).getById(saveParam.getSalaryAcctEmpId()); if (Objects.isNull(salaryAcctEmployeePO)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98831, "薪资核算人员不存在或已被删除")); } // 保存参数转换成薪资核算结果po List salaryAcctResultPOS = SalaryAcctResultBO.convert2PO(saveParam, salaryAcctEmployeePO, (long) user.getUID()); // 删除原来的薪资核算结果 deleteBySalaryAcctEmployeeIds(Collections.singleton(saveParam.getSalaryAcctEmpId())); // 保存薪资核算结果 if (CollectionUtils.isNotEmpty(salaryAcctResultPOS)) { batchSave(salaryAcctResultPOS); } // 查询操作日志的targetName String targetName = getSalaryAcctRecordService(user).getLogTargetNameById(salaryAcctEmployeePO.getSalaryAcctRecordId()); // 查询人员信息 DataCollectionEmployee simpleEmployee = getSalaryEmployeeService(user).getEmployeeById(salaryAcctEmployeePO.getEmployeeId()); // 查询个税扣缴义务人 // TaxAgentPO taxAgentPO = getTaxAgentService(user).getById(salaryAcctEmployeePO.getTaxAgentId()); // 记录日志 // String operateDesc = simpleEmployee.getUsername() + "(" + Optional.ofNullable(taxAgentPO).map(TaxAgentPO::getName).orElse(StringUtils.EMPTY) + ")"; // LoggerContext loggerContext = new LoggerContext<>(); // loggerContext.setTargetId(String.valueOf(salaryAcctEmployeePO.getSalaryAcctRecordId())); // loggerContext.setTargetName(targetName); // loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue()); // loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(95783, "编辑薪资核算结果") + ": " + operateDesc); // loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(95783, "编辑薪资核算结果") + ": " + operateDesc); // loggerContext.setNewValueList(Lists.newArrayList(salaryAcctResultPOS)); // salaryAcctRecordLoggerTemplate.write(loggerContext); } @Override public void batchSave(Collection salaryAcctResultPOS) { if (CollectionUtils.isNotEmpty(salaryAcctResultPOS)) { List> partition = Lists.partition((List) salaryAcctResultPOS, 100); partition.forEach(getSalaryAcctResultMapper()::batchInsert); } } @Override public void deleteBySalaryAcctEmployeeIds(Collection salaryAcctEmployeeIds) { getSalaryAcctResultMapper().deleteBySalaryAcctEmpIds(salaryAcctEmployeeIds); } @Override public void deleteByAcctEmployeeIdsAndSalaryItemIds(Collection salaryAcctEmployeeIds, Collection salaryItemIds) { getSalaryAcctResultMapper().deleteByAcctEmpIdsAndSalaryItemIds(salaryAcctEmployeeIds, salaryItemIds); } @Override public void deleteBySalaryAcctRecordIds(Collection salaryAcctRecordIds) { getSalaryAcctResultMapper().deleteBySalaryAcctRecordIds(salaryAcctRecordIds); } @Override public void calculate(SalaryAcctCalculateParam calculateParam, DataCollectionEmployee simpleEmployee) { log.info("开始核算V2{}",calculateParam); try { // 1、查询薪资核算记录 SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(calculateParam.getSalaryAcctRecordId()); if (Objects.isNull(salaryAcctRecordPO)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除")); } // 1.1、如果薪资核算记录已经归档了,就不能继续核算 if (!Objects.equals(salaryAcctRecordPO.getStatus(), SalaryAcctRecordStatusEnum.NOT_ARCHIVED.getValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(99148, "当前薪资核算记录已归档,请重新打开后再进行核算")); } // 2、查询薪资核算记录的薪资周期、考勤周期等 SalarySobCycleDTO salarySobCycleDTO = getSalaryAcctRecordService(user).getSalarySobCycleById(calculateParam.getSalaryAcctRecordId()); // 3、查询薪资核算记录所用薪资账套的薪资项目副本 List salarySobItemPOS = getSalarySobItemService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId()); if (CollectionUtils.isEmpty(salarySobItemPOS)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(99151, "当前所用的薪资账套未选择任何薪资项目,无法核算")); } // 4、查询当前租户的所有薪资项目 List salaryItemPOS = getSalaryItemService(user).listAll(); // 5、查询薪资核算记录所用薪资账套的调薪计薪规则 List salarySobAdjustRulePOS = getSalarySobAdjustRuleService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId()); // 6、查询社保福利的所有字段 Map welfareColumns = getSIAccountService(user).welfareColumns(); // 7、查询考勤引用的所有字段 List attendQuoteFieldListDTOS = getAttendQuoteFieldService(user).listAll(); // 8、查询公式详情 Set formulaIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getFormulaId); formulaIds.addAll(SalaryEntityUtil.properties(salaryItemPOS, SalaryItemPO::getFormulaId)); List expressFormulas = getSalaryFormulaService(user).listExpressFormula(formulaIds); // 9、计算薪资项目的运算优先级 List> salarySobItemsWithPriority = SalaryAcctCalculatePriorityBO.calculatePriority(salarySobItemPOS, salaryItemPOS, expressFormulas); // 10、根据id查询其他合并计税的薪资核算记录 List otherSalaryAcctRecordPOS = getSalaryAcctRecordService(user).listById4OtherConsolidatedTax(salaryAcctRecordPO.getId()); // 11、查询本次核算人员 List salaryAcctEmployeePOS; if (CollectionUtils.isEmpty(calculateParam.getIds())) { salaryAcctEmployeePOS = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordId(salaryAcctRecordPO.getId()); } else { salaryAcctEmployeePOS = getSalaryAcctEmployeeService(user).listByIds(calculateParam.getIds()); } if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(103378, "薪资核算人员不能为空")); } // 11.1、初始化进度 SalaryAcctProgressDTO initProgress = new SalaryAcctProgressDTO() .setTitle(SalaryI18nUtil.getI18nLabel(97515, "核算中")) .setTitleLabelId(97515L) .setTotalQuantity(salaryAcctEmployeePOS.size() * 2 + 1) .setCalculatedQuantity(0) .setProgress(BigDecimal.ZERO) .setStatus(true) .setMessage(StringUtils.EMPTY); getSalaryAcctProgressService(user).initProgress(SalaryCacheKey.ACCT_PROGRESS + calculateParam.getSalaryAcctRecordId(), initProgress); // 12、对薪资核算人员进行拆分 List> partition = Lists.partition(salaryAcctEmployeePOS, 500); // 12.1、监控子线程的任务执行 CountDownLatch childMonitor = new CountDownLatch(partition.size()); // 12.2、记录子线程的执行结果 BlockingDeque calculateResults = new LinkedBlockingDeque<>(partition.size()); // 12.3、生成本次运算的key String calculateKey = UUID.randomUUID().toString(); // 12.4、多线程运算,运算结果存放在临时表中 for (List acctEmployeePOS : partition) { SalaryAcctCalculateBO salaryAcctCalculateBO = new SalaryAcctCalculateBO() .setSalaryAcctRecordPO(salaryAcctRecordPO) .setSalarySobCycleDTO(salarySobCycleDTO) .setOtherSalaryAcctRecordPOS(otherSalaryAcctRecordPOS) .setSalarySobItemPOS(salarySobItemPOS) .setSalaryItemIdWithPriorityList(salarySobItemsWithPriority) .setExpressFormulas(expressFormulas) .setSalaryItemPOS(salaryItemPOS) .setSalarySobAdjustRulePOS(salarySobAdjustRulePOS) .setWelfareColumns(MapUtils.emptyIfNull(welfareColumns)) .setAttendQuoteFieldListDTOS(attendQuoteFieldListDTOS) .setSalaryAcctEmployeePOS(acctEmployeePOS) .setChildMonitor(childMonitor) .setResults(calculateResults) .setCalculateKey(calculateKey); LocalRunnable localRunnable = new LocalRunnable() { @Override public void execute() { getSalaryAcctCalculateService(user).calculate(salaryAcctCalculateBO, simpleEmployee); } }; ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.HRM, "salaryAcctCalculateV2", localRunnable); } // 13、等待所有子线程执行完毕 childMonitor.await(); // 14、判断子线程执行结果 boolean allSuccess = calculateResults.stream().allMatch(SalaryAcctCalculateBO.Result::isStatus); if (!allSuccess) { // 薪资核算实现的线程的错误信息 String errorMsg = calculateResults.stream() .filter(result -> !result.isStatus()) .map(SalaryAcctCalculateBO.Result::getErrMsg) .collect(Collectors.joining("|")); getSalaryAcctProgressService(user).fail(SalaryCacheKey.ACCT_PROGRESS + calculateParam.getSalaryAcctRecordId(), errorMsg); // 删除薪资核算临时存储表中的数据 getSalaryAcctResultTempService(user).deleteByCalculateKey(calculateKey); return; } // 15、处理核算结果临时表数据 handleSalaryAcctResultTemp(calculateParam, calculateKey); // 16、开始运行校验规则 // SalaryAcctCheckParam salaryAcctCheckParam = new SalaryAcctCheckParam() // .setSalaryAcctRecordId(calculateParam.getSalaryAcctRecordId()) // .setIds(calculateParam.getIds()); // salaryCheckResultService.check(salaryAcctCheckParam, true, simpleEmployee); // Thread.sleep(10); getSalaryAcctProgressService(user).finish(SalaryCacheKey.ACCT_PROGRESS + calculateParam.getSalaryAcctRecordId(), true); // 记录日志 // 查询操作日志的targetName // String targetName = getSalaryAcctRecordService(user).getLogTargetNameById(calculateParam.getSalaryAcctRecordId()); // LoggerContext loggerContext = new LoggerContext<>(); // loggerContext.setTargetId(String.valueOf(calculateParam.getSalaryAcctRecordId())); // loggerContext.setTargetName(targetName); // loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue()); // loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(95783, "薪资核算")); // loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(95783, "薪资核算")); // salaryAcctRecordLoggerTemplate.write(loggerContext); } catch (Exception e) { log.info("薪资核算出错:{}", e.getMessage(), e); // throw new SalaryRunTimeException(e); getSalaryAcctProgressService(user).fail(SalaryCacheKey.ACCT_PROGRESS + calculateParam.getSalaryAcctRecordId(), SalaryI18nUtil.getI18nLabel(99642, "薪资核算出错") + ": " + e.getMessage()); } finally { // 数据库字段加密用 } } /** * 处理薪资核算临时存储表中的数据 * * @param calculateParam * @param calculateKey */ private void handleSalaryAcctResultTemp(SalaryAcctCalculateParam calculateParam, String calculateKey) { // TransactionStatus status = dataSourceTransactionManager.getTransaction(new DefaultTransactionDefinition()); // try { // 查询薪资核算结果的临时存储 List salaryAcctResultTempPOS = getSalaryAcctResultTempService(user).listByCalculateKey(calculateKey); // 删除原来的薪资核算结果 if (CollectionUtils.isNotEmpty(calculateParam.getIds())) { getSalaryAcctResultMapper().deleteBySalaryAcctEmpIds(calculateParam.getIds()); } else { getSalaryAcctResultMapper().deleteBySalaryAcctRecordIds(Collections.singleton(calculateParam.getSalaryAcctRecordId())); } // 保存薪资的薪资核算结果 List salaryAcctResultPOS = SalaryAcctResultBO.convert2ResultPO(salaryAcctResultTempPOS); batchSave(salaryAcctResultPOS); // 删除薪资核算临时存储表中的数据 getSalaryAcctResultTempService(user).deleteByCalculateKey(calculateKey); // // 提交事务 // dataSourceTransactionManager.commit(status); // } catch (Exception e) { // dataSourceTransactionManager.rollback(status); // throw e; // } } }