package com.engine.salary.service.impl; 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.bo.SalaryCalcTaxFeedback; import com.engine.salary.entity.salaryacct.dto.SalaryCalcTaxInfoDTO; import com.engine.salary.entity.salaryacct.param.SalaryCalcTaxParam; import com.engine.salary.entity.salaryacct.po.*; 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; import com.engine.salary.enums.salarysob.IncomeCategoryEnum; import com.engine.salary.enums.sicategory.DeleteTypeEnum; 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; import org.apache.commons.collections4.CollectionUtils; import weaver.hrm.User; import java.time.LocalDateTime; import java.util.*; 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); } 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 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.setEnableTaxDeclarationApiConfig(enableTaxDeclarationApiConfig); salaryCalcTaxInfo.setShowCalcTaxButton(showCalcTaxButton); salaryCalcTaxInfo.setShowCalcTaxFeedbackButton(showCalcTaxFeedbackButton); return salaryCalcTaxInfo; } @Override public void calcTax(SalaryCalcTaxParam salaryCalcTaxParam) { // 查询供应商信息 TaxDeclarationApiConfigPO apiConfig = getTaxDeclarationApiConfigService(user).getConfig(true); if (apiConfig == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(160525, "接口流量不足,暂无法使用该功能,请先购买智能算薪接口流量")); } // 查询薪资核算记录 SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salaryCalcTaxParam.getSalaryAcctRecordId()); // 查询薪资核算记录关联的个税扣缴义务人 List salaryAcctTaxAgents = getSalaryAcctTaxAgentService(user) .listBySalaryAcctRecordIds(Collections.singleton(salaryAcctRecord.getId())); // 查询薪资核算记录关联的薪资核算人员 List salaryAcctEmployees = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordId(salaryAcctRecord.getId()); // 查询薪资核算记录关联的薪资核算结果 List salaryAcctResultValues = getSalaryAcctResultService(user).listBySalaryAcctRecordIds(Collections.singleton(salaryAcctRecord.getId())); // 查询个税扣缴义务人 Set taxAgentIds = SalaryEntityUtil.properties(salaryAcctTaxAgents, SalaryAcctTaxAgentPO::getTaxAgentId); List taxAgents = getTaxAgentService(user).listByIds(taxAgentIds); // 查询个税扣缴义务人关联的报税信息 List taxAgentTaxReturns = getTaxAgentTaxReturnService(user).getByTaxAgentIds(taxAgentIds); // 查询个税申报表字段 List taxReportColumns = getTaxReportColumnService(user).listAll(); // 查询薪资核算记录关联薪资账套的个税申报配置 List salarySobTaxReportRules = getSalarySobTaxReportRuleService(user) .listBySalarySobIds(Collections.singleton(salaryAcctRecord.getSalarySobId())); // 查询报送人员 List employeeDeclares = getEmployeeDeclareService(user).listBySalaryAcctTaxAgent(salaryAcctTaxAgents); List salaryAcctCalcTaxReqs = new ArrayList<>(); Date now = new Date(); Map params = new HashMap<>(1); Map 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> taxAgentIdKeyRequestParam = salaryCalcTax.buildCalcTaxRequestParam(); for (Map.Entry> entry : taxAgentIdKeyRequestParam.entrySet()) { String reqJson = JsonUtil.toJsonString(entry.getValue()); // 请求第三方供应商 String res = HttpUtil.doPost(url, header, reqJson, HttpUtil.JSON_TYPE); 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); // 记录日志 String operateTypeName = SalaryI18nUtil.getI18nLabel(268191, "在线计算个税"); // 记录日志 // getSalaryAcctResultService(user).writeBatchLog(salaryAcctRecord, Collections.emptyMap(), SalaryLogOperateTypeEnum.CALC_TAX_ONLINE); } @Override public void calcTaxFeedback(SalaryCalcTaxParam salaryCalcTaxParam) { // 查询供应商信息 TaxDeclarationApiConfigPO apiConfig = getTaxDeclarationApiConfigService(user).getConfig(true); if (apiConfig == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(160525, "接口流量不足,暂无法使用该功能,请先购买智能算薪接口流量")); } // 查询薪资核算记录 SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salaryCalcTaxParam.getSalaryAcctRecordId()); // 查询薪资核算记录关联的薪资核算人员 List salaryAcctEmployees = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordId(salaryAcctRecord.getId()); Map> salaryAcctEmployeeMap = SalaryEntityUtil.group2Map(salaryAcctEmployees, e -> e.getTaxAgentId() + "-" + e.getIncomeCategory()); // 查询薪资核算记录关联的薪资核算结果 List salaryAcctResultValues = getSalaryAcctResultService(user).listBySalaryAcctRecordIds(Collections.singleton(salaryAcctRecord.getId())); Map> salaryAcctResultValueMap = SalaryEntityUtil.list2Map(salaryAcctResultValues, SalaryAcctResultPO::getSalaryAcctEmpId, SalaryAcctResultPO::getSalaryItemId); // 查询薪资核算记录关联的个税扣缴义务人 List salaryAcctTaxAgents = getSalaryAcctTaxAgentService(user) .listBySalaryAcctRecordIds(Collections.singleton(salaryAcctRecord.getId())); Map> salaryAcctTaxAgentMap = SalaryEntityUtil.group2Map(salaryAcctTaxAgents, SalaryAcctTaxAgentPO::getTaxAgentId); // 查询薪资核算记录关联的异步算税请求记录 List salaryAcctCalcTaxReqs = getSalaryAcctCalcTaxReqService(user).listByRecordId(salaryAcctRecord.getId()); if (CollectionUtils.isEmpty(salaryAcctCalcTaxReqs)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(268184, "请先计算个税再获取反馈")); } // 查询薪资核算记录关联的薪资账套个税申报表字段对应 List salarySobTaxReportRules = getSalarySobTaxReportRuleService(user).listBySalarySobIds(Collections.singleton(salaryAcctRecord.getSalarySobId())); Map salarySobTaxReportRuleMap = SalaryEntityUtil.convert2Map(salarySobTaxReportRules, SalarySobTaxReportRulePO::getReportColumnDataIndex); // 查询报送人员 List employeeDeclares = getEmployeeDeclareService(user).listBySalaryAcctTaxAgent(salaryAcctTaxAgents); Map> employeeDeclareMap = SalaryEntityUtil.group2Map(employeeDeclares, EmployeeDeclarePO::getTaxAgentId); String url = apiConfig.getHost() + SzyhApiConstant.ASYN_INDIVIDUAL_INCOME_TAX_FEEDBACK; Map header = SingnatureData.initHeader(Collections.emptyMap(), apiConfig.getAppKey(), apiConfig.getAppSecret()); List resultPOS = new ArrayList<>(); for (SalaryAcctCalcTaxReqPO salaryAcctCalcTaxReq : salaryAcctCalcTaxReqs) { CalculateClient calculateClient = new CalculateClient(salaryAcctCalcTaxReq.getTaxAgentId()); GetASynIndividualIncomeTaxFeedbackResponse feedbackResponse = calculateClient.getASynIndividualIncomeTaxFeedback(salaryAcctCalcTaxReq.getRequestId()); if (Objects.isNull(feedbackResponse) || Objects.isNull(feedbackResponse.getHead())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(156449, "服务异常")); } if (!Objects.equals(feedbackResponse.getHead().getCode(), SzyhApiConstant.SUCCESS_CODE)) { throw new SalaryRunTimeException(feedbackResponse.getHead().getMsg()); } List subSalaryAcctTaxAgents = salaryAcctTaxAgentMap.get(salaryAcctCalcTaxReq.getTaxAgentId()); if (CollectionUtils.isEmpty(subSalaryAcctTaxAgents)) { continue; } List subEmployeeDeclares = employeeDeclareMap.get(salaryAcctCalcTaxReq.getTaxAgentId()); // 获取不同所得项目的个税 for (SalaryAcctTaxAgentPO salaryAcctTaxAgent : subSalaryAcctTaxAgents) { IncomeCategoryEnum incomeCategoryEnum = IncomeCategoryEnum.parseByValue(salaryAcctTaxAgent.getIncomeCategory()); if (incomeCategoryEnum == null) { continue; } Map empIdResult = incomeCategoryEnum.parseGetASynIndividualIncomeTaxFeedbackResponse(feedbackResponse, subEmployeeDeclares); Map dataMap = null; // switch (incomeCategoryEnum) { // case WAGES_AND_SALARIES: // dataMap = JsonUtil.parseMap(ZHSDMap.get("zcgzxj"), Object.class); // break; // case ONETIME_ANNUAL_BONUS: // dataMap = JsonUtil.parseMap(ZHSDMap.get("qnycxjjsslb"), Object.class); // break; // case COMPENSATION_FOR_RETIRE: // dataMap = JsonUtil.parseMap(ZHSDMap.get("ntycxbcjlb"), Object.class); // break; // case COMPENSATION_FOR_DISMISS: // dataMap = JsonUtil.parseMap(ZHSDMap.get("jcldhtycxbcjlb"), Object.class); // break; // case INCOME_FOR_INDIVIDUAL_EQUITY_INCENTIVE: // dataMap = JsonUtil.parseMap(ZHSDMap.get("grgqjl"), Object.class); // break; // case ANNUITY_RECEIPT: // dataMap = JsonUtil.parseMap(ZHSDMap.get("qynj"), Object.class); // break; // case REMUNERATION_FOR_LABOR: // dataMap = JsonUtil.parseMap(ZHSDMap.get("lwbclb"), Object.class); // break; // case INCOME_FOR_INSURANCE_SALESMAN: // dataMap = JsonUtil.parseMap(ZHSDMap.get("bxyxy"), Object.class); // break; // case INCOME_FOR_SECURITIES_BROKER: // dataMap = JsonUtil.parseMap(ZHSDMap.get("zqjjr"), Object.class); // break; // case REMUNERATION_FOR_OTHER_CONTINUOUS_LABOR: // dataMap = JsonUtil.parseMap(ZHSDMap.get("qtlxlwbc"), Object.class); // break; // case REMUNERATION_FOR_OTHER_LABOR: // dataMap = JsonUtil.parseMap(ZHSDMap.get("qtflxlwbc"), Object.class); // break; // case REMUNERATION_FOR_AUTHOR: // dataMap = JsonUtil.parseMap(ZHSDMap.get("gcsdlb"), Object.class); // break; // case ROYALTIES: // dataMap = JsonUtil.parseMap(ZHSDMap.get("txq"), Object.class); // break; // default: // dataMap = Collections.emptyMap(); // break; // } Map employeeIdKeyTaxMap; SalaryCalcTaxFeedback salaryCalcTaxFeedback = new SalaryCalcTaxFeedback(dataMap, subEmployeeDeclares); if (incomeCategoryEnum == IncomeCategoryEnum.WAGES_AND_SALARIES) { employeeIdKeyTaxMap = salaryCalcTaxFeedback.buildZCGZXJFeedback(); } else { employeeIdKeyTaxMap = salaryCalcTaxFeedback.buildOtherFeedback(); } LocalDateTime now = LocalDateTime.now(); List subSalaryAcctEmployees = salaryAcctEmployeeMap.get(salaryAcctTaxAgent.getTaxAgentId() + "-" + salaryAcctTaxAgent.getIncomeCategory()); if (CollectionUtils.isEmpty(subSalaryAcctEmployees)) { continue; } for (SalaryAcctEmployeePO salaryAcctEmployee : subSalaryAcctEmployees) { Map salaryAcctResultValue = salaryAcctResultValueMap.get(salaryAcctEmployee.getId()); if (salaryAcctResultValue == null) { continue; } SalarySobTaxReportRulePO salarySobTaxReportRule = salarySobTaxReportRuleMap.get("refundedOrSupplementedTax" + salaryAcctEmployee.getIncomeCategory()); if (salarySobTaxReportRule != null) { SalaryAcctResultPO salaryAcctResultPO = salaryAcctResultValue.get(salarySobTaxReportRule.getSalaryItemId()); salaryAcctResultPO.setResultValue(employeeIdKeyTaxMap.get(salaryAcctEmployee.getEmployeeId())); resultPOS.add(salaryAcctResultPO); } } } } getSalaryAcctResultService(user).batchUpdate(resultPOS); getSalaryAcctCalcTaxReqService(user).deleteByRecordId(salaryAcctRecord.getId()); // 记录日志 // getSalaryAcctResultService(user).writeBatchLog(salaryAcctRecord, Collections.emptyMap(), SalaryLogOperateTypeEnum.GET_CALC_TAX_FEEDBACK); } }