weaver-hrm-salary/src/com/engine/salary/service/impl/SalaryAcctResultServiceImpl...

502 lines
30 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.engine.salary.service.impl;
import com.engine.core.impl.Service;
import com.engine.salary.biz.TaxAgentBiz;
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.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.taxrate.TaxAgent;
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.page.PageInfo;
import com.google.common.collect.Lists;
import com.weaver.excel.formula.api.entity.ExpressFormula;
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 org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
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;
/**
* 薪资核算结果
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctResultService {
private SalaryAcctResultMapper salaryAcctResultMapper;
private SalaryAcctEmployeeService salaryAcctEmployeeService;
private SalarySobItemService salarySobItemService;
private SalaryItemService salaryItemService;
private SalarySobEmpFieldService salarySobEmpFieldService;
private SalarySobService salarySobService;
private SalaryAcctRecordService salaryAcctRecordService;
private TaxAgentBiz taxAgentService;
private SalaryEmployeeService hrmCommonEmployeeService;
private SalaryFormulaService salaryFormulaService;
private SalarySobAdjustRuleService salarySobAdjustRuleService;
private SalaryAcctCalculateService salaryAcctCalculateService;
// private SalaryAcctProgressService salaryAcctProgressService;
private DataSourceTransactionManager dataSourceTransactionManager;
private SalaryAcctResultTempService salaryAcctResultTempService;
// private LoggerTemplate salaryAcctRecordLoggerTemplate;
// private SIAccountService siAccountService;
private AttendQuoteFieldService attendQuoteFieldService;
// private SalaryCheckResultService salaryCheckResultService;
@Override
public List<SalaryAcctResultPO> listBySalaryAcctRecordIds(Collection<Long> salaryAcctRecordIds) {
if (CollectionUtils.isEmpty(salaryAcctRecordIds)) {
return Collections.emptyList();
}
return salaryAcctResultMapper.listSome(SalaryAcctResultPO.builder().salaryAcctRecordIds(salaryAcctRecordIds).build());
}
@Override
public List<SalaryAcctResultPO> listBySalaryAcctEmployeeId(Long salaryAcctEmployeeId) {
return salaryAcctResultMapper.listSome(SalaryAcctResultPO.builder().salaryAcctEmpId(salaryAcctEmployeeId).build());
}
@Override
public List<SalaryAcctResultPO> listBySalaryAcctEmployeeIds(Collection<Long> salaryAcctEmployeeIds) {
if (CollectionUtils.isEmpty(salaryAcctEmployeeIds)) {
return Collections.emptyList();
}
return salaryAcctResultMapper.listSome(SalaryAcctResultPO.builder().salaryAcctEmpIds(salaryAcctEmployeeIds).build());
}
@Override
public List<SalaryAcctResultPO> listBySalaryAcctRecordIdsAndEmployeeIds(Collection<Long> salaryAcctRecordIds, Collection<Long> employeeIds) {
if (CollectionUtils.isEmpty(salaryAcctRecordIds) || CollectionUtils.isEmpty(employeeIds)) {
return Collections.emptyList();
}
return salaryAcctResultMapper.listSome(SalaryAcctResultPO.builder().salaryAcctRecordIds(salaryAcctRecordIds).employeeIds(employeeIds).build());
}
@Override
public SalaryAcctResultDetailDTO getBySalaryAcctEmployeeId(Long salaryAcctEmployeeId) {
// 查询薪资核算人员
SalaryAcctEmployeePO salaryAcctEmployeePO = salaryAcctEmployeeService.getById(salaryAcctEmployeeId);
if (Objects.isNull(salaryAcctEmployeePO)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98831, "薪资核算人员不存在或已被删除"));
}
// 查询薪资核算所用薪资账套的薪资项目副本
List<SalarySobItemPO> salarySobItemPOS = salarySobItemService.listBySalarySobId(salaryAcctEmployeePO.getSalarySobId());
// 查询薪资项目
Set<Long> salaryItemIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getSalaryItemId);
List<SalaryItemPO> salaryItemPOS = salaryItemService.listByIds(salaryItemIds);
// 查询薪资核算所用薪资账套的人员信息字段
List<SalarySobEmpFieldPO> salarySobEmpFieldPOS = salarySobEmpFieldService.listBySalarySobId(salaryAcctEmployeePO.getSalarySobId());
// 查询人员信息
DataCollectionEmployee simpleEmployee = hrmCommonEmployeeService.getEmployeeById(salaryAcctEmployeePO.getEmployeeId());
// 查询薪资核算结果
List<SalaryAcctResultPO> salaryAcctResultPOS = listBySalaryAcctEmployeeId(salaryAcctEmployeeId);
// 查询个税扣缴义务人
TaxAgent taxAgent = taxAgentService.getById(salaryAcctEmployeePO.getTaxAgentId());
// 转换成薪资核算结果详情dto
return SalaryAcctResultBO.convert2DetailDTO(simpleEmployee, taxAgent, salaryAcctEmployeePO, salarySobEmpFieldPOS, salarySobItemPOS, salaryItemPOS, salaryAcctResultPOS);
}
@Override
public PageInfo<Map<String, Object>> listPageByParam(SalaryAcctResultQueryParam queryParam) {
// 查询薪资核算人员(分页)
PageInfo<SalaryAcctEmployeePO> page = salaryAcctEmployeeService.listPageByResultQueryParam(queryParam);
// 查询薪资核算结果
List<Map<String, Object>> data = listBySalaryAcctEmployees(page.getList(), queryParam);
// 薪资核算结果的分页结果
PageInfo<Map<String, Object>> resultPage = new PageInfo<>();
resultPage.setList(data);
return resultPage;
}
@Override
public List<Map<String, Object>> listByParam(SalaryAcctResultQueryParam queryParam) {
// 查询薪资核算人员
List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = salaryAcctEmployeeService.listByResultQueryParam(queryParam);
// 查询薪资核算结果
return listBySalaryAcctEmployees(salaryAcctEmployeePOS, queryParam);
}
/**
* 根据薪资核算人员查询薪资核算结果
*
* @param salaryAcctEmployeePOS 薪资核算人员
* @param queryParam 列表查询条件
* @return
*/
private List<Map<String, Object>> listBySalaryAcctEmployees(List<SalaryAcctEmployeePO> salaryAcctEmployeePOS,
SalaryAcctResultQueryParam queryParam) {
if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) {
return Collections.emptyList();
}
// 查询薪资核算记录
SalaryAcctRecordPO salaryAcctRecordPO = salaryAcctRecordService.getById(queryParam.getSalaryAcctRecordId());
if (Objects.isNull(salaryAcctRecordPO)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
}
// 查询薪资核算所用的薪资账套的员工信息字段
List<SalarySobEmpFieldPO> salarySobEmpFieldPOS = salarySobEmpFieldService.listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
// 查询薪资核算所用薪资账套的薪资项目
List<SalarySobItemPO> salarySobItemPOS = salarySobItemService.listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
Set<Long> salaryItemIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getSalaryItemId);
List<SalaryItemPO> salaryItemPOS = salaryItemService.listByIds(salaryItemIds);
// 查询薪资核算结果
Set<Long> salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId);
List<SalaryAcctResultPO> salaryAcctResultPOS = listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds);
// 查询人员信息
List<Long> employeeIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getEmployeeId, Collectors.toList());
List<DataCollectionEmployee> simpleEmployees = hrmCommonEmployeeService.listByIds(employeeIds);
// 查询个税扣缴义务人
Set<Long> taxAgentIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getTaxAgentId);
List<TaxAgent> taxAgentPOS = taxAgentService.listByIds(taxAgentIds);
// 判断是否存在合并计税
Set<Long> salaryAcctEmployeeIds4ConsolidatedTax;
if (StringUtils.isNotEmpty(queryParam.getConsolidatedTaxation())) {
// 如果查询条件中含有"合并计税"那么在入参中的salaryAcctEmployeePOS就已经全部都是存在合并计税的人员了前面已经过滤了无需再次查询合并计税的人员
salaryAcctEmployeeIds4ConsolidatedTax = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId);
} else {
// 如果查询条件中没有包含"合并计税",那么就需要查询出存在合并计税的人,标记给前端
SalaryAcctEmployeeQueryParam accEmployeeQueryParam = new SalaryAcctEmployeeQueryParam()
.setSalaryAcctRecordId(queryParam.getSalaryAcctRecordId())
.setIds(SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId));
List<SalaryAcctEmployeePO> salaryAcctEmployeePOS4ConsolidatedTax = salaryAcctEmployeeService.listByParam4ConsolidatedTax(accEmployeeQueryParam);
salaryAcctEmployeeIds4ConsolidatedTax = SalaryEntityUtil.properties(salaryAcctEmployeePOS4ConsolidatedTax, SalaryAcctEmployeePO::getId);
}
// 查询公式详情
Set<Long> formulaIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getFormulaId);
List<ExpressFormula> expressFormulas = salaryFormulaService.listExpressFormula(formulaIds);
Map<Long, String> expressFormulaMap = SalaryEntityUtil.convert2Map(expressFormulas, ExpressFormula::getId, ExpressFormula::getFormula);
Map<Long, String> 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 = salaryAcctEmployeeService.getById(salaryAcctEmployeeId);
if (Objects.isNull(salaryAcctEmployeePO)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98831, "薪资核算人员不存在或已被删除"));
}
// 查询当前的薪资核算人员的个税扣缴义务人
TaxAgent taxAgentPO = taxAgentService.getById(salaryAcctEmployeePO.getTaxAgentId());
// 查询当前的薪资核算人员的人员信息
DataCollectionEmployee simpleEmployee = hrmCommonEmployeeService.getEmployeeById(salaryAcctEmployeePO.getEmployeeId());
// 查询当前的薪资核算记录
SalaryAcctRecordPO salaryAcctRecordPO = salaryAcctRecordService.getById(salaryAcctEmployeePO.getSalaryAcctRecordId());
// 查询当前薪资核算记录所用的薪资账套
SalarySobPO salarySobPO = salarySobService.getById(salaryAcctRecordPO.getSalarySobId());
// 当前薪资核算记录所用的薪资账套的员工信息字段
List<SalarySobEmpFieldPO> salarySobEmpFieldPOS = salarySobEmpFieldService.listBySalarySobId(salarySobPO.getId());
List<SalaryAcctRecordPO> salaryAcctRecordPOS = Collections.singletonList(salaryAcctRecordPO);
List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = Collections.singletonList(salaryAcctEmployeePO);
// 如果当前薪资核算记录所用的薪资账套的薪资类型是工资薪金,代表可能存在合并计税
if (Objects.equals(salarySobPO.getIncomeCategory(), IncomeCategoryEnum.WAGES_AND_SALARIES.getValue())) {
// 查询所有薪资类型为工资薪金的账套
List<SalarySobPO> salarySobPOS = salarySobService.listByIncomeCategory(IncomeCategoryEnum.WAGES_AND_SALARIES);
// 查询相同税款所属期内的薪资类型为工资薪金的账套的所有核算记录
Set<Long> salarySobIds = SalaryEntityUtil.properties(salarySobPOS, SalarySobPO::getId);
LocalDateRange taxCycleDateRange = SalaryDateUtil.localDate2Range(salaryAcctRecordPO.getTaxCycle());
salaryAcctRecordPOS = salaryAcctRecordService.listBySalarySobIdsAndSalaryMonth(salarySobIds, taxCycleDateRange);
// 查询当前薪资核算人员所涉及的合并计税的所有薪资核算人员
Set<Long> salaryAcctRecordIds = SalaryEntityUtil.properties(salaryAcctRecordPOS, SalaryAcctRecordPO::getId);
salaryAcctEmployeePOS = salaryAcctEmployeeService.listByRecordIdsAndEmpIdAndTaxAgentId(salaryAcctRecordIds,
salaryAcctEmployeePO.getEmployeeId(), salaryAcctEmployeePO.getTaxAgentId());
}
// 查询薪资核算人员的薪资核算结果
Set<Long> salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId);
List<SalaryAcctResultPO> salaryAcctResultPOS = listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds);
// 查询薪资核算人员所有合并计税的薪资核算记录所用的账套
Set<Long> salarySobIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getSalarySobId);
List<SalarySobPO> salarySobPOS = salarySobService.listByIds(salarySobIds);
// 查询薪资项目所引用的薪资项目
List<SalarySobItemPO> salarySobItemPOS = salarySobItemService.listBySalarySobIds(salarySobIds);
// 查询薪资项目
Set<Long> salaryItemIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getSalaryItemId);
List<SalaryItemPO> salaryItemPOS = salaryItemService.listByIds(salaryItemIds);
// 转换成合并计税详情dto
return SalaryAcctResultBO.convert2ConsolidatedTaxDetailDTO(simpleEmployee, taxAgentPO, salarySobEmpFieldPOS, salaryItemPOS,
salaryAcctEmployeePOS, salarySobPOS, salaryAcctRecordPOS, salaryAcctResultPOS);
}
@Override
public void save(SalaryAcctResultSaveParam saveParam) {
// 查询薪资核算人员
SalaryAcctEmployeePO salaryAcctEmployeePO = salaryAcctEmployeeService.getById(saveParam.getSalaryAcctEmpId());
if (Objects.isNull(salaryAcctEmployeePO)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98831, "薪资核算人员不存在或已被删除"));
}
// 保存参数转换成薪资核算结果po
List<SalaryAcctResultPO> salaryAcctResultPOS = SalaryAcctResultBO.convert2PO(saveParam, salaryAcctEmployeePO, (long)user.getUID());
// 删除原来的薪资核算结果
deleteBySalaryAcctEmployeeIds(Collections.singleton(saveParam.getSalaryAcctEmpId()));
// 保存薪资核算结果
if (CollectionUtils.isNotEmpty(salaryAcctResultPOS)) {
salaryAcctResultMapper.batchInsert(salaryAcctResultPOS);
}
// 查询操作日志的targetName
String targetName = salaryAcctRecordService.getLogTargetNameById(salaryAcctEmployeePO.getSalaryAcctRecordId());
// 查询人员信息
DataCollectionEmployee simpleEmployee = hrmCommonEmployeeService.getEmployeeById(salaryAcctEmployeePO.getEmployeeId());
// 查询个税扣缴义务人
TaxAgent taxAgentPO = taxAgentService.getById(salaryAcctEmployeePO.getTaxAgentId());
// 记录日志
// String operateDesc = simpleEmployee.getUsername() + "(" + Optional.ofNullable(taxAgentPO).map(TaxAgentPO::getName).orElse(StringUtils.EMPTY) + ")";
// LoggerContext<SalaryCheckResultPO> 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<SalaryAcctResultPO> salaryAcctResultPOS) {
if (CollectionUtils.isNotEmpty(salaryAcctResultPOS)) {
salaryAcctResultMapper.batchInsert(salaryAcctResultPOS);
}
}
@Override
public void deleteBySalaryAcctEmployeeIds(Collection<Long> salaryAcctEmployeeIds) {
salaryAcctResultMapper.deleteBySalaryAcctEmpIds(salaryAcctEmployeeIds);
}
@Override
public void deleteByAcctEmployeeIdsAndSalaryItemIds(Collection<Long> salaryAcctEmployeeIds, Collection<Long> salaryItemIds) {
salaryAcctResultMapper.deleteByAcctEmpIdsAndSalaryItemIds(salaryAcctEmployeeIds, salaryItemIds);
}
@Override
public void deleteBySalaryAcctRecordIds(Collection<Long> salaryAcctRecordIds) {
salaryAcctResultMapper.deleteBySalaryAcctRecordIds(salaryAcctRecordIds);
}
@Override
public void calculate(SalaryAcctCalculateParam calculateParam, DataCollectionEmployee simpleEmployee) {
try {
// 1、查询薪资核算记录
SalaryAcctRecordPO salaryAcctRecordPO = salaryAcctRecordService.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 = salaryAcctRecordService.getSalarySobCycleById(calculateParam.getSalaryAcctRecordId());
// 3、查询薪资核算记录所用薪资账套的薪资项目副本
List<SalarySobItemPO> salarySobItemPOS = salarySobItemService.listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
if (CollectionUtils.isEmpty(salarySobItemPOS)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(99151, "当前所用的薪资账套未选择任何薪资项目,无法核算"));
}
// 4、查询当前租户的所有薪资项目
List<SalaryItemPO> salaryItemPOS = salaryItemService.listAll();
// 5、查询薪资核算记录所用薪资账套的调薪计薪规则
List<SalarySobAdjustRulePO> salarySobAdjustRulePOS = salarySobAdjustRuleService.listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
// todo 6、查询社保福利的所有字段
Map<String, String> welfareColumns = null;//siAccountService.welfareColumns(tenantKey);
// 7、查询考勤引用的所有字段
List<AttendQuoteFieldListDTO> attendQuoteFieldListDTOS = attendQuoteFieldService.listAll();
// 8、查询公式详情
Set<Long> formulaIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getFormulaId);
formulaIds.addAll(SalaryEntityUtil.properties(salaryItemPOS, SalaryItemPO::getFormulaId));
List<ExpressFormula> expressFormulas = salaryFormulaService.listExpressFormula(formulaIds);
// 9、计算薪资项目的运算优先级
List<List<Long>> salarySobItemsWithPriority = SalaryAcctCalculatePriorityBO.calculatePriority(salarySobItemPOS, salaryItemPOS, expressFormulas);
// 10、根据id查询其他合并计税的薪资核算记录
List<SalaryAcctRecordPO> otherSalaryAcctRecordPOS = salaryAcctRecordService.listById4OtherConsolidatedTax(salaryAcctRecordPO.getId());
// 11、查询本次核算人员
List<SalaryAcctEmployeePO> salaryAcctEmployeePOS;
if (CollectionUtils.isEmpty(calculateParam.getIds())) {
salaryAcctEmployeePOS = salaryAcctEmployeeService.listBySalaryAcctRecordId(salaryAcctRecordPO.getId());
} else {
salaryAcctEmployeePOS = salaryAcctEmployeeService.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);
// salaryAcctProgressService.initProgress("" + calculateParam.getSalaryAcctRecordId(), initProgress, simpleEmployee.getEmployeeId());
// 12、对薪资核算人员进行拆分
List<List<SalaryAcctEmployeePO>> partition = Lists.partition(salaryAcctEmployeePOS, 100);
// 12.1、监控子线程的任务执行
CountDownLatch childMonitor = new CountDownLatch(partition.size());
// 12.2、记录子线程的执行结果
BlockingDeque<SalaryAcctCalculateBO.Result> calculateResults = new LinkedBlockingDeque<>(partition.size());
// 12.3、生成本次运算的key
String calculateKey = UUID.randomUUID().toString();
// 12.4、多线程运算,运算结果存放在临时表中
for (List<SalaryAcctEmployeePO> 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() {
salaryAcctCalculateService.calculate(salaryAcctCalculateBO, simpleEmployee);
}
};
ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.OTHER, "salaryAcctCalculate", 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("|"));
// salaryAcctProgressService.fail("" + calculateParam.getSalaryAcctRecordId(), errorMsg);
// 删除薪资核算临时存储表中的数据
salaryAcctResultTempService.deleteByCalculateKey(calculateKey);
return;
}
// 15、处理核算结果临时表数据
handleSalaryAcctResultTemp(calculateParam, calculateKey);
// 16、开始运行校验规则
// SalaryAcctCheckParam salaryAcctCheckParam = new SalaryAcctCheckParam()
// .setSalaryAcctRecordId(calculateParam.getSalaryAcctRecordId())
// .setIds(calculateParam.getIds());
// salaryCheckResultService.check(salaryAcctCheckParam, true, simpleEmployee);
// 记录日志
// 查询操作日志的targetName
// String targetName = salaryAcctRecordService.getLogTargetNameById(calculateParam.getSalaryAcctRecordId());
// LoggerContext<SalaryCheckResultPO> 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);
// salaryAcctProgressService.fail("" + 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<SalaryAcctResultTempPO> salaryAcctResultTempPOS = salaryAcctResultTempService.listByCalculateKey(calculateKey);
// 删除原来的薪资核算结果
if (CollectionUtils.isNotEmpty(calculateParam.getIds())) {
salaryAcctResultMapper.deleteBySalaryAcctEmpIds(calculateParam.getIds());
} else {
salaryAcctResultMapper.deleteBySalaryAcctRecordIds(Collections.singleton(calculateParam.getSalaryAcctRecordId()));
}
// 保存薪资的薪资核算结果
List<SalaryAcctResultPO> salaryAcctResultPOS = SalaryAcctResultBO.convert2ResultPO(salaryAcctResultTempPOS);
batchSave(salaryAcctResultPOS);
// 删除薪资核算临时存储表中的数据
salaryAcctResultTempService.deleteByCalculateKey(calculateKey);
// 提交事务
dataSourceTransactionManager.commit(status);
} catch (Exception e) {
dataSourceTransactionManager.rollback(status);
throw e;
}
}
}