weaver-hrm-salary/src/com/engine/salary/service/impl/SalaryCalcTaxServiceImpl.java

307 lines
19 KiB
Java
Raw Normal View History

2024-06-06 13:51:33 +08:00
package com.engine.salary.service.impl;
2024-06-20 10:39:40 +08:00
import cn.hutool.core.collection.CollUtil;
2024-06-06 13:51:33 +08:00
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.constant.SzyhApiConstant;
import com.engine.salary.entity.employeedeclare.po.EmployeeDeclarePO;
import com.engine.salary.entity.salaryacct.bo.SalaryCalcTax;
import com.engine.salary.entity.salaryacct.dto.SalaryCalcTaxInfoDTO;
import com.engine.salary.entity.salaryacct.param.AbnormalEmployeeListQueryParam;
2024-06-06 13:51:33 +08:00
import com.engine.salary.entity.salaryacct.param.SalaryCalcTaxParam;
import com.engine.salary.entity.salaryacct.po.*;
2024-06-11 10:09:18 +08:00
import com.engine.salary.entity.salarysob.dto.SalarySobTaxRuleDTO;
2024-06-06 13:51:33 +08:00
import com.engine.salary.entity.salarysob.po.SalarySobTaxReportRulePO;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.entity.taxagent.po.TaxAgentTaxReturnPO;
import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationApiConfigPO;
import com.engine.salary.entity.taxdeclaration.po.TaxReportColumnPO;
import com.engine.salary.entity.taxdeclaration.response.DeclareTaxResponse;
2024-06-20 10:39:40 +08:00
import com.engine.salary.enums.common.SalaryLogOperateTypeEnum;
2024-06-06 13:51:33 +08:00
import com.engine.salary.enums.salarysob.IncomeCategoryEnum;
import com.engine.salary.enums.sicategory.DeleteTypeEnum;
2024-07-31 16:02:11 +08:00
import com.engine.salary.exception.OnlineCalculateTaxException;
2024-06-06 13:51:33 +08:00
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.remote.tax.client.CalculateClient;
import com.engine.salary.remote.tax.response.calculate.GetASynIndividualIncomeTaxFeedbackResponse;
import com.engine.salary.service.*;
import com.engine.salary.util.*;
import com.engine.salary.util.db.IdGenerator;
2024-07-31 13:17:35 +08:00
import lombok.extern.slf4j.Slf4j;
2024-06-06 13:51:33 +08:00
import org.apache.commons.collections4.CollectionUtils;
import weaver.hrm.User;
import java.util.*;
2024-07-31 13:17:35 +08:00
@Slf4j
2024-06-06 13:51:33 +08:00
public class SalaryCalcTaxServiceImpl extends Service implements SalaryCalcTaxService {
private SalaryAcctRecordService getSalaryAcctRecordService(User user) {
return ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user);
}
private SalaryAcctTaxAgentService getSalaryAcctTaxAgentService(User user) {
return ServiceUtil.getService(SalaryAcctTaxAgentServiceImpl.class, user);
}
private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) {
return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user);
}
private TaxAgentService getTaxAgentService(User user) {
return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
}
private TaxAgentTaxReturnService getTaxAgentTaxReturnService(User user) {
return ServiceUtil.getService(TaxAgentTaxReturnServiceImpl.class, user);
}
private TaxReportColumnService getTaxReportColumnService(User user) {
return ServiceUtil.getService(TaxReportColumnServiceImpl.class, user);
}
private SalarySobTaxReportRuleService getSalarySobTaxReportRuleService(User user) {
return ServiceUtil.getService(SalarySobTaxReportRuleServiceImpl.class, user);
}
2024-06-11 10:09:18 +08:00
private SalarySobTaxRuleService getSalarySobTaxRuleService(User user) {
return ServiceUtil.getService(SalarySobTaxRuleServiceImpl.class, user);
}
2024-06-06 13:51:33 +08:00
private EmployeeDeclareService getEmployeeDeclareService(User user) {
return ServiceUtil.getService(EmployeeDeclareServiceImpl.class, user);
}
private TaxDeclarationApiConfigService getTaxDeclarationApiConfigService(User user) {
return ServiceUtil.getService(TaxDeclarationApiConfigServiceImpl.class, user);
}
private SalaryAcctCalcTaxReqService getSalaryAcctCalcTaxReqService(User user) {
return ServiceUtil.getService(SalaryAcctCalcTaxReqServiceImpl.class, user);
}
private SalaryAcctResultService getSalaryAcctResultService(User user) {
return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user);
}
@Override
public SalaryCalcTaxInfoDTO getCalcTaxInfo(SalaryCalcTaxParam salaryCalcTaxParam) {
// 查询薪资核算记录
SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salaryCalcTaxParam.getSalaryAcctRecordId());
// 查询供应商信息
TaxDeclarationApiConfigPO apiConfig = getTaxDeclarationApiConfigService(user).getConfig(false);
// 查询在线计算个税记录
List<SalaryAcctCalcTaxReqPO> salaryAcctCalcTaxReqs = getSalaryAcctCalcTaxReqService(user).listByRecordId(salaryAcctRecord.getId());
boolean enableTaxDeclarationApiConfig = Objects.nonNull(apiConfig) && Objects.equals(apiConfig.getEnableUse(), 1);
boolean showCalcTaxButton = enableTaxDeclarationApiConfig && CollectionUtils.isEmpty(salaryAcctCalcTaxReqs);
boolean showCalcTaxFeedbackButton = enableTaxDeclarationApiConfig && CollectionUtils.isNotEmpty(salaryAcctCalcTaxReqs);
SalaryCalcTaxInfoDTO salaryCalcTaxInfo = new SalaryCalcTaxInfoDTO();
salaryCalcTaxInfo.setShowCalcTaxButton(showCalcTaxButton);
salaryCalcTaxInfo.setShowCalcTaxFeedbackButton(showCalcTaxFeedbackButton);
2024-07-17 11:05:30 +08:00
salaryCalcTaxInfo.setShowCalcAfterTaxButton(showCalcTaxFeedbackButton);
2024-06-06 13:51:33 +08:00
return salaryCalcTaxInfo;
}
@Override
public void calcTax(SalaryCalcTaxParam salaryCalcTaxParam) {
// 查询供应商信息
TaxDeclarationApiConfigPO apiConfig = getTaxDeclarationApiConfigService(user).getConfig(true);
if (apiConfig == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(160525, "接口流量不足,暂无法使用该功能,请先购买智能算薪接口流量"));
}
2024-06-20 10:39:40 +08:00
Long salaryAcctRecordId = salaryCalcTaxParam.getSalaryAcctRecordId();
int i = getSalaryAcctEmployeeService(user).countNotDeclareByParam(AbnormalEmployeeListQueryParam.builder().recordId(salaryAcctRecordId).build());
if (i > 0) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(11111, "存在未报送的人员,请先进行人员报送"));
}
2024-06-20 10:39:40 +08:00
List<SalaryAcctCalcTaxReqPO> reqs = getSalaryAcctCalcTaxReqService(user).listByRecordId(salaryAcctRecordId);
if (CollUtil.isNotEmpty(reqs)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(11111, "请先获取上一次在线算税结果"));
}
2024-06-06 13:51:33 +08:00
// 查询薪资核算记录
2024-06-20 10:39:40 +08:00
SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salaryAcctRecordId);
2024-06-06 13:51:33 +08:00
// 查询薪资核算记录关联的个税扣缴义务人
List<SalaryAcctTaxAgentPO> salaryAcctTaxAgents = getSalaryAcctTaxAgentService(user)
.listBySalaryAcctRecordIds(Collections.singleton(salaryAcctRecord.getId()));
// 查询薪资核算记录关联的薪资核算人员
List<SalaryAcctEmployeePO> salaryAcctEmployees = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordId(salaryAcctRecord.getId());
// 查询薪资核算记录关联的薪资核算结果
List<SalaryAcctResultPO> salaryAcctResultValues = getSalaryAcctResultService(user).listBySalaryAcctRecordIds(Collections.singleton(salaryAcctRecord.getId()));
// 查询个税扣缴义务人
Set<Long> taxAgentIds = SalaryEntityUtil.properties(salaryAcctTaxAgents, SalaryAcctTaxAgentPO::getTaxAgentId);
List<TaxAgentPO> taxAgents = getTaxAgentService(user).listByIds(taxAgentIds);
// 查询个税扣缴义务人关联的报税信息
List<TaxAgentTaxReturnPO> taxAgentTaxReturns = getTaxAgentTaxReturnService(user).getByTaxAgentIds(taxAgentIds);
// 查询个税申报表字段
2024-07-22 14:18:05 +08:00
List<TaxReportColumnPO> taxReportColumns = getTaxReportColumnService(user).listByContrastType(0);
2024-06-06 13:51:33 +08:00
// 查询薪资核算记录关联薪资账套的个税申报配置
List<SalarySobTaxReportRulePO> salarySobTaxReportRules = getSalarySobTaxReportRuleService(user)
.listBySalarySobIds(Collections.singleton(salaryAcctRecord.getSalarySobId()));
// 查询报送人员
List<EmployeeDeclarePO> employeeDeclares = getEmployeeDeclareService(user).listBySalaryAcctTaxAgent(salaryAcctTaxAgents);
List<SalaryAcctCalcTaxReqPO> salaryAcctCalcTaxReqs = new ArrayList<>();
Date now = new Date();
Map<String, String> params = new HashMap<>(1);
Map<String, String> header = SingnatureData.initHeader(params, apiConfig.getAppKey(), apiConfig.getAppSecret());
String url = apiConfig.getHost() + SzyhApiConstant.CALCULATE_ASYN_INDIVIDUAL_INCOME_TAX;
SalaryCalcTax salaryCalcTax = new SalaryCalcTax(salaryAcctRecord, salaryAcctTaxAgents, salaryAcctEmployees,
salaryAcctResultValues, taxAgents, taxAgentTaxReturns, taxReportColumns, salarySobTaxReportRules, employeeDeclares);
Map<Long, Map<String, Object>> taxAgentIdKeyRequestParam = salaryCalcTax.buildCalcTaxRequestParam();
for (Map.Entry<Long, Map<String, Object>> entry : taxAgentIdKeyRequestParam.entrySet()) {
String reqJson = JsonUtil.toJsonString(entry.getValue());
// 请求第三方供应商
String res = HttpUtil.doPost(url, header, reqJson, HttpUtil.JSON_TYPE);
2024-07-02 19:13:14 +08:00
TaskUtil taskUtil = new TaskUtil();
2024-07-15 16:59:10 +08:00
taskUtil.writeApiTaskRecord(salaryAcctRecordId + "", url, reqJson, res);
2024-06-06 13:51:33 +08:00
DeclareTaxResponse declareTaxResponse = JsonUtil.parseObject(res, DeclareTaxResponse.class);
if (Objects.isNull(declareTaxResponse) || Objects.isNull(declareTaxResponse.getHead())) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(156449, "服务异常"));
}
if (!Objects.equals(declareTaxResponse.getHead().getCode(), SzyhApiConstant.SUCCESS_CODE)) {
throw new SalaryRunTimeException(declareTaxResponse.getHead().getMsg());
}
SalaryAcctCalcTaxReqPO salaryAcctCalcTaxReq = new SalaryAcctCalcTaxReqPO();
salaryAcctCalcTaxReq.setId(IdGenerator.generate());
salaryAcctCalcTaxReq.setSalaryAcctRecordId(salaryAcctRecord.getId());
salaryAcctCalcTaxReq.setTaxAgentId(entry.getKey());
salaryAcctCalcTaxReq.setRequestId(declareTaxResponse.getBody().getRequestId());
salaryAcctCalcTaxReq.setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY);
salaryAcctCalcTaxReq.setCreator((long) user.getUID());
salaryAcctCalcTaxReq.setDeleteType(DeleteTypeEnum.NOT_DELETED.getValue());
salaryAcctCalcTaxReq.setCreateTime(now);
salaryAcctCalcTaxReq.setUpdateTime(now);
salaryAcctCalcTaxReqs.add(salaryAcctCalcTaxReq);
}
// 批量保存
getSalaryAcctCalcTaxReqService(user).batchSave(salaryAcctCalcTaxReqs);
// 记录日志
2024-06-20 10:39:40 +08:00
getSalaryAcctResultService(user).writeBatchLog(salaryAcctRecord, Collections.emptyMap(), SalaryLogOperateTypeEnum.CALC_TAX_ONLINE);
2024-06-06 13:51:33 +08:00
}
@Override
public void calcTaxFeedback(SalaryCalcTaxParam salaryCalcTaxParam) {
// 查询供应商信息
TaxDeclarationApiConfigPO apiConfig = getTaxDeclarationApiConfigService(user).getConfig(true);
if (apiConfig == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(160525, "接口流量不足,暂无法使用该功能,请先购买智能算薪接口流量"));
}
// 查询薪资核算记录
Long salaryAcctRecordId = salaryCalcTaxParam.getSalaryAcctRecordId();
SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salaryAcctRecordId);
2024-06-06 13:51:33 +08:00
// 查询薪资核算记录关联的薪资核算人员
List<SalaryAcctEmployeePO> salaryAcctEmployees = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordId(salaryAcctRecord.getId());
Map<String, List<SalaryAcctEmployeePO>> salaryAcctEmployeeMap = SalaryEntityUtil.group2Map(salaryAcctEmployees, e -> e.getTaxAgentId() + "-" + e.getIncomeCategory());
// 查询薪资核算记录关联的薪资核算结果
List<SalaryAcctResultPO> salaryAcctResultValues = getSalaryAcctResultService(user).listBySalaryAcctRecordIds(Collections.singleton(salaryAcctRecord.getId()));
Map<Long, Map<Long, SalaryAcctResultPO>> salaryAcctResultValueMap = SalaryEntityUtil.list2Map(salaryAcctResultValues, SalaryAcctResultPO::getSalaryAcctEmpId, SalaryAcctResultPO::getSalaryItemId);
// 查询薪资核算记录关联的个税扣缴义务人
List<SalaryAcctTaxAgentPO> salaryAcctTaxAgents = getSalaryAcctTaxAgentService(user)
.listBySalaryAcctRecordIds(Collections.singleton(salaryAcctRecord.getId()));
Map<Long, List<SalaryAcctTaxAgentPO>> salaryAcctTaxAgentMap = SalaryEntityUtil.group2Map(salaryAcctTaxAgents, SalaryAcctTaxAgentPO::getTaxAgentId);
// 查询薪资核算记录关联的异步算税请求记录
List<SalaryAcctCalcTaxReqPO> salaryAcctCalcTaxReqs = getSalaryAcctCalcTaxReqService(user).listByRecordId(salaryAcctRecord.getId());
if (CollectionUtils.isEmpty(salaryAcctCalcTaxReqs)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(268184, "请先计算个税再获取反馈"));
}
2024-06-11 10:09:18 +08:00
// 查询薪资核算记录关联的薪资账套个税字段对应
List<SalarySobTaxRuleDTO> salarySobTaxRules = getSalarySobTaxRuleService(user).getSalarySobTaxRuleDTO(salaryAcctRecord.getSalarySobId());
Map<String, SalarySobTaxRuleDTO> salarySobTaxRuleMap = SalaryEntityUtil.convert2Map(salarySobTaxRules, SalarySobTaxRuleDTO::getIncomeCategoryId);
2024-06-06 13:51:33 +08:00
// 查询报送人员
List<EmployeeDeclarePO> employeeDeclares = getEmployeeDeclareService(user).listBySalaryAcctTaxAgent(salaryAcctTaxAgents);
Map<Long, List<EmployeeDeclarePO>> employeeDeclareMap = SalaryEntityUtil.group2Map(employeeDeclares, EmployeeDeclarePO::getTaxAgentId);
List<SalaryAcctResultPO> addResultPOS = new ArrayList<>();
List<SalaryAcctResultPO> updateResultPOS = new ArrayList<>();
2024-06-06 13:51:33 +08:00
for (SalaryAcctCalcTaxReqPO salaryAcctCalcTaxReq : salaryAcctCalcTaxReqs) {
CalculateClient calculateClient = new CalculateClient(salaryAcctCalcTaxReq.getTaxAgentId());
GetASynIndividualIncomeTaxFeedbackResponse feedbackResponse = calculateClient.getASynIndividualIncomeTaxFeedback(salaryAcctCalcTaxReq.getRequestId());
List<SalaryAcctTaxAgentPO> subSalaryAcctTaxAgents = salaryAcctTaxAgentMap.get(salaryAcctCalcTaxReq.getTaxAgentId());
if (CollectionUtils.isEmpty(subSalaryAcctTaxAgents)) {
continue;
}
List<EmployeeDeclarePO> subEmployeeDeclares = employeeDeclareMap.get(salaryAcctCalcTaxReq.getTaxAgentId());
Date now = new Date();
2024-06-06 13:51:33 +08:00
// 获取不同所得项目的个税
for (SalaryAcctTaxAgentPO salaryAcctTaxAgent : subSalaryAcctTaxAgents) {
IncomeCategoryEnum incomeCategoryEnum = IncomeCategoryEnum.parseByValue(salaryAcctTaxAgent.getIncomeCategory());
if (incomeCategoryEnum == null) {
continue;
}
2024-06-11 10:09:18 +08:00
SalarySobTaxRuleDTO taxRuleDTO = salarySobTaxRuleMap.get(incomeCategoryEnum.getValue().toString());
2024-07-31 16:02:11 +08:00
Map<Long, SalarySobTaxRuleDTO> empIdResult;
try {
empIdResult = incomeCategoryEnum.parseGetASynIndividualIncomeTaxFeedbackResponse(feedbackResponse, subEmployeeDeclares, taxRuleDTO);
} catch (OnlineCalculateTaxException e) {
log.error("获取在线算税结果异常", e);
getSalaryAcctCalcTaxReqService(user).deleteByRecordId(salaryAcctRecord.getId());
throw new SalaryRunTimeException(e.getMessage());
}
2024-06-06 13:51:33 +08:00
List<SalaryAcctEmployeePO> subSalaryAcctEmployees = salaryAcctEmployeeMap.get(salaryAcctTaxAgent.getTaxAgentId() + "-" + salaryAcctTaxAgent.getIncomeCategory());
if (CollectionUtils.isEmpty(subSalaryAcctEmployees)) {
continue;
}
for (SalaryAcctEmployeePO salaryAcctEmployee : subSalaryAcctEmployees) {
Map<Long, SalaryAcctResultPO> salaryAcctResultValue = salaryAcctResultValueMap.get(salaryAcctEmployee.getId());
if (salaryAcctResultValue == null) {
continue;
}
2024-06-11 10:09:18 +08:00
SalarySobTaxRuleDTO salarySobTaxRuleDTO = empIdResult.get(salaryAcctEmployee.getEmployeeId());
2024-07-02 19:13:14 +08:00
if (salarySobTaxRuleDTO == null) {
continue;
}
2024-06-11 10:09:18 +08:00
List<SalarySobTaxRuleDTO.TaxRuleDTO> taxRules = salarySobTaxRuleDTO.getTaxRules();
2024-07-15 16:59:10 +08:00
taxRules.stream()
.filter(rule -> rule.getSalaryItemId() != null)
.forEach(rule -> {
Long salaryItemId = rule.getSalaryItemId();
SalaryAcctResultPO salaryAcctResultPO = salaryAcctResultValue.get(salaryItemId);
if (salaryAcctResultPO != null) {
salaryAcctResultPO.setResultValue(rule.getValue());
updateResultPOS.add(salaryAcctResultPO);
} else {
salaryAcctResultPO = SalaryAcctResultPO.builder()
.salaryAcctRecordId(salaryAcctRecordId)
.salaryAcctEmpId(salaryAcctEmployee.getId())
.employeeId(salaryAcctEmployee.getEmployeeId())
.taxAgentId(salaryAcctEmployee.getTaxAgentId())
.salarySobId(salaryAcctEmployee.getSalarySobId())
.salaryItemId(salaryItemId)
.resultValue(rule.getValue())
.originResultValue("")
.creator((long) user.getUID())
.createTime(now)
.updateTime(now)
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.deleteType(0)
.build();
addResultPOS.add(salaryAcctResultPO);
}
});
2024-06-06 13:51:33 +08:00
}
}
}
getSalaryAcctResultService(user).batchSave(addResultPOS);
getSalaryAcctResultService(user).batchUpdate(updateResultPOS);
2024-06-06 13:51:33 +08:00
getSalaryAcctCalcTaxReqService(user).deleteByRecordId(salaryAcctRecord.getId());
// 记录日志
2024-06-20 10:39:40 +08:00
getSalaryAcctResultService(user).writeBatchLog(salaryAcctRecord, Collections.emptyMap(), SalaryLogOperateTypeEnum.GET_CALC_TAX_FEEDBACK);
2024-06-06 13:51:33 +08:00
}
}