package com.engine.salary.entity.taxdeclaration.bo; import cn.hutool.core.util.NumberUtil; import com.engine.salary.entity.datacollection.po.*; import com.engine.salary.entity.employeedeclare.po.EmployeeDeclarePO; import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationPO; import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationValuePO; import com.engine.salary.entity.taxdeclaration.po.TaxReportColumnPO; import com.engine.salary.enums.datacollection.TaxFreeTypeEnum; import com.engine.salary.enums.employeedeclare.CardTypeEnum; import com.engine.salary.enums.salaryitem.SalaryDataTypeEnum; import com.engine.salary.enums.salarysob.IncomeCategoryEnum; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryEntityUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import weaver.general.Util; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; /** * 个税申报 *

Copyright: Copyright (c) 2023

*

Company: 泛微软件

* * @author qiantao * @version 1.0 **/ public class TaxDeclarationRequest { public static Map convert2RequestParam(List taxReportColumns, List taxDeclarations, List taxDeclarationValues, List employeeDeclares, Map> taxFreeMap) { Map> objRequestParam = Maps.newHashMap(); Map>> listRequestParam = Maps.newHashMap(); Map> taxReportColumnMap = SalaryEntityUtil.group2Map(taxReportColumns, TaxReportColumnPO::getIncomeCategory); Map employeeDeclareMap = SalaryEntityUtil.convert2Map(employeeDeclares, EmployeeDeclarePO::getEmployeeId); Map> taxDeclarationValueMap = SalaryEntityUtil.group2Map(taxDeclarationValues, TaxDeclarationValuePO::getTaxDeclarationId); for (TaxDeclarationPO taxDeclaration : taxDeclarations) { List values = taxDeclarationValueMap.get(taxDeclaration.getId()); for (TaxDeclarationValuePO taxDeclarationValue : values) { EmployeeDeclarePO employeeDeclare = employeeDeclareMap.get(taxDeclarationValue.getEmployeeId()); IncomeCategoryEnum incomeCategoryEnum = IncomeCategoryEnum.parseByValue(taxDeclaration.getIncomeCategory()); if (employeeDeclare == null || incomeCategoryEnum == null) { continue; } List taxReportColumnList = taxReportColumnMap.get(Util.null2String(incomeCategoryEnum.getValue())); Map employeeRequestParam = convert2RequestParam(incomeCategoryEnum, taxReportColumnList, taxDeclarationValue, employeeDeclare); if (incomeCategoryEnum == IncomeCategoryEnum.WAGES_AND_SALARIES) { Map paramMap = objRequestParam.computeIfAbsent("zcgzxj", k -> { Map param = new HashMap<>(); // 正常工资薪金列表 param.put("zcgzxjlb", Lists.newArrayList()); // 正常工资薪金是否需要专项 param.put("zcgzxjsfxyzx", 0); // 正常工资薪金是否传入专项累计 param.put("zcgzxjsfcrlj", 1); return param; }); List> employeeRequestParams = (List>) paramMap.computeIfAbsent("zcgzxjlb", K -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.ONETIME_ANNUAL_BONUS) { // 全年一次性奖金收入 List> employeeRequestParams = listRequestParam.computeIfAbsent("qnycxjjsslb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.COMPENSATION_FOR_RETIRE) { // 内退一次性补偿金 List> employeeRequestParams = listRequestParam.computeIfAbsent("ntycxbcjlb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.COMPENSATION_FOR_DISMISS) { // 解除劳动合同一次性补偿金 List> employeeRequestParams = listRequestParam.computeIfAbsent("jcldhtycxbcjlb", k -> Lists.newArrayList()); employeeRequestParam.put("sfzdscmsfb", "是"); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.INCOME_FOR_INDIVIDUAL_EQUITY_INCENTIVE) { // 个人股权激励收入 List> employeeRequestParams = listRequestParam.computeIfAbsent("grgqjl", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.ANNUITY_RECEIPT) { // 处理"是否一次性领取"(接口只能传0和1但是接口的错误返回信息告知只能填写是和否,所以需要转一下) String sfycxlq = Util.null2String(employeeRequestParam.get("sfycxlq")); employeeRequestParam.put("sfycxlq", Objects.equals("是", sfycxlq) ? "1" : "0"); // 年金领取 List> employeeRequestParams = listRequestParam.computeIfAbsent("qynj", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.REMUNERATION_FOR_LABOR) { // 一般劳务报酬所得 List> employeeRequestParams = listRequestParam.computeIfAbsent("lwbclb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.INCOME_FOR_INSURANCE_SALESMAN) { // 保险营销员佣金收入 Map paramMap = objRequestParam.computeIfAbsent("bxyxy", k -> { Map param = new HashMap<>(); param.put("bxyxylwbclb", Lists.newArrayList()); return param; }); List> employeeRequestParams = (List>) paramMap.computeIfAbsent("bxyxylwbclb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.INCOME_FOR_SECURITIES_BROKER) { // 证券经纪人佣金收入 Map paramMap = objRequestParam.computeIfAbsent("zqjjr", k -> { Map param = new HashMap<>(); param.put("zqjjrsdlb", Lists.newArrayList()); return param; }); List> employeeRequestParams = (List>) paramMap.computeIfAbsent("zqjjrsdlb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.REMUNERATION_FOR_OTHER_CONTINUOUS_LABOR) { // 其他连续劳务报酬所得 Map paramMap = objRequestParam.computeIfAbsent("qtlxlwbc", k -> { Map param = new HashMap<>(); param.put("qtlxlwbclb", Lists.newArrayList()); return param; }); List> employeeRequestParams = (List>) paramMap.computeIfAbsent("qtlxlwbclb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.REMUNERATION_FOR_OTHER_LABOR) { // 其他非连续劳务报酬所得 List> employeeRequestParams = listRequestParam.computeIfAbsent("qtflxlwbc", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.REMUNERATION_FOR_AUTHOR) { // 稿酬所得 List> employeeRequestParams = listRequestParam.computeIfAbsent("gcsdlb", k -> Lists.newArrayList()); employeeRequestParam.put("sfzdscmsfb", "是"); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.ROYALTIES) { // 特许权使用费所得 List> employeeRequestParams = listRequestParam.computeIfAbsent("txq", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } // 其他免税扣除附表 buildOtherDeductionDetailParams(taxFreeMap, listRequestParam, employeeDeclare, incomeCategoryEnum, employeeRequestParam); } } Map requestParam = Maps.newHashMap(); requestParam.putAll(objRequestParam); requestParam.putAll(listRequestParam); return requestParam; } private static void buildOtherDeductionDetailParams(Map> taxFreeMap, Map>> listRequestParam, EmployeeDeclarePO employeeDeclare, IncomeCategoryEnum incomeCategoryEnum, Map employeeRequestParam) { String mssd = employeeRequestParam.getOrDefault("mssd", "0").toString(); if (NumberUtil.isNumber(mssd) && new BigDecimal(mssd).compareTo(new BigDecimal("0")) > 0) { Map freeIncomeMap = taxFreeMap.get(TaxFreeTypeEnum.FREE_INCOME); List poList = (List) freeIncomeMap.get(employeeDeclare.getTaxAgentId() + "-" + employeeDeclare.getEmployeeId() + "-" + SalaryDateUtil.getFormatYearMonth(employeeDeclare.getTaxCycle())); if (CollectionUtils.isNotEmpty(poList)) { List> paramMaps = new ArrayList<>(); for (FreeIncomePO po : poList) { Map map = new HashMap<>(); // 姓名 map.put("xm", employeeDeclare.getEmployeeName()); // 证件类型 map.put("zzlx", CardTypeEnum.RESIDENT_IDENTITY_CARDS.getDefaultLabel()); // 证件号码 map.put("zzhm", employeeDeclare.getCardNum()); // 所得项目 map.put("sdxm", incomeCategoryEnum.getDefaultLabel()); map.put("jmsx", po.getFreeItem()); map.put("jmxz", po.getFreeProperty()); map.put("sjkcje", po.getFreeAmount()); paramMaps.add(map); } listRequestParam.put("msfblb", paramMaps); } } String syjkbx = employeeRequestParam.getOrDefault("syjkbx", "0").toString(); if (NumberUtil.isNumber(syjkbx) && new BigDecimal(syjkbx).compareTo(new BigDecimal("0")) > 0) { Map healthInsuranceMap = taxFreeMap.get(TaxFreeTypeEnum.HEALTH_INSURANCE); List pos = (List) healthInsuranceMap.get(employeeDeclare.getTaxAgentId() + "-" + employeeDeclare.getEmployeeId() + "-" + SalaryDateUtil.getFormatYearMonth(employeeDeclare.getTaxCycle())); if (CollectionUtils.isNotEmpty(pos)) { List> paramMaps = new ArrayList<>(); for (HealthInsurancePO healthInsurancePO : pos) { Map map = new HashMap<>(); // 姓名 map.put("xm", employeeDeclare.getEmployeeName()); // 证件类型 map.put("zzlx", CardTypeEnum.RESIDENT_IDENTITY_CARDS.getDefaultLabel()); // 证件号码 map.put("zzhm", employeeDeclare.getCardNum()); // 所得项目 map.put("sdxm", incomeCategoryEnum.getDefaultLabel()); map.put("bdsxrq", SalaryDateUtil.getFormatLocalDate(healthInsurancePO.getEffectiveDate())); map.put("sysbm", healthInsurancePO.getIdentificationNumber()); map.put("ndbf", healthInsurancePO.getYearPremium()); map.put("ydbf", healthInsurancePO.getMonthPremium()); map.put("sjkcje", healthInsurancePO.getCurrentDeduction()); paramMaps.add(map); } listRequestParam.put("syjkbxfblb", paramMaps); } } String syylbx = employeeRequestParam.getOrDefault("syylbx", "0").toString(); if (NumberUtil.isNumber(syylbx) && new BigDecimal(syylbx).compareTo(new BigDecimal("0")) > 0) { Map posMap = taxFreeMap.get(TaxFreeTypeEnum.ENDOWMENT_INSURANCE); List pos = (List) posMap.get(employeeDeclare.getTaxAgentId() + "-" + employeeDeclare.getEmployeeId() + "-" + SalaryDateUtil.getFormatYearMonth(employeeDeclare.getTaxCycle())); if (CollectionUtils.isNotEmpty(pos)) { List> paramMaps = new ArrayList<>(); for (EndowmentInsurancePO po : pos) { Map map = new HashMap<>(); // 姓名 map.put("xm", employeeDeclare.getEmployeeName()); // 证件类型 map.put("zzlx", CardTypeEnum.RESIDENT_IDENTITY_CARDS.getDefaultLabel()); // 证件号码 map.put("zzhm", employeeDeclare.getCardNum()); // 所得项目 map.put("sdxm", incomeCategoryEnum.getDefaultLabel()); map.put("sbkcyf", SalaryDateUtil.getFormatYearMonth((po.getDeductionMonth()))); map.put("syylzhbh", po.getAccountNumber()); map.put("bsjym", po.getCheckCode()); map.put("ndbf", po.getYearPremium()); map.put("ydbf", po.getMonthPremium()); map.put("sjkcje", po.getCurrentDeduction()); paramMaps.add(map); } listRequestParam.put("syjkbxfblb", paramMaps); } } String zykcjze = employeeRequestParam.getOrDefault("zykcjze", "0").toString(); if (NumberUtil.isNumber(zykcjze) && new BigDecimal(zykcjze).compareTo(new BigDecimal("0")) > 0) { Map posMap = taxFreeMap.get(TaxFreeTypeEnum.GRANT_DONATION); List pos = (List) posMap.get(employeeDeclare.getTaxAgentId() + "-" + employeeDeclare.getEmployeeId() + "-" + SalaryDateUtil.getFormatYearMonth(employeeDeclare.getTaxCycle())); if (CollectionUtils.isNotEmpty(pos)) { List> paramMaps = new ArrayList<>(); for (GrantDonationPO po : pos) { Map map = new HashMap<>(); // 姓名 map.put("xm", employeeDeclare.getEmployeeName()); // 证件类型 map.put("zzlx", CardTypeEnum.RESIDENT_IDENTITY_CARDS.getDefaultLabel()); // 证件号码 map.put("zzhm", employeeDeclare.getCardNum()); // 所得项目 map.put("sdxm", incomeCategoryEnum.getDefaultLabel()); map.put("szdwmc", po.getRecipientName()); map.put("szdwnsrsbh", po.getTaxCode()); map.put("jzpzh", po.getDonationNumber()); if (po.getDonateDate() != null) { map.put("jzrq", SalaryDateUtil.getFormatLocalDate(po.getDonateDate())); } map.put("jzje", po.getDonateAmount()); map.put("kcbl", po.getDeductionProportion()); map.put("sjkcje", po.getActualDeduction()); paramMaps.add(map); } listRequestParam.put("zykcjzefb", paramMaps); } } String jmse = employeeRequestParam.getOrDefault("jmse", "0").toString(); if (NumberUtil.isNumber(jmse) && new BigDecimal(jmse).compareTo(new BigDecimal("0")) > 0) { Map posMap = taxFreeMap.get(TaxFreeTypeEnum.DERATE_DEDUCTION); List pos = (List) posMap.get(employeeDeclare.getTaxAgentId() + "-" + employeeDeclare.getEmployeeId() + "-" + SalaryDateUtil.getFormatYearMonth(employeeDeclare.getTaxCycle())); if (CollectionUtils.isNotEmpty(pos)) { List> paramMaps = new ArrayList<>(); for (DerateDeductionPO po : pos) { Map map = new HashMap<>(); // 姓名 map.put("xm", employeeDeclare.getEmployeeName()); // 证件类型 map.put("zzlx", CardTypeEnum.RESIDENT_IDENTITY_CARDS.getDefaultLabel()); // 证件号码 map.put("zzhm", employeeDeclare.getCardNum()); // 所得项目 map.put("sdxm", incomeCategoryEnum.getDefaultLabel()); map.put("jmsx", po.getDerateItem()); map.put("jmxz", po.getDerateProperty()); map.put("sjkcje", po.getDerateAmount()); paramMaps.add(map); } listRequestParam.put("jmfblb", paramMaps); } } String qt = employeeRequestParam.getOrDefault("qt", "0").toString(); if (NumberUtil.isNumber(qt) && new BigDecimal(qt).compareTo(new BigDecimal("0")) > 0) { Map posMap = taxFreeMap.get(TaxFreeTypeEnum.OTHER_DERATE_DEDUCTION); List pos = (List) posMap.get(employeeDeclare.getTaxAgentId() + "-" + employeeDeclare.getEmployeeId() + "-" + SalaryDateUtil.getFormatYearMonth(employeeDeclare.getTaxCycle())); if (CollectionUtils.isNotEmpty(pos)) { employeeRequestParam.put("bz", pos.get(0).getRemark()); } } } private static Map convert2RequestParam(IncomeCategoryEnum incomeCategoryEnum, List taxReportColumns, TaxDeclarationValuePO taxDeclarationValue, EmployeeDeclarePO employeeDeclare) { if (CollectionUtils.isEmpty(taxReportColumns)) { return Collections.emptyMap(); } Map requestParam = Maps.newHashMap(); // 姓名 requestParam.put("xm", employeeDeclare.getEmployeeName()); // 证件类型 requestParam.put("zzlx", CardTypeEnum.getByValue(employeeDeclare.getCardType()).getDefaultLabel()); // 证件号码 requestParam.put("zzhm", employeeDeclare.getCardNum()); // 所得项目 requestParam.put("sdxm", incomeCategoryEnum.getDefaultLabel()); for (TaxReportColumnPO taxReportColumn : taxReportColumns) { String value = taxDeclarationValue.getResultValue().getOrDefault(taxReportColumn.getReportColumnDataIndex(), StringUtils.EMPTY); if (Objects.equals(taxReportColumn.getDataType(), SalaryDataTypeEnum.NUMBER.getValue())) { value = SalaryEntityUtil.string2BigDecimalDefault0(taxDeclarationValue.getResultValue().get(taxReportColumn.getReportColumnDataIndex())).toPlainString(); } else if (Objects.equals(taxReportColumn.getDataType(), "integer")) { value = SalaryEntityUtil.string2BigDecimalDefault0(taxDeclarationValue.getResultValue().get(taxReportColumn.getReportColumnDataIndex())).setScale(0, RoundingMode.HALF_UP).toPlainString(); } requestParam.put(taxReportColumn.getRequestParamKey(), value); } return requestParam; } public static Map convert2flsdRequestParam(List taxReportColumns, List taxDeclarations, List taxDeclarationValues, List employeeDeclares) { Map> objRequestParam = Maps.newHashMap(); Map>> listRequestParam = Maps.newHashMap(); Map> taxReportColumnMap = SalaryEntityUtil.group2Map(taxReportColumns, TaxReportColumnPO::getIncomeCategory); Map employeeDeclareMap = SalaryEntityUtil.convert2Map(employeeDeclares, EmployeeDeclarePO::getEmployeeId); Map> taxDeclarationValueMap = SalaryEntityUtil.group2Map(taxDeclarationValues, TaxDeclarationValuePO::getTaxDeclarationId); for (TaxDeclarationPO taxDeclaration : taxDeclarations) { List values = taxDeclarationValueMap.get(taxDeclaration.getId()); for (TaxDeclarationValuePO taxDeclarationValue : values) { EmployeeDeclarePO employeeDeclare = employeeDeclareMap.get(taxDeclarationValue.getEmployeeId()); IncomeCategoryEnum incomeCategoryEnum = IncomeCategoryEnum.parseByValue(taxDeclaration.getIncomeCategory()); if (employeeDeclare == null || incomeCategoryEnum == null) { continue; } List taxReportColumnList = taxReportColumnMap.get(Util.null2String(incomeCategoryEnum.getValue())); Map employeeRequestParam = convert2RequestParam(incomeCategoryEnum, taxReportColumnList, taxDeclarationValue, employeeDeclare); if (incomeCategoryEnum == IncomeCategoryEnum.CLASSIFIED_INCOME_LISTED_COMPANY_DIVIDENDS_BONUSES) { // 上市公司股息红利所得(沪市、深市、创业板) List> employeeRequestParams = listRequestParam.computeIfAbsent("ssgsgxhllb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } if (incomeCategoryEnum == IncomeCategoryEnum.CLASSIFIED_INCOME_OTHER_INTEREST_DIVIDENDS_BONUSES) { // 其他利息股息红利所得 List> employeeRequestParams = listRequestParam.computeIfAbsent("lxgxhllb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } } } Map requestParam = Maps.newHashMap(); requestParam.putAll(objRequestParam); requestParam.putAll(listRequestParam); return requestParam; } public static Map convert2fjmsdRequestParam(List taxReportColumns, List taxDeclarations, List taxDeclarationValues, List employeeDeclares) { Map> objRequestParam = Maps.newHashMap(); Map>> listRequestParam = Maps.newHashMap(); Map> taxReportColumnMap = SalaryEntityUtil.group2Map(taxReportColumns, TaxReportColumnPO::getIncomeCategory); Map employeeDeclareMap = SalaryEntityUtil.convert2Map(employeeDeclares, EmployeeDeclarePO::getEmployeeId); Map> taxDeclarationValueMap = SalaryEntityUtil.group2Map(taxDeclarationValues, TaxDeclarationValuePO::getTaxDeclarationId); for (TaxDeclarationPO taxDeclaration : taxDeclarations) { List values = taxDeclarationValueMap.get(taxDeclaration.getId()); for (TaxDeclarationValuePO taxDeclarationValue : values) { EmployeeDeclarePO employeeDeclare = employeeDeclareMap.get(taxDeclarationValue.getEmployeeId()); IncomeCategoryEnum incomeCategoryEnum = IncomeCategoryEnum.parseByValue(taxDeclaration.getIncomeCategory()); if (employeeDeclare == null || incomeCategoryEnum == null) { continue; } List taxReportColumnList = taxReportColumnMap.get(Util.null2String(incomeCategoryEnum.getValue())); Map employeeRequestParam = convert2RequestParam(incomeCategoryEnum, taxReportColumnList, taxDeclarationValue, employeeDeclare); if (incomeCategoryEnum == IncomeCategoryEnum.NON_RESIDENT_INCOME_WAGES_AND_SALARIES) { // 无住所个人正常工资薪金 List> employeeRequestParams = listRequestParam.computeIfAbsent("wjgzxjlb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.NON_RESIDENT_INCOME_MONTHLY_BONUS) { // 全年一次性奖金收入 List> employeeRequestParams = listRequestParam.computeIfAbsent("wjrysyjjlb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.NON_RESIDENT_INCOME_REMUNERATION_FOR_LABOR) { // 内退一次性补偿金 List> employeeRequestParams = listRequestParam.computeIfAbsent("lwbclb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } else if (incomeCategoryEnum == IncomeCategoryEnum.NON_RESIDENT_INCOME_COMPENSATION_FOR_DISMISS) { // 解除劳动合同一次性补偿金 List> employeeRequestParams = listRequestParam.computeIfAbsent("jcldhtycxbcjlb", k -> Lists.newArrayList()); employeeRequestParams.add(employeeRequestParam); } } } Map requestParam = Maps.newHashMap(); requestParam.putAll(objRequestParam); requestParam.putAll(listRequestParam); return requestParam; } }