diff --git a/src/com/engine/salary/config/SalaryPermissionConfig.java b/src/com/engine/salary/config/SalaryPermissionConfig.java index 7703e9267..61abe6086 100644 --- a/src/com/engine/salary/config/SalaryPermissionConfig.java +++ b/src/com/engine/salary/config/SalaryPermissionConfig.java @@ -22,11 +22,11 @@ //@Configuration //public class SalaryPermissionConfig { // -// @Autowired +// // private PermissionConfig permissionConfig; -// @Autowired +// // private PermissionModuleSourceService permissionModuleSourceService; -// @Autowired +// // private PermissionModuleTargetService permissionModuleTargetService; // // public static final String TABLE_NAME = "hrsa"; diff --git a/src/com/engine/salary/constant/SzyhApiConstant.java b/src/com/engine/salary/constant/SzyhApiConstant.java index 608bf61a4..ae932a07d 100644 --- a/src/com/engine/salary/constant/SzyhApiConstant.java +++ b/src/com/engine/salary/constant/SzyhApiConstant.java @@ -147,6 +147,25 @@ public class SzyhApiConstant { */ public static final String GET_COMPANY_INCOMES = "gateway/iit/report/getCompanyIncomes"; + /** + * 个人养老金下载 + */ + public static final String DOWNLOAD_PERSONAL_PENSION = "gateway/iit/personalPension/download"; + /** + * 获取个人养老金下载反馈 + */ + public static final String DOWNLOAD_PERSONAL_PENSION_FEEDBACK = "gateway/iit/personalPension/getDownloadFeedback"; + /** + * 异步计算个税 + */ + public static final String CALCULATE_ASYN_INDIVIDUAL_INCOME_TAX = "gateway/iit/calculateTax/calculateASynIndividualIncomeTax"; + /** + * 查询算税反馈结果 + */ + public static final String ASYN_INDIVIDUAL_INCOME_TAX_FEEDBACK = "gateway/iit/calculateTax/getASynIndividualIncomeTaxFeedback"; + + + /** * 请求成功状态码 diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcTax.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcTax.java new file mode 100644 index 000000000..3dab288f0 --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcTax.java @@ -0,0 +1,199 @@ +package com.engine.salary.entity.salaryacct.bo; + +import com.engine.salary.entity.employeedeclare.po.EmployeeDeclarePO; +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.SalaryAcctTaxAgentPO; +import com.engine.salary.entity.salarysob.po.SalarySobTaxReportRulePO; +import com.engine.salary.entity.taxagent.bo.TaxAgentTaxReturnBO; +import com.engine.salary.entity.taxagent.po.TaxAgentPO; +import com.engine.salary.entity.taxagent.po.TaxAgentTaxReturnPO; +import com.engine.salary.entity.taxdeclaration.po.TaxReportColumnPO; +import com.engine.salary.enums.salarysob.IncomeCategoryEnum; +import com.engine.salary.exception.SalaryRunTimeException; +import com.engine.salary.util.SalaryDateUtil; +import com.engine.salary.util.SalaryEntityUtil; +import com.engine.salary.util.SalaryI18nUtil; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 薪资核算计算个税 + * + * @author xiajun + */ +@Data +@AllArgsConstructor +public class SalaryCalcTax { + + /** + * 薪资核算记录 + */ + private SalaryAcctRecordPO salaryAcctRecord; + + /** + * 薪资核算关联的个税扣缴义务人 + */ + private List salaryAcctTaxAgents; + + /** + * 薪资核算关联的薪资核算人员 + */ + private List salaryAcctEmployees; + + /** + * 薪资核算关联的薪资核算结果 + */ + private List salaryAcctResultValues; + + /** + * 个税扣缴义务人 + */ + private List taxAgents; + + /** + * 个税扣缴义务人的个税信息 + */ + private List taxAgentTaxReturns; + + /** + * 个税申报表字段 + */ + private List taxReportColumns; + + /** + * 薪资账套的个税申报表字段对应 + */ + private List salarySobTaxReportRules; + + /** + * 报送人员 + */ + private List employeeDeclares; + + public Map> buildCalcTaxRequestParam() { + // 薪资核算关联的个税扣缴义务人 + Map> salaryAcctAgentMap = SalaryEntityUtil.group2Map(salaryAcctTaxAgents, SalaryAcctTaxAgentPO::getTaxAgentId); + // 薪资核算关联的薪资核算人员 + Map> salaryAcctEmployeeMap = SalaryEntityUtil.group2Map(salaryAcctEmployees, SalaryAcctEmployeePO::getTaxAgentId); + // 薪资核算关联的薪资核算结果 + Map> salaryAcctResultValueMap = SalaryEntityUtil.group2Map(salaryAcctResultValues, SalaryAcctResultPO::getSalaryAcctEmpId); + // 个税扣款义务人 + Map taxAgentMap = SalaryEntityUtil.convert2Map(taxAgents, TaxAgentPO::getId); + // 个税扣款义务人的个税信息 + Map taxAgentTaxReturnMap = SalaryEntityUtil.convert2Map(taxAgentTaxReturns, TaxAgentTaxReturnPO::getTaxAgentId); + // 个税申报表字段 + Map> taxReportColumnMap = SalaryEntityUtil.group2Map(taxReportColumns, TaxReportColumnPO::getIncomeCategory); + // 薪资账套的个税申报表字段对应 + Map salarySobTaxReportRuleMap = SalaryEntityUtil.convert2Map(salarySobTaxReportRules, SalarySobTaxReportRulePO::getReportColumnDataIndex); + // 报送人员 + Map> employeeDeclareMap = SalaryEntityUtil.group2Map(employeeDeclares, EmployeeDeclarePO::getTaxAgentId); + + Map> resultMap = new HashMap<>(); + + for (Map.Entry> entry : salaryAcctAgentMap.entrySet()) { + TaxAgentPO taxAgent = taxAgentMap.get(entry.getKey()); + if (taxAgent == null) { + throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0, "个税扣缴义务人不存在或已被删除")); + } + TaxAgentTaxReturnPO taxAgentTaxReturn = taxAgentTaxReturnMap.get(taxAgent.getId()); + if (taxAgentTaxReturn == null) { + throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0, "个税扣缴义务人没有维护个税信息")); + } + List salaryAcctEmployees = salaryAcctEmployeeMap.get(taxAgent.getId()); + if (CollectionUtils.isEmpty(salaryAcctEmployees)) { + continue; + } + List employeeDeclares = employeeDeclareMap.get(taxAgent.getId()); + if (CollectionUtils.isEmpty(employeeDeclares)) { + throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0, "该个税扣缴义务人无申报人员")); + } + + // 注册的企业信息-->请求参数 + Map requestParam = TaxAgentTaxReturnBO.convert2RequestMap(taxAgent, taxAgentTaxReturn); + // 税款所属期 + requestParam.put("skssq", SalaryDateUtil.getFormatYYYYMM(entry.getValue().get(0).getTaxCycle())); + // 综合所得 + requestParam.put("zhsd", buildZHSDRequestParam(salaryAcctTaxAgents, salaryAcctEmployees, + salaryAcctResultValueMap, taxReportColumnMap, salarySobTaxReportRuleMap, employeeDeclares)); + + resultMap.put(taxAgent.getId(), requestParam); + } + return resultMap; + } + + private Map buildZHSDRequestParam(List salaryAcctTaxAgents, + List salaryAcctEmployees, + Map> salaryAcctResultValueMap, + Map> taxReportColumnMap, + Map salarySobTaxReportRuleMap, + List employeeDeclares) { + Map> incomeCategoryKeySalaryAcctEmployeeMap = SalaryEntityUtil + .group2Map(salaryAcctEmployees, SalaryAcctEmployeePO::getIncomeCategory); + + Map requestParam = new HashMap<>(); + + for (SalaryAcctTaxAgentPO salaryAcctTaxAgent : salaryAcctTaxAgents) { + IncomeCategoryEnum incomeCategoryEnum = IncomeCategoryEnum + .parseByValue(salaryAcctTaxAgent.getIncomeCategory()); + List taxReportColumns = taxReportColumnMap.get(incomeCategoryEnum.getValue().toString()); + List subSalaryAcctEmployees = incomeCategoryKeySalaryAcctEmployeeMap.get(incomeCategoryEnum.getValue().toString()); + Map salaryAcctEmployeeMap = SalaryEntityUtil.convert2Map(subSalaryAcctEmployees, SalaryAcctEmployeePO::getEmployeeId); + + SalaryCalcTaxRequest salaryCalcTaxRequest = new SalaryCalcTaxRequest(salaryAcctEmployeeMap, + salaryAcctResultValueMap, taxReportColumns, salarySobTaxReportRuleMap, employeeDeclares); + + switch (incomeCategoryEnum) { + case WAGES_AND_SALARIES: + requestParam.put("zcgzxj", salaryCalcTaxRequest.buildZCGZXJRequestParam()); + break; + case ONETIME_ANNUAL_BONUS: + requestParam.put("qnycxjjsslb", salaryCalcTaxRequest.buildQNYCXJJSSLBRequestParam()); + break; + case COMPENSATION_FOR_RETIRE: + requestParam.put("ntycxbcjlb", salaryCalcTaxRequest.buildNTYCXBCJLBRequestParam()); + break; + case COMPENSATION_FOR_DISMISS: + requestParam.put("jcldhtycxbcjlb", salaryCalcTaxRequest.buildJCLDHTYCXBCJLBRequestParam()); + break; + case INCOME_FOR_INDIVIDUAL_EQUITY_INCENTIVE: + requestParam.put("grgqjl", salaryCalcTaxRequest.buildGRGQJLRequestParam()); + break; + case ANNUITY_RECEIPT: + requestParam.put("qynj", salaryCalcTaxRequest.buildQYNJRequestParam()); + break; + case REMUNERATION_FOR_LABOR: + requestParam.put("lwbclb", salaryCalcTaxRequest.buildLWBCLBRequestParam()); + break; + case INCOME_FOR_INSURANCE_SALESMAN: + requestParam.put("bxyxy", salaryCalcTaxRequest.buildBXYXYRequestParam()); + break; + case INCOME_FOR_SECURITIES_BROKER: + requestParam.put("zqjjr", salaryCalcTaxRequest.buildZQJJRRequestParam()); + break; + case REMUNERATION_FOR_OTHER_CONTINUOUS_LABOR: + requestParam.put("qtlxlwbc", salaryCalcTaxRequest.buildQTLXLWBCRequestParam()); + break; + case REMUNERATION_FOR_OTHER_LABOR: + requestParam.put("qtflxlwbc", salaryCalcTaxRequest.buildQTFLXLWBCRequestParam()); + break; + case REMUNERATION_FOR_AUTHOR: + requestParam.put("gcsdlb", salaryCalcTaxRequest.buildGCSDLBRequestParam()); + break; + case ROYALTIES: + requestParam.put("txq", salaryCalcTaxRequest.buildTXQRequestParam()); + break; + default: + break; + + } + } + return requestParam; + } +} diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcTaxFeedback.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcTaxFeedback.java new file mode 100644 index 000000000..70963b916 --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcTaxFeedback.java @@ -0,0 +1,62 @@ +package com.engine.salary.entity.salaryacct.bo; + +import com.engine.salary.entity.employeedeclare.po.EmployeeDeclarePO; +import com.engine.salary.util.JsonUtil; +import lombok.Data; +import weaver.general.Util; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 异步算税的反馈结果 + */ +@Data +public class SalaryCalcTaxFeedback { + + private Map dataMap; + + private List employeeDeclares; + + public SalaryCalcTaxFeedback(Map dataMap, List employeeDeclares) { + this.dataMap = dataMap; + this.employeeDeclares = employeeDeclares; + } + + public Map buildZCGZXJFeedback() { + Map successDataMap = new HashMap<>(); + List successList = JsonUtil.parseList(dataMap.get("sscglb"), Map.class); + for (Map map : successList) { + // 证件号码 + String zzhm = Util.null2String(map.get("zzhm")); + // 应补退税额 + String ybtse = Util.null2String(map.get("ybtse")); + + successDataMap.put(zzhm, ybtse); + } + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), successDataMap.get(employeeDeclare.getCardNum())); + } + return resultMap; + } + + public Map buildOtherFeedback() { + Map successDataMap = new HashMap<>(); + List successList = JsonUtil.parseList(dataMap.get("sscglb"), Map.class); + for (Map map : successList) { + // 证件号码 + String zzhm = Util.null2String(map.get("zzhm")); + // 应补退税额 + String ybtse = Util.null2String(map.get("yingkjse")); + + successDataMap.put(zzhm, ybtse); + } + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), successDataMap.get(employeeDeclare.getCardNum())); + } + return resultMap; + } +} diff --git a/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcTaxRequest.java b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcTaxRequest.java new file mode 100644 index 000000000..cca1f16ff --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/bo/SalaryCalcTaxRequest.java @@ -0,0 +1,258 @@ +package com.engine.salary.entity.salaryacct.bo; + +import com.engine.salary.entity.employeedeclare.bo.EmployeeDeclareRequest; +import com.engine.salary.entity.employeedeclare.po.EmployeeDeclarePO; +import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO; +import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO; +import com.engine.salary.entity.salarysob.po.SalarySobTaxReportRulePO; +import com.engine.salary.entity.taxdeclaration.po.TaxReportColumnPO; +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.SalaryEntityUtil; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.wbi.util.Util; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; + +@Data +@AllArgsConstructor +public class SalaryCalcTaxRequest { + + private Map salaryAcctEmployeeMap; + private Map> salaryAcctResultValueMap; + private List taxReportColumns; + private Map salarySobTaxReportRuleMap; + private List employeeDeclares; + + /** + * 正常工资薪金 + * + * @return + */ + public Map buildZCGZXJRequestParam() { + // 人员列表 + List> RYLBRequestParam = EmployeeDeclareRequest.convert2RequestParam(employeeDeclares); + // 正常工资薪金列表 + List> ZCGZXJLBRequestParams = buildRequestParams(IncomeCategoryEnum.WAGES_AND_SALARIES, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + + Map param = new HashMap<>(); + // 人员列表 + param.put("rylb", RYLBRequestParam); + // 正常工资薪金列表 + param.put("zcgzxjlb", ZCGZXJLBRequestParams); + // 正常工资薪金是否需要专项 + param.put("zcgzxjsfxyzx", 0); + // 正常工资薪金是否传入专项累计 + param.put("zcgzxjsfcrlj", 1); + // 是否传入累计个人养老金,2使用传入数据 + param.put("gryljcl", 2); + + return param; + } + + /** + * 全年一次性奖金收入 + * + * @return + */ + public List> buildQNYCXJJSSLBRequestParam() { + return buildRequestParams(IncomeCategoryEnum.ONETIME_ANNUAL_BONUS, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + } + + /** + * 稿酬所得 + * + * @return + */ + public List> buildGCSDLBRequestParam() { + return buildRequestParams(IncomeCategoryEnum.REMUNERATION_FOR_AUTHOR, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + } + + /** + * 一般劳务报酬所得 + * + * @return + */ + public List> buildLWBCLBRequestParam() { + return buildRequestParams(IncomeCategoryEnum.REMUNERATION_FOR_LABOR, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + } + + /** + * 解除劳动合同一次性补偿金 + * + * @return + */ + public List> buildJCLDHTYCXBCJLBRequestParam() { + return buildRequestParams(IncomeCategoryEnum.COMPENSATION_FOR_DISMISS, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + } + + /** + * 保险营销员佣金收入 + * + * @return + */ + public Map buildBXYXYRequestParam() { + List> requestParams = buildRequestParams(IncomeCategoryEnum.INCOME_FOR_INSURANCE_SALESMAN, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + + Map param = new HashMap<>(); + // 保险营销员薪金列表 + param.put("bxyxylwbclb", requestParams); + // 是否传入累计个人养老金,2使用传入数据 + param.put("gryljcl", 2); + return param; + } + + /** + * 证券经纪人佣金收入 + * + * @return + */ + public Map buildZQJJRRequestParam() { + List> requestParams = buildRequestParams(IncomeCategoryEnum.INCOME_FOR_SECURITIES_BROKER, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + + Map param = new HashMap<>(); + // 证券经纪人薪金列表 + param.put("zqjjrsdlb", requestParams); + // 是否传入累计个人养老金,2使用传入数据 + param.put("gryljcl", 2); + return param; + } + + /** + * 其他连续劳务报酬所得 + * + * @return + */ + public Map buildQTLXLWBCRequestParam() { + List> requestParams = buildRequestParams(IncomeCategoryEnum.REMUNERATION_FOR_OTHER_CONTINUOUS_LABOR, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + + Map param = new HashMap<>(); + param.put("qtlxlwbclb", Lists.newArrayList()); + // 是否传入累计个人养老金,2使用传入数据 + param.put("gryljcl", 2); + return param; + } + + /** + * 特许权使用费所得 + * + * @return + */ + public List> buildTXQRequestParam() { + return buildRequestParams(IncomeCategoryEnum.ROYALTIES, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + } + + /** + * 个人股权激励收入 + * + * @return + */ + public List> buildGRGQJLRequestParam() { + return buildRequestParams(IncomeCategoryEnum.INCOME_FOR_INDIVIDUAL_EQUITY_INCENTIVE, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + } + + /** + * 年金领取 + * + * @return + */ + public List> buildQYNJRequestParam() { + return buildRequestParams(IncomeCategoryEnum.ANNUITY_RECEIPT, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + } + + /** + * 内退一次性补偿金 + * + * @return + */ + public List> buildNTYCXBCJLBRequestParam() { + return buildRequestParams(IncomeCategoryEnum.COMPENSATION_FOR_RETIRE, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + } + + /** + * 其他非连续劳务报酬所得 + * + * @return + */ + public List> buildQTFLXLWBCRequestParam() { + return buildRequestParams(IncomeCategoryEnum.REMUNERATION_FOR_OTHER_LABOR, + employeeDeclares, salaryAcctEmployeeMap, salaryAcctResultValueMap); + } + + private List> buildRequestParams(IncomeCategoryEnum incomeCategoryEnum, + List employeeDeclares, + Map salaryAcctEmployeeMap, + Map> salaryAcctResultValueMap) { + List> requestParams = Lists.newArrayListWithExpectedSize(salaryAcctResultValueMap.size()); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + SalaryAcctEmployeePO salaryAcctEmployee = salaryAcctEmployeeMap.get(employeeDeclare.getEmployeeId()); + if (salaryAcctEmployee == null) { + continue; + } + List salaryAcctResultValue = salaryAcctResultValueMap.get(salaryAcctEmployee.getId()); + if (salaryAcctResultValue == null) { + continue; + } + Map map = SalaryEntityUtil.convert2Map(salaryAcctResultValue, SalaryAcctResultPO::getSalaryItemId, SalaryAcctResultPO::getResultValue); + Map requestParam = buildRequestParam(incomeCategoryEnum, employeeDeclare, map); + if (MapUtils.isNotEmpty(requestParam)) { + requestParams.add(requestParam); + } + } + return requestParams; + } + + private Map buildRequestParam(IncomeCategoryEnum incomeCategoryEnum, + EmployeeDeclarePO employeeDeclare, + Map salaryAcctResultValue) { + if (CollectionUtils.isEmpty(taxReportColumns)) { + return Collections.emptyMap(); + } + Map requestParam = Maps.newHashMap(); + // 姓名 + requestParam.put("xm", employeeDeclare.getEmployeeName()); + // 证件类型 + requestParam.put("zzlx", CardTypeEnum.RESIDENT_IDENTITY_CARDS.getDefaultLabel()); + // 证件号码 + requestParam.put("zzhm", employeeDeclare.getCardNum()); + // 所得项目 + requestParam.put("sdxm", incomeCategoryEnum.getDefaultLabel()); + + for (TaxReportColumnPO taxReportColumn : taxReportColumns) { + Long dataKey = null; + SalarySobTaxReportRulePO salarySobTaxReportRule = salarySobTaxReportRuleMap.get(taxReportColumn.getReportColumnDataIndex()); + if (salarySobTaxReportRule != null && salarySobTaxReportRule.getSalaryItemId() != null) { + dataKey = salarySobTaxReportRule.getSalaryItemId(); + } + String value = salaryAcctResultValue.getOrDefault(dataKey, StringUtils.EMPTY); + if (Objects.equals(taxReportColumn.getDataType(), SalaryDataTypeEnum.NUMBER.getValue())) { + value = Util.getBigDecimalValue(value, BigDecimal.ZERO).toPlainString(); + } else if (Objects.equals(taxReportColumn.getDataType(), "integer")) { + value = Util.getBigDecimalValue(value, BigDecimal.ZERO).setScale(0, RoundingMode.HALF_UP).toPlainString(); + } + requestParam.put(taxReportColumn.getRequestParamKey(), value); + } + return requestParam; + } +} diff --git a/src/com/engine/salary/entity/salaryacct/dto/SalaryCalcTaxInfoDTO.java b/src/com/engine/salary/entity/salaryacct/dto/SalaryCalcTaxInfoDTO.java new file mode 100644 index 000000000..554f98f9d --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/dto/SalaryCalcTaxInfoDTO.java @@ -0,0 +1,27 @@ +package com.engine.salary.entity.salaryacct.dto; + +import lombok.Data; + +/** + * 薪资核算计算个税 + * + * @author xiajun + */ +@Data +public class SalaryCalcTaxInfoDTO { + + /** + * 是否开启智能算薪 + */ + private boolean enableTaxDeclarationApiConfig; + + /** + * 是否显示计算个税按钮 + */ + private boolean showCalcTaxButton; + + /** + * 是否显示获取个税计算反馈按钮 + */ + private boolean showCalcTaxFeedbackButton; +} diff --git a/src/com/engine/salary/entity/salaryacct/param/SalaryCalcTaxParam.java b/src/com/engine/salary/entity/salaryacct/param/SalaryCalcTaxParam.java new file mode 100644 index 000000000..d4745f149 --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/param/SalaryCalcTaxParam.java @@ -0,0 +1,19 @@ +package com.engine.salary.entity.salaryacct.param; + +import com.engine.salary.util.valid.DataCheck; +import lombok.Data; + +/** + * 薪资核算计算个税 + * + * @author xiajun + */ +@Data +public class SalaryCalcTaxParam { + + /** + * 参数错误,薪资核算记录ID不能为空 + */ + @DataCheck(require = true,message = "薪资核算记录ID不能为空") + private Long salaryAcctRecordId; +} diff --git a/src/com/engine/salary/entity/salaryacct/po/SalaryAcctCalcTaxReqPO.java b/src/com/engine/salary/entity/salaryacct/po/SalaryAcctCalcTaxReqPO.java new file mode 100644 index 000000000..a325a71a1 --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/po/SalaryAcctCalcTaxReqPO.java @@ -0,0 +1,52 @@ +package com.engine.salary.entity.salaryacct.po; + +import com.engine.hrmelog.annotation.ElogTransform; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.util.Collection; +import java.util.Date; + +@Data +@Builder +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@ElogTransform(name = "薪资核算在线计算个税请求") +//hrsa_acct_calc_tax_req +public class SalaryAcctCalcTaxReqPO { + + @ElogTransform(name = "主键id", ignore = true) + private Long id; + + @ElogTransform(name = "薪资核算记录", ignore = true) + private Long salaryAcctRecordId; + + @ElogTransform(name = "个税扣缴义务人id", ignore = true) + private Long taxAgentId; + + @ElogTransform(name = "请求requestId", ignore = true) + private String requestId; + + @ElogTransform(name = "租户key", ignore = true) + private String tenantKey; + + @ElogTransform(name = "创建人id", ignore = true) + private Long creator; + + @ElogTransform(name = "是否删除", ignore = true) + private Integer deleteType; + + @ElogTransform(name = "创建时间", ignore = true) + private Date createTime; + + @ElogTransform(name = "更新时间", ignore = true) + private Date updateTime; + + //--------条件---------- + //主键id集合 + private Collection ids; +} diff --git a/src/com/engine/salary/enums/salarysob/IncomeCategoryEnum.java b/src/com/engine/salary/enums/salarysob/IncomeCategoryEnum.java index fbce1c59b..9d7c9c427 100644 --- a/src/com/engine/salary/enums/salarysob/IncomeCategoryEnum.java +++ b/src/com/engine/salary/enums/salarysob/IncomeCategoryEnum.java @@ -1,7 +1,10 @@ package com.engine.salary.enums.salarysob; +import com.engine.salary.entity.employeedeclare.po.EmployeeDeclarePO; import com.engine.salary.enums.BaseEnum; +import com.engine.salary.remote.tax.response.calculate.GetASynIndividualIncomeTaxFeedbackResponse; import com.engine.salary.remote.tax.response.declare.GetDeclareTaxResultFeedbackResponse; +import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.excel.ExcelUtil; import com.google.common.collect.Lists; import org.apache.commons.collections4.CollectionUtils; @@ -21,155 +24,325 @@ public enum IncomeCategoryEnum implements BaseEnum { // todo 多语言 WAGES_AND_SALARIES(1, "0101", "正常工资薪金", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 160487) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getZcgzxj().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getZcgzxj().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, REMUNERATION_FOR_LABOR(4, "0400", "一般劳务报酬所得", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 160488) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getLwbclb().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getLwbclb().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, ONETIME_ANNUAL_BONUS(2, "0103", "全年一次性奖金收入", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 160489) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getQnycxjjsslb().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getQnycxjjsslb().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, COMPENSATION_FOR_RETIRE(107, "0107", "内退一次性补偿金", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 181936) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getNtycxbcjlb().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getNtycxbcjlb().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, COMPENSATION_FOR_DISMISS(108, "0108", "解除劳动合同一次性补偿金", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 181937) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getJcldhtycxbcjlb().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getJcldhtycxbcjlb().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, INCOME_FOR_INDIVIDUAL_EQUITY_INCENTIVE(109, "0109", "个人股权激励收入", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 181938) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getGrgqjl().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getGrgqjl().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, ANNUITY_RECEIPT(110, "0110", "年金领取", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 181939) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getQynj().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getQynj().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, INCOME_FOR_INSURANCE_SALESMAN(402, "0402", "保险营销员佣金收入", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 181940) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getBxyxy().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getBxyxy().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, INCOME_FOR_SECURITIES_BROKER(403, "0403", "证券经纪人佣金收入", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 181942) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getZqjjr().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getZqjjr().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, REMUNERATION_FOR_OTHER_CONTINUOUS_LABOR(489, "0489", "其他连续劳务报酬所得", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 181943) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getQtlxlwbc().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getQtlxlwbc().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, REMUNERATION_FOR_OTHER_LABOR(499, "0499", "其他非连续劳务报酬所得", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 175330) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getQtflxlwbc().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getQtflxlwbc().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, REMUNERATION_FOR_AUTHOR(500, "0500", "稿酬所得", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 181944) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getGcsdlb().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getGcsdlb().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, ROYALTIES(600, "0600", "特许权使用费所得", DeclareReportTypeEnum.COMPREHENSIVE_INCOME, 181945) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List zhsd = declareTaxResultFeedbackResponse.getBody().getZhsd().getTxq().getSscglb(); List> zhsdSheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.zhsd.zcgzxj.zhsdscjgbw.class, zhsd); result.put(this.getDefaultLabel(), zhsdSheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getZhsd().getTxq().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, NON_RESIDENT_INCOME_WAGES_AND_SALARIES(700, "0700", "无住所个人正常工资薪金", DeclareReportTypeEnum.NONRESIDENT_INCOME, 181945) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List fjmsd = declareTaxResultFeedbackResponse.getBody().getFjmsd().getWjgzxjlb().getSscglb(); List> sheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.fjmsd.fjmsdssjgdx.fjmsdscbw.class, fjmsd); result.put(this.getDefaultLabel(), sheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getFjmsd().getWjgzxjlb().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, NON_RESIDENT_INCOME_MONTHLY_BONUS(710, "0710", "无住所个人数月奖金", DeclareReportTypeEnum.NONRESIDENT_INCOME, 181945) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List fjmsd = declareTaxResultFeedbackResponse.getBody().getFjmsd().getWjrysyjjlb().getSscglb(); List> sheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.fjmsd.fjmsdssjgdx.fjmsdscbw.class, fjmsd); result.put(this.getDefaultLabel(), sheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getFjmsd().getWjrysyjjlb().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }, NON_RESIDENT_INCOME_REMUNERATION_FOR_LABOR(720, "0720", "一般劳务报酬所得", DeclareReportTypeEnum.NONRESIDENT_INCOME, 181945) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List fjmsd = declareTaxResultFeedbackResponse.getBody().getFjmsd().getLwbclb().getSscglb(); List> sheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.fjmsd.fjmsdssjgdx.fjmsdscbw.class, fjmsd); result.put(this.getDefaultLabel(), sheetData); - return result; } + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getFjmsd().getLwbclb().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; + } + }, NON_RESIDENT_INCOME_COMPENSATION_FOR_DISMISS(730, "0730", "解除劳动合同一次性补偿金", DeclareReportTypeEnum.NONRESIDENT_INCOME, 181945) { @Override - public Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { + public void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse) { List fjmsd = declareTaxResultFeedbackResponse.getBody().getFjmsd().getJcldhtycxbcjlb().getSscglb(); List> sheetData = ExcelUtil.getExcelSheetData(GetDeclareTaxResultFeedbackResponse.Body.fjmsd.fjmsdssjgdx.fjmsdscbw.class, fjmsd); result.put(this.getDefaultLabel(), sheetData); - return result; + } + + @Override + public Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares) { + List sscglb = declareTaxResultFeedbackResponse.getBody().getFjmsd().getJcldhtycxbcjlb().getSscglb(); + Map idNoResultMap = SalaryEntityUtil.convert2Map(sscglb, GetASynIndividualIncomeTaxFeedbackResponse.Body.result::getZzhm); + Map resultMap = new HashMap<>(); + for (EmployeeDeclarePO employeeDeclare : employeeDeclares) { + resultMap.put(employeeDeclare.getEmployeeId(), idNoResultMap.get(employeeDeclare.getCardNum())); + } + return resultMap; } }; @@ -192,7 +365,11 @@ public enum IncomeCategoryEnum implements BaseEnum { this.labelId = labelId; } - public abstract Map>> parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse); + public abstract void parseGetDeclareTaxResultFeedbackResponse(Map>> result, GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse); + + + public abstract Map parseGetASynIndividualIncomeTaxFeedbackResponse(GetASynIndividualIncomeTaxFeedbackResponse declareTaxResultFeedbackResponse, List employeeDeclares); + @Override public Integer getValue() { diff --git a/src/com/engine/salary/mapper/salaryacct/SalaryAcctCalcTaxReqMapper.java b/src/com/engine/salary/mapper/salaryacct/SalaryAcctCalcTaxReqMapper.java new file mode 100644 index 000000000..badcde3d7 --- /dev/null +++ b/src/com/engine/salary/mapper/salaryacct/SalaryAcctCalcTaxReqMapper.java @@ -0,0 +1,74 @@ +package com.engine.salary.mapper.salaryacct; + +import com.engine.salary.entity.salaryacct.po.SalaryAcctCalcTaxReqPO; +import org.apache.ibatis.annotations.Param; + +import java.util.Collection; +import java.util.List; + +public interface SalaryAcctCalcTaxReqMapper { + + /** + * 查询所有记录 + * + * @return 返回集合,没有返回空List + */ + List listAll(); + + /** + * 条件查询 + * + * @return 返回集合,没有返回空List + */ + List listSome(SalaryAcctCalcTaxReqPO acctCalcTaxReq); + + + /** + * 根据主键查询 + * + * @param id 主键 + * @return 返回记录,没有返回null + */ + SalaryAcctCalcTaxReqPO getById(Long id); + + /** + * 新增,忽略null字段 + * + * @param acctCalcTaxReq 新增的记录 + * @return 返回影响行数 + */ + int insertIgnoreNull(SalaryAcctCalcTaxReqPO acctCalcTaxReq); + + + /** + * 修改,修改所有字段 + * + * @param acctCalcTaxReq 修改的记录 + * @return 返回影响行数 + */ + int update(SalaryAcctCalcTaxReqPO acctCalcTaxReq); + + /** + * 修改,忽略null字段 + * + * @param acctCalcTaxReq 修改的记录 + * @return 返回影响行数 + */ + int updateIgnoreNull(SalaryAcctCalcTaxReqPO acctCalcTaxReq); + + /** + * 删除记录 + * + * @param acctCalcTaxReq 待删除的记录 + * @return 返回影响行数 + */ + int delete(SalaryAcctCalcTaxReqPO acctCalcTaxReq); + + /** + * 批量删除记录 + * @param ids 主键id集合 + */ + void deleteByIds(@Param("ids") Collection ids); + + void deleteByRecordId(Long salaryAcctRecordId); +} \ No newline at end of file diff --git a/src/com/engine/salary/mapper/salaryacct/SalaryAcctCalcTaxReqMapper.xml b/src/com/engine/salary/mapper/salaryacct/SalaryAcctCalcTaxReqMapper.xml new file mode 100644 index 000000000..ced6e5276 --- /dev/null +++ b/src/com/engine/salary/mapper/salaryacct/SalaryAcctCalcTaxReqMapper.xml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + t + . + id + , t.salary_acct_record_id + , t.tax_agent_id + , t.request_id + , t.tenant_key + , t.creator + , t.delete_type + , t.create_time + , t.update_time + + + + + + + + + + + + + + + INSERT INTO hrsa_acct_calc_tax_req + + + + id, + + + salary_acct_record_id, + + + tax_agent_id, + + + request_id, + + + tenant_key, + + + creator, + + + delete_type, + + + create_time, + + + update_time, + + + + + #{id}, + + + #{salaryAcctRecordId}, + + + #{taxAgentId}, + + + #{requestId}, + + + #{tenantKey}, + + + #{creator}, + + + #{deleteType}, + + + #{createTime}, + + + #{updateTime}, + + + + + + + + UPDATE hrsa_acct_calc_tax_req + + salary_acct_record_id=#{salaryAcctRecordId}, + tax_agent_id=#{taxAgentId}, + request_id=#{requestId}, + tenant_key=#{tenantKey}, + creator=#{creator}, + delete_type=#{deleteType}, + create_time=#{createTime}, + update_time=#{updateTime}, + + WHERE id = #{id} AND delete_type = 0 + + + + + + UPDATE hrsa_acct_calc_tax_req + + + salary_acct_record_id=#{salaryAcctRecordId}, + + + tax_agent_id=#{taxAgentId}, + + + request_id=#{requestId}, + + + tenant_key=#{tenantKey}, + + + creator=#{creator}, + + + delete_type=#{deleteType}, + + + create_time=#{createTime}, + + + update_time=#{updateTime}, + + + WHERE id = #{id} AND delete_type = 0 + + + + + + UPDATE hrsa_acct_calc_tax_req + SET delete_type=1 + WHERE id = #{id} + AND delete_type = 0 + + + + UPDATE hrsa_acct_calc_tax_req + SET delete_type = 1 + WHERE delete_type = 0 + AND id IN + + #{id} + + + + + UPDATE hrsa_acct_calc_tax_req + SET delete_type = 1 + WHERE delete_type = 0 + AND salary_acct_record_id = #{salaryAcctRecordId} + + + + \ No newline at end of file diff --git a/src/com/engine/salary/remote/tax/client/CalculateClient.java b/src/com/engine/salary/remote/tax/client/CalculateClient.java new file mode 100644 index 000000000..6c27ef8fc --- /dev/null +++ b/src/com/engine/salary/remote/tax/client/CalculateClient.java @@ -0,0 +1,31 @@ +package com.engine.salary.remote.tax.client; + +import com.engine.salary.remote.tax.response.calculate.GetASynIndividualIncomeTaxFeedbackResponse; +import com.engine.salary.util.HttpUtil; +import com.engine.salary.util.JsonUtil; +import com.engine.salary.util.SingnatureData; +import lombok.extern.slf4j.Slf4j; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +public class CalculateClient extends TaxBaseClient{ + + public CalculateClient(Long taxAgentId) { + super(taxAgentId); + } + + public GetASynIndividualIncomeTaxFeedbackResponse getASynIndividualIncomeTaxFeedback(String requestId){ + String url = super.apiConfig.getHost() + "/gateway/iit/calculateTax/getASynIndividualIncomeTaxFeedback"; + Map params = new HashMap<>(1); + params.put("requestId", requestId); + Map header = SingnatureData.initHeader(Collections.emptyMap(), apiConfig.getAppKey(), apiConfig.getAppSecret()); + String res = HttpUtil.getRequest(url, header, params); + + log.info("getDeclareTaxResultFeedback res --- {}", res); + return JsonUtil.parseObject(res, GetASynIndividualIncomeTaxFeedbackResponse.class); + + } +} diff --git a/src/com/engine/salary/remote/tax/request/calculate/CalculateASynIndividualIncomeTaxRequest.java b/src/com/engine/salary/remote/tax/request/calculate/CalculateASynIndividualIncomeTaxRequest.java new file mode 100644 index 000000000..408dec81f --- /dev/null +++ b/src/com/engine/salary/remote/tax/request/calculate/CalculateASynIndividualIncomeTaxRequest.java @@ -0,0 +1,1442 @@ +package com.engine.salary.remote.tax.request.calculate; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class CalculateASynIndividualIncomeTaxRequest { + /** + * 外部业务编号 必填:是 外部业务编号,唯一,幂等需要,最长64位,建议使用UUID,建议使用UUID + */ + private String bizNo; + /** + * 企业名称 必填:是 扣缴义务人名称:例如:测试ß科技有限公司 + */ + private String qymc; + /** + * 密码类型 必填:否 0表示申报密码;2表示实名账号实名密码 + */ + private String mmlx; + /** + * 实名账号 必填:条件必填 当mmlx=2时,必填 + */ + private String smzh; + /** + * 实名密码 必填:条件必填 当mmlx=2时,必填 + */ + private String smmm; + /** + * 加密实名密码 必填:否 默认不传则设置为0,0表示不加密,1表示加密 + */ + private String jmsmmm; + /** + * 申报密码 必填:条件必填 当mmlx=0时,必填 + */ + private String sbmm; + /** + * 加密申报密码 必填:否 默认不传则设置为0,0表示不加密;1表示加密 + */ + private String jmsbmm; + /** + * 登记序号 必填:条件必填 存在多个登记序号时,需要指定传入一个.例:10117440105249764755 + */ + private String djxhid; + /** + * 税号 必填:是 扣缴单位纳税人识别号 + */ + private String nsrsbh; + /** + * 地区编号 必填:是 6位行政区划代码,精确到市级,例如:440100,参考省市区编码 + */ + private String areaid; + /** + * 部门编号 必填:条件必填 分部门代报时必传 + */ + private String bmbh; + /** + * 部门名称 必填:否 分部门代报时必传 + */ + private String bmmc; + /** + * 所属期 必填:是 格式YYYYMM年月 + */ + private String skssq; + /** + * 多批次算税,是否校验人员之前批次算税状态 必填:否 应用场景: 如果填写“是”,在多批次算税中会校验当前批次中的人员在之前批次算税中是否存在未拿反馈的请求,如果存在就阻断当前批次算税。 + * 如果不填写或者填写“否”,不校验该逻辑。 + */ + private String sfjyrysszt; + /** + * 综合所得 必填:是 见综合所得 + */ + private zhsd zhsd; +// /** +// * 分类所得 必填:是 见分类所得 +// */ +// private 对象 flsd; +// /** +// * 非居民所得 必填:是 见非居民所得 +// */ +// private 对象 fjmsd; +// /** +// * 限售股所得 必填:是 见限售股所得 +// */ +// private 对象 xsgsd; + + @Data + public static class zhsd { + /** + * 是否离线算薪 必填:否 可选【是】或【否】,非必传,不传的情况下默认为【否】,当为离线算薪时,专项下载、人员报送都失效, + * sfrysb=1 时也不会报送人员, + * zcgzxjsfcrlj=0时会统一使用本地数据进行计算 + */ + private String sflxsx; + /** + * 减免方式 必填:否 1:"比例减免方式" 2:"限额减免方式" 其他方式不传值,按照当地政策选择减免方式 + */ + private String jmfs; + /** + * 减免比例 必填:条件必填 jmfs为1时必填,示例:10% 传0.1 + */ + private BigDecimal jmbl; + /** + * 减免限额 必填:条件必填 jmfs为2时必填,减免限额大于0 + */ + private BigDecimal jmxe; + /** + * 正常工资薪金对象 必填:是 参考综合所得-正常工资薪金对象 + */ + private zcgzxj zcgzxj; + /** + * 全年一次性奖金收入列表 必填:是 参考综合所得-全年一次性奖金收入 + */ + private List qnycxjjsslb; + /** + * 稿酬所得列表 必填:是 参考综合所得-稿酬所得 + */ + private List gcsdlb; + /** + * 一般劳务报酬所得列表 必填:是 参考综合所得-一般劳务报酬所得 + */ + private List lwbclb; + /** + * 解除劳动合同一次性补偿金列表 必填:是 参考综合所得-解除劳动合同一次性补偿金 + */ + private List jcldhtycxbcjlb; + /** + * 保险营销员 必填:是 参考综合所得-保险营销员薪金对象 + */ + private bxyxy bxyxy; + /** + * 证券经纪人 必填:是 参考综合所得-证券经纪人薪金对象 + */ + private zqjjr zqjjr; + /** + * 其他连续劳务报酬所得 必填:是 参考综合所得-其他连续劳务报酬所得 + */ + private qtlxlwbc qtlxlwbc; + /** + * 特许权所得 必填:是 参考综合所得-特许权所得 + */ + private List txq; + /** + * 个人股权激励所得 必填:是 参考综合所得-个人股权激励所得 + */ + private List grgqjl; + /** + * 企业年金 必填:是 参考综合所得-企业年金 + */ + private List qynj; + /** + * 内退一次性补偿金 必填:是 参考综合所得-内退一次性补偿金 + */ + private List ntycxbcjlb; + /** + * 其他非连续劳务报酬 必填:是 参考综合所得-其他非连续劳务报酬 + */ + private List qtflxlwbc; +// /** +// * 提前退休一次性补贴 必填:是 参考综合所得-提前退休一次性补贴 +// */ +// private List tqtxycxbt; +// /** +// * 央企负责人绩效薪金延期兑现收入和任期奖励 必填:是 参考综合所得-央企负责人绩效薪金延期兑现收入和任期奖励 +// */ +// private 数组 yqfzrsrhjl; +// /** +// * 法律援助劳务报酬所得列表 必填:是 参考综合所得-法律援助劳务报酬所得列表 +// */ +// private 数组 flyzlwbclb; +// /** +// * 非居民所得 必填:是 见非居民所得 +// */ +// private 对象 fjmsd; +// /** +// * 限售股所得 必填:是 见限售股所得 +// */ +// private 对象 xsgsd; + + @Data + public static class ry { + /** + * 姓名 必填:是 纳税人姓名 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 证件号码需要大写 + */ + private String zzhm; + /** + * 其他证件类型 必填:条件必填 见证件类型字典 + */ + private String qtzzlx; + /** + * 其他证件号码 必填:条件必填 见证件类型字典 + */ + private String qtzzhm; + /** + * 部门编号 必填:否 部门编号 + */ + private String bmbh; + /** + * 人员报送策略 必填:否 1. 默认逻辑“是”,仅当信息变化时才会报送信息到税局 2. 若企业想要支持人员信息不变化的情况下,也能重新发起报送,覆盖局端信息,可修改传参为“否” + */ + private String rybscl; + /** + * 工号 必填:否 + */ + private String gh; + /** + * 所属期 必填:否 格式YYYYMM年月 + */ + private String skssq; + /** + * 电话号码 必填:是 11位中国大陆手机号码 + */ + private String lxdh; + /** + * 人员状态 必填:是 默认为正常,可选择正常/非正常 + */ + private String nsrzt; + /** + * 任职受雇类型 必填:是 可选择雇员、保险营销员、证券经纪人、其他、实习学生(全日制学历教育) + */ + private String sfgy; + /** + * 入职年度就业情形 必填:否 当雇员、保险营销员、证券经纪人时可选择:当年首次入职学生、当年首次入职其他人员。其他情况下填写默认为空 + */ + private String rzndjyqk; + /** + * 受雇日期 必填:条件必填 格式:YYYY-MM-DD,不能大于当前时间 任职受雇类型选择:雇员、保险营销员、证券经纪人、实习学生(全日制学历教育)时必录 + */ + private String rzsgrq; + /** + * 性别 必填:是 男/女 + */ + private String xb; + /** + * 出生日期 必填:是 YYYY-MM-DD 需要和身份证上保持一致 + */ + private String csny; + /** + * 国籍 必填:是 见国籍字典 + */ + private String gj; + /** + * 人员地区 必填:是 境内/境外 + */ + private String rydq; + /** + * 离职日期 必填:否 格式:YYYY-MM-DD,不能大于当前时间,离职日期不能大于入职日期 人员状态非正常时必填 注:清空离职时间传入空字符串,不能是null + */ + private String lzrq; + /** + * 个人投资总额 必填:条件必填 当为股东投资者时必填,投资额大于0 + */ + private BigDecimal grgbze; + /** + * 个人投资比例 必填:否 投资额填写时必填,范围为0~100,不包含0 + */ + private BigDecimal grgbbl; + /** + * 是否残疾 必填:否 默认为否,可选择是/否 + */ + private String sfcj; + /** + * 是否烈属 必填:否 默认为否,可选择是/否 + */ + private String sfls; + /** + * 是否孤老 必填:否 默认为否,可选择是/否 + */ + private String sfgl; + /** + * 是否扣除减除费用 必填:否 默认为是,可选择是/否,传null或者空值都会默认为是,当填了否后, 如果后续还需要保持否的状态还需传否,不填则会默认为是 + */ + private String sfzdw; + /** + * 残疾证号 必填:条件必填 当为残疾时必填 + */ + private String cjzh; + /** + * 烈属证号 必填:条件必填 当为烈属时必填 + */ + private String lszh; + /** + * 邮箱 必填:否 + */ + private String dzyx; + /** + * 学历 必填:否 + * 默认为空,大学本科以下 大学本科 研究生 + */ + private String xl; + /** + * 职务 必填:否 高层 普通 + */ + private String zw; + /** + * 开户银行 必填:否 见银行字典 + */ + private String khyh; + /** + * 开户银行省份 必填:否 见开户银行省份字典 + */ + private String khyhsfmz; + /** + * 银行账号 必填:否 如果khyh,khyhsfmz,yhzh 有一项选择填写了那么其他两项也需要填写 + */ + private String yhzh; + /** + * 居住省份 必填:否 中文,例如浙江省 + */ + private String lxdz_sheng; + /** + * 居住城市 必填:否 中文,例如杭州市 + */ + private String lxdz_shi; + /** + * 居住区县 必填:否 中文,例如滨江区 + */ + private String lxdz_qx; + /** + * 居住街道 必填:否 中文,浦沿街道 + */ + private String lxdz_jd; + /** + * 居住详细地址 必填:否 + */ + private String lxdz; + /** + * 户籍省份 必填:否 中文,例如浙江省 + */ + private String hjszd_sheng; + /** + * 户籍城市 必填:否 中文,例如杭州市 + */ + private String hjszd_shi; + /** + * 户籍区县 必填:否 中文,例如滨江区 + */ + private String hjszd_qx; + /** + * 户籍街道 必填:否 中文,浦沿街道 + */ + private String hjszd_jd; + /** + * 户籍详细地址 必填:否 + */ + private String hjszd_xxdz; + /** + * 备注 必填:否 + */ + private String bz; + /** + * 出生地 必填:条件必填 外籍人员必填,填写出生地国家(地区),见国籍字典 + */ + private String csd; + /** + * 涉税事由 必填:条件必填 外籍人员必填,多个时用逗号分割; + * 任职受雇 提供临时劳务 转让财产 从事投资和经营活动 其他 + */ + private String sssx; + /** + * 首次入境时间 必填:条件必填 证件类型为港澳居民来往内地通行证、港澳居民居住证、台湾居民来往大陆通行证、台湾居民居住证、外国护照、外国人永久居留身份证、外国人来华工作许可证A、外国人来华工作许可证B、外国人来华工作许可证C时,且任职受雇类型选择雇员时必填,格式YYYY-MM-DD + */ + private String scrjsj; + /** + * 预计离境时间 必填:条件必填 证件类型为港澳居民来往内地通行证、港澳居民居住证、台湾居民来往大陆通行证、台湾居民居住证、外国护照、外国人永久居留身份证、外国人来华工作许可证A、外国人来华工作许可证B、外国人来华工作许可证C时,且任职受雇类型选择雇员时必填,格式YYYY-MM-DD + */ + private String yjljsj; + /** + * 联系地省份 必填:否 + */ + private String wjrlxdz_sheng; + /** + * 联系地城市 必填:否 + */ + private String wjrlxdz_shi; + /** + * 联系地区县 必填:否 + */ + private String wjrlxdz_qx; + /** + * 联系地街道 必填:否 + */ + private String wjrlxdz_jd; + /** + * 联系地详细地址 必填:否 + */ + private String wjrlxdz_xxdz; + /** + * 中文名 必填:否 证件类型为外国护照、外国人永久居留身份证、外国人工作许可证(A类)、外国人工作许可证(B类)、外国人工作许可证(C类)时不可填写,其他证件类型可填写。如果有填写必须为中文。 + */ + private String xmzw; + + } + + @Data + public static class zcgzxj { + /** + * 正常工资薪金列表 必填:是 参考综合所得-正常工资薪金 + */ + private List zcgzxjlb; + /** + * 上月正常工资薪金列表 必填:否 参考综合所得-正常工资薪金 + * 1、若当月已经代报完毕(当月代报上月所得),那么能从客户端下发累计到上月的所得数据,此时传给客户端的所得月份为当前月份 + * 2、若当月未代报完毕(当月代报上月所得),那么能从客户端下发累计到上月-1的所属数据,此时传给客户端的所得月份为当月月份-1 + * 3、上月正常工资薪金列表与本月正常工资薪金列表需要一一对应 + */ + private List syzcgzxjlb; + /** + * 人员列表 必填:是 见人员列表 + */ + private List rylb; + /** + * 正常工资薪金是否需要下载专项 必填:是 + * 1:需要专项明细进行专项计算 + * 0:不需要专项明细进行专项计算 + * 见附录专项传值策略 + */ + private String zcgzxjsfxyzx; + /** + * 是否已代报上月正常工资薪金 必填:否 + * 仅对需要计算正常工资所得生效,(默认为1) + * 1: 已代报上月正常工资薪金 + * 0: 未代报上月正常工资薪金(两个月算税传入0) + */ + private String syysfsyzcgzxj; + /** + * 支持传入专项 必填:否 + * 仅在syysfsyzcgzxj=0时候生效,默认值=0 + * 0: 不支持用户传专项,使用实时下载的专项,默认值 + * 1: 支持传上月当月的专项 + * 2:支持传截止至上月为止的累计专项 + */ + private String zcgzxjsfcrzx; + /** + * 当前算税月正常工资薪金是否传入专项累计 必填:否 + * 仅对当前算税月数据生效,默认为0 + * (如果是离线算薪,zcgzxjsfcrlj=1时会强制使用本地数据进行计算) + * 0:使用下载计算专项累计 + * 1:使用传入的专项累计值 + * 2: 不实时下载专项,使用本地数据进行计算 + * 见附录专项传值策略 + */ + private String zcgzxjsfcrlj; + + /** + * 批次号 必填:否 + * 默认不填为Null,表示一月一次算薪; + * 其他整数值(如1、2、3等)为一月多次发薪算薪的批次 + */ + private Integer pch; + /** + * 是否导入上月正常工资薪金(一月多次发薪) 必填:否 + * 仅在一月多次算税场景中使用 0:不导入上月薪金 1:导入上月薪资(默认为1,导入上月薪资) + */ + private String sfdrsyzcgzxj; + /** + * 是否同时人员报送 必填:否 0: 人员不报送; + */ + private String sfrysb; + /** + * 年金/住房公积金上限选项 必填:否 + * 1:不处理(默认) + * 2:使用年金/公积金上限(超过上限使用上限值,不超过 则使用原来的值) + * 3:年金使用上限,公积金截取超上限部分纳入收入额 + * 4.年金使用上限,截取公积金超过上限的部分减少收入额 + */ + private String njzfgjjsxxx; + /** + * 企业下载往期标志 必填:否 + * 1:按照企业维度下载(默认) 0:按照部门维度下载(企业在局端备案分部门,需要传入0) + */ + private String qyxzwqbz; + + /** + * 多月算税,是否使用上月传入的应补退税额 必填:否 + * 1. 不传或传空(默认为否)或者传“否”,与当前多月算税逻辑一致。2. 传“是”,多月算税时取上月薪资数据传入的应补退税额参与算税。 + */ + private String sfsysyybtse; + + /** + * 个人养老金策略 必填:否 + * 0: 不传或传空或者传“0”则会实时下载个人养老金 1: 传“1”则使用本地的个人养老金 2: 传“2”则使用传入的累计个人养老金 + */ + private String gryljcl; + + /** + * 上月个人养老金策略 必填:否 + * 不传或传空赋值默认值,默认值为1 + * 0:传“0”则会实时下载个人养老金 1: 传“1”则使用本地的个人养老金 2: 传“2”则使用传入的累计个人养老金 + */ + private String sygryljcl; + + @Data + public static class zcgz { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:条件必填 当sygs为空或者等于公式5时必填 + */ + private BigDecimal sre; + /** + * 适用公式 必填:否 见《工资收入公式字典》 + * 重点说明:一般正常工资薪金所得不用传适用公式,只需要传入收入额,就可以进行计算;也可以传适用公式,系统就会按照适用公式进行计算 当证件类型为居民身份证时,适用公式默认为空 + */ + private String sygs; + /** + * 境内工作天数 必填:条件必填 正常工资薪金传了适用公式才需要条件必录。当sygs字段填值并且不等于公式5时,该字段必填,可以为小数 小数位0.5天 不能两位小数,只能是1或者1.0不能1.00 + */ + private BigDecimal jngzts; + /** + * 境外工作天数 必填:条件必填 正常工资薪金传了适用公式才需要条件必录。当sygs字段填值并且不等于公式5时,该字段必填,可以为小数 小数位0.5天 不能两位小数,只能是1或者1.0不能1.00 + */ + private BigDecimal jwgzts; + /** + * 境内支付 必填:条件必填 正常工资薪金传了适用公式才需要条件必录。当sygs字段填值并且不等于公式5时,该字段必填 + */ + private BigDecimal jnzf; + /** + * 境外支付 必填:条件必填 正常工资薪金传了适用公式才需要条件必录。当sygs字段填值并且不等于公式5时,该字段必填 + */ + private BigDecimal jwzf; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 基本养老保险 必填:否 无则填0 + */ + private BigDecimal jbylaobxf; + /** + * 基本医疗保险 必填:否 无则填0 + */ + private BigDecimal jbylbxf; + /** + * 失业保险 必填:否 无则填0 + */ + private BigDecimal sybxf; + /** + * 住房公积金 必填:否 无则填0 + */ + private BigDecimal zfgjj; + /** + * 年金 必填:否 无则填0 + */ + private BigDecimal nj; + /** + * 商业健康保险 必填:否 无则填0 + */ + private BigDecimal syjkbx; + /** + * 税延养老保险 必填:否 无则填0 + */ + private BigDecimal syylbx; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目,填写其他,一定 + */ + private BigDecimal qt; + /** + * 备注 必填:条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称 + */ + private String bz; + /** + * 准予扣除的捐赠额 必填:否 无则填0,按照税法以及相关法规、政策规定,可以在税前扣除的捐赠额 + */ + private BigDecimal zykcjze; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 所得项目名称 必填:是 正常工资薪金; + */ + private String sdxm; + /** + * 子女教育支出 必填:条件必填 在zcgzxjsfcrzx=1时必传,默认不传 + */ + private BigDecimal znjyzc; + /** + * 继续教育支出 必填:条件必填 在zcgzxjsfcrzx=1时必传,默认不传 + */ + private BigDecimal jxjyzc; + /** + * 住房租金支出 必填:条件必填 在zcgzxjsfcrzx=1时必传,默认不传 + */ + private BigDecimal zfzjzc; + /** + * 房屋贷款支出 必填:条件必填 在zcgzxjsfcrzx=1时必传,默认不传 + */ + private BigDecimal zfdklxzc; + /** + * 赡养老人支出 必填:条件必填 在zcgzxjsfcrzx=1时必传,默认不传 + */ + private BigDecimal sylrzc; + /** + * 3岁以下婴幼儿照护支出 必填:条件必填 在zcgzxjsfcrzx=1时必传,默认不传 + */ + private BigDecimal yyezhzc; + /** + * 累计子女教育支出 必填:条件必填 在zcgzxjsfcrzx=2时必传,默认不传 + */ + private BigDecimal ljznjyzc; + /** + * 累计继续教育支出 必填:条件必填 在zcgzxjsfcrzx=2时必传,默认不传 + */ + private BigDecimal ljjxjyzc; + /** + * 累计住房租金支出 必填:条件必填 在zcgzxjsfcrzx=2时必传,默认不传 + */ + private BigDecimal ljzfzjzc; + /** + * 累计房屋贷款支出 必填:条件必填 在zcgzxjsfcrzx=2时必传,默认不传 + */ + private BigDecimal ljzfdklxzc; + /** + * 累计赡养老人支出 必填:条件必填 在zcgzxjsfcrzx=2时必传,默认不传 + */ + private BigDecimal ljsylrzc; + /** + * 累计3岁以下婴幼儿照护支出 必填:条件必填 在zcgzxjsfcrzx=2时必传,默认不传 + */ + private BigDecimal ljyyezhzc; + /** + * 累计个人养老金 必填:否 在gryljcl=2时传值,默认不传 + */ + private BigDecimal ljgrylj; + /** + * 累计个人养老金校验码 必填:否 + * 在gryljcl=2时传值,默认不传 在ljgrylj传值时校验是否合法 ljgrylj传0时不校验 + */ + private String ljgryljjym; + /** + * 应补退税额 必填:否 配合sfsysyybtse字段使用 + */ + private BigDecimal ybtse; + } + } + + @Data + public static class qnycxjjss { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 批次号 必填:否 默认不填为Null,表示一月一次算薪; 其他整数值(如1、2、3等)为一月多次发薪算薪的批次 + */ + private Integer pch; + /** + * 当期收入额 必填:是 不填写默认为0 + */ + private BigDecimal sre; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 准予扣除的捐赠额 必填:否 无则填0 + */ + private BigDecimal zykcjze; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 备注 必填: 条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 所得项目名称 必填:是 填写:全年一次性奖金收入; + */ + private String sdxm; + } + + @Data + public static class gcsd { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:是 不填写默认为0 + */ + private BigDecimal sre; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 备注 必填: 条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 所得项目名称 必填:是 填写:稿酬所得; + */ + private String sdxm; + } + + @Data + public static class lwbc { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:是 不填写默认为0 + */ + private BigDecimal sre; + /** + * 当期免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 商业健康保险 必填:否 无则填0 + */ + private BigDecimal syjkbx; + /** + * 税延养老保险 必填:否 无则填0 + */ + private BigDecimal syylbx; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 备注 必填:条件必填  根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 允许扣除税费 必填:否 + */ + private BigDecimal yxkcsf; + /** + * 所得项目名称 必填:是 填写:一般劳务报酬所得; + */ + private String sdxm; + } + + @Data + public static class jcldhtycxbcj { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:是 不填写默认为0 + */ + private BigDecimal sre; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 备注 必填: 条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 准予扣除的捐赠额 必填:否 无则填0 + */ + private BigDecimal zykcjze; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 所得项目名称 必填:是 填写:解除劳动合同一次性补偿金; + */ + private String sdxm; + + } + + @Data + public static class bxyxy { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:条件必填 当sygs为空或者等于公式5时必填 + */ + private BigDecimal sre; + /** + * 免税收入 必填:是 无则填0 + */ + private BigDecimal mssd; + /** + * 商业健康保险 必填:是 无则填0 + */ + private BigDecimal syjkbx; + /** + * 税延养老保险 必填:是 无则填0 + */ + private BigDecimal syylbx; + /** + * 准予扣除的捐赠额 必填:否 无则填0,按照税法以及相关法规、政策规定,可以在税前扣除的捐赠额 + */ + private BigDecimal zykcjze; + /** + * 其他 必填:是 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 备注 必填:条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 减免税额 必填:是 无则填0 + */ + private BigDecimal jmse; + /** + * 累计个人养老金 必填:否 在gryljcl=2时传值,默认不传 + */ + private BigDecimal ljgrylj; + /** + * 累计个人养老金校验码 必填:否 + * 在gryljcl=2时传值,默认不传 在ljgrylj传值时校验是否合法 ljgrylj传0时不校验 + */ + private String ljgryljjym; + + /** + * 所得项目名称 必填:是 保险营销员佣金收入; + */ + private String sdxm; + /** + * 允许扣除税费 必填:否 + */ + private BigDecimal yxkcsf; + /** + * 应补退税额 必填:否 配合sfsysyybtse字段使用 + */ + private BigDecimal ybtse; + } + + @Data + public static class zqjjr { + /** + * 证券经纪人所得薪金列表 必填:null 参考综合所得-证券经纪人列表 + */ + private List zqjjrsdlb; + /** + * 上月证券经纪人列表 必填:null 参考综合所得-证券经纪人列表 + */ + private List syzqjjrlb; + /** + * 人员列表 必填:null 见企业人员列表 + */ + private List rylb; + /** + * 批次号 必填:否 + * 默认不填为Null,表示一月一次算薪; + * 其他整数值(如1、2、3等)为一月多次发薪算薪的批次 + */ + private Integer pch; + /** + * 是否导入上月正常工资薪金(一月多次发薪) 必填:否 + * 仅在一月多次算税场景中使用 + * 0:不导入上月薪金 1:导入上月薪资 (默认为1,导入上月薪资) + */ + private String sfdrsyzcgzxj; + /** + * 是否同时人员报送 必填:否 0: 人员不报送; 1: 人员报送 (默认为1,算税前同时处理人员报送,离线算薪模式时,不会进行人员报送) + */ + private String sfrysb; + /** + * 是否已代报上月薪金 必填:否 (默认为1) 1: 已代报上月正常工资薪金 0: 未代报上月正常工资薪金(两个月算税传入0) + */ + private String syysfsyzcgzxj; + /** + * 企业下载往期标志 必填:否 1:按照企业维度下载(默认) 0:按照部门维度下载(企业在局端备案分部门,需要传入0) + */ + private String qyxzwqbz; + /** + * 多月算税,是否使用上月传入的应补退税额 必填:否 + * 1. 不传或传空(默认为否)或者传“否”,与当前多月算税逻辑一致。 2. 传“是”,多月算税时取上月薪资数据传入的应补退税额参与算税。 + */ + private String sfsysyybtse; + /** + * 个人养老金策略 必填:否 + * 0: 不传或传空或者传“0”则会实时下载个人养老金 1: 传“1”则使用本地的个人养老金 2: 传“2”则使用传入的累计个人养老金 + */ + private String gryljcl; + /** + * 上月个人养老金策略 必填:否 + * 不传或传空赋值默认值,默认值为1 0:传“0”则会实时下载个人养老金 1: 传“1”则使用本地的个人养老金 2: 传“2”则使用传入的累计个人养老金 + */ + private String sygryljcl; + + + @Data + public static class zqjjrsd { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:条件必填 当sygs为空或者等于公式5时必填 + */ + private BigDecimal sre; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 商业健康保险 必填:否 无则填0 + */ + private BigDecimal syjkbx; + /** + * 税延养老保险 必填:否 无则填0 + */ + private BigDecimal syylbx; + /** + * 准予扣除的捐赠额 必填:否 无则填0,按照税法以及相关法规、政策规定,可以在税前扣除的捐赠额 + */ + private BigDecimal zykcjze; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 备注 必填:条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 累计个人养老金 必填:否 在gryljcl=2时传值,默认不传 + */ + private BigDecimal ljgrylj; + /** + * 累计个人养老金校验码 必填:否 + * 在gryljcl=2时传值,默认不传 在ljgrylj传值时校验是否合法 ljgrylj传0时不校验 + */ + private String ljgryljjym; + /** + * 所得项目名称 必填:是 证券经纪人佣金收入; + */ + private String sdxm; + /** + * 允许扣除税费 必填:否 + */ + private BigDecimal yxkcsf; + /** + * 应补退税额 必填:否 配合sfsysyybtse字段使用 + */ + private BigDecimal ybtse; + } + } + + @Data + public static class qtlxlwbc { + /** + * 其他连续劳务报酬所得列表 必填:null 参考综合所得-其他连续劳务报酬所得列表 + */ + private List qtlxlwbclb; + /** + * 上月其他连续劳务报酬所得列表 必填:null 参考综合所得-其他连续劳务报酬所得列表 + */ + private List syqtlxlwbclb; + /** + * 人员列表 必填:null 见企业人员列表 + */ + private List rylb; + /** + * 是否同时人员报送 必填:否 0: 人员不报送;1: 人员报送 默认为1,算税前同时处理人员报送,离线算薪模式时,不会进行人员报送) + */ + private String sfrysb; + /** + * 是否已代报上薪金 必填:否 (默认为1) 1: 已代报上月正常工资薪金 0: 未代报上月正常工资薪金(两个月算税) + */ + private String syysfsyzcgzxj; + /** + * 企业下载往期标志 必填:否 1:按照企业维度下载(默认) 0:按照部门维度下载(企业在局端备案分部门,需要传入0) + */ + private String qyxzwqbz; + /** + * 批次号 必填:否 默认不填为Null,表示一月一次算薪; 其他整数值(如1、2、3等)为一月多次发薪算薪的批次 + */ + private Integer pch; + /** + * 多月算税,是否使用上月传入的应补退税额 必填:否 1. 不传或传空(默认为否)或者传“否”,与当前多月算税逻辑一致。 2. 传“是”,多月算税时取上月薪资数据传入的应补退税额参与算税。 + */ + private String sfsysyybtse; + /** + * 个人养老金策略 必填:否 0: 不传或传空或者传“0”则会实时下载个人养老金 1: 传“1”则使用本地的个人养老金 2: 传“2”则使用传入的累计个人养老金 + */ + private String gryljcl; + /** + * 上月个人养老金策略 必填:否 不传或传空赋值默认值,默认值为1 0:传“0”则会实时下载个人养老金 1: 传“1”则使用本地的个人养老金 2: 传“2”则使用传入的累计个人养老金 + */ + private String sygryljcl; + + @Data + public static class qtlxlw { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:条件必填 当sygs为空或者等于公式5时必填 + */ + private BigDecimal sre; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 商业健康保险 必填:否 无则填0 + */ + private BigDecimal syjkbx; + /** + * 税延养老保险 必填:否 无则填0 + */ + private BigDecimal syylbx; + /** + * 准予扣除的捐赠额 必填:否 无则填0,按照税法以及相关法规、政策规定,可以在税前扣除的捐赠额 + */ + private BigDecimal zykcjze; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 备注 必填:条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 累计个人养老金 必填:否 在gryljcl=2时传值,默认不传 + */ + private BigDecimal ljgrylj; + /** + * 累计个人养老金校验码 必填:否 在gryljcl=2时传值,默认不传 在ljgrylj传值时校验是否合法 ljgrylj传0时不校验 + */ + private String ljgryljjym; + /** + * 所得项目名称 必填:是 证券经纪人佣金收入; + */ + private String sdxm; + /** + * 允许扣除税费 必填:否 + */ + private BigDecimal yxkcsf; + /** + * 应补退税额 必填:否 配合sfsysyybtse字段使用 + */ + private BigDecimal ybtse; + } + } + + @Data + public static class txq { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:是 不填写默认为0 + */ + private BigDecimal sre; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 备注 必填: 条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 所得项目名称 必填:是 填写:特许权使用费所得 + */ + private String sdxm; + } + + @Data + public static class grgqjl { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:是 + */ + private BigDecimal sre; + /** + * 累计收入额(不含本期) 必填:否 如果为null,则使用本地申报数据累计自动填充 + */ + private BigDecimal ljsre; + /** + * 累计免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 备注 必填:条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 准予扣除的捐赠额 必填:否 无则填0 + */ + private BigDecimal zykcjze; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 适用公式 必填:否 见《工资收入公式字典》 + */ + private String sygs; + /** + * 累计已扣缴税额 必填:否 如果为null,则使用本地申报数据累计自动填充 + */ + private BigDecimal ykjse; + /** + * 境内工作天数 必填:条件必填 + * 当sygs字段填值并且不等于公式5时,该字段必填 不能两位小数,只能是1或者1.0不能1.00 + */ + private BigDecimal jngzts; + /** + * 境外工作天数 必填:条件必填 + * 当sygs字段填值并且不等于公式5时,该字段必填 + * 不能两位小数,只能是1或者1.0不能1.00 + */ + private BigDecimal jwgzts; + /** + * 境内支付 必填:条件必填 当sygs字段填值并且不等于公式5时,该字段必填 + */ + private BigDecimal jnzf; + /** + * 境外支付 必填:条件必填 当sygs字段填值并且不等于公式5时,该字段必填 + */ + private BigDecimal jwzf; + /** + * 所得项目名称 必填:是 填写:个人股权激励收入 + */ + private String sdxm; + } + + @Data + public static class qynj { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:是 不填写默认为0 + */ + private BigDecimal sre; + /** + * 已完税缴费额 必填:否 不填写默认为0 + */ + private BigDecimal ywsjfe; + /** + * 全部缴费额 必填:是 不小于等于0,取值小数点后两位例0.00 + */ + private BigDecimal qbjfe; + /** + * 是否一次性领取 必填: 是 1:是 0:否 + */ + private String sfycxlq; + /** + * 年金领取方式 必填:条件必填 当“是否一次性领取”为是时,不可填写,当“是否一次性领取”为否时,可填写; 领取方式按“按年”,“按季”,“按月” + */ + private String njlqfs; + /** + * 年金领取原因 必填:条件必填 当“是否一次性领取”为是时,可填写; 当“是否一次性领取”为否时,不可填写; 领取原因:“出国定居或个人死亡“、”其他“; + */ + private String njlqyy; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 商业健康保险 必填:否 + */ + private BigDecimal syjkbx; + /** + * 税延养老保险 必填:否 + */ + private BigDecimal syylbx; + /** + * 其他 必填:否 + */ + private BigDecimal qt; + /** + * 准予扣除捐赠额 必填:否 + */ + private BigDecimal zykcjze; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 备注 必填:条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 所得项目名称 必填:是 填写:年金领取 + */ + private String sdxm; + } + + @Data + public static class ntycxbcj { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 一次性补偿收入 必填:是 不填写默认为0 + */ + private BigDecimal sre; + /** + * 本期工资收入 必填: 否 + */ + private BigDecimal bqgzs; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 其他 必填:否 + */ + private BigDecimal qt; + /** + * 准予扣除捐赠额 必填:否 + */ + private BigDecimal zykcjze; + /** + * 备注 必填:条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 所得项目名称 必填:是 填写:内退一次性补偿金 + */ + private String sdxm; + /** + * 分摊月份数 必填:是 + */ + private Integer ftyfs; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + } + + @Data + public static class qtflxlwbc { + /** + * 姓名 必填:是 + */ + private String xm; + /** + * 证件类型 必填:是 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 必填:是 + */ + private String zzhm; + /** + * 当期收入额 必填:是 不填写默认为0 + */ + private BigDecimal sre; + /** + * 免税收入 必填:否 无则填0 + */ + private BigDecimal mssd; + /** + * 商业健康保险 必填:否 无则填0 + */ + private BigDecimal syjkbx; + /** + * 税延养老保险 必填:否 无则填0 + */ + private BigDecimal syylbx; + /** + * 允许扣除税费 必填:否 + */ + private BigDecimal yxkcsf; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 备注 必填:条件必填 根据政策要求,填写【其他】项,一定在备注中写明具体扣除项目名称,备注不超过20个字符 + */ + private String bz; + /** + * 减免税额 必填:否 无则填0 + */ + private BigDecimal jmse; + /** + * 所得项目名称 必填:是 填写:其他非连续劳务报酬 + */ + private String sdxm; + } + } + + +} diff --git a/src/com/engine/salary/remote/tax/response/calculate/GetASynIndividualIncomeTaxFeedbackResponse.java b/src/com/engine/salary/remote/tax/response/calculate/GetASynIndividualIncomeTaxFeedbackResponse.java new file mode 100644 index 000000000..7c1e13b6d --- /dev/null +++ b/src/com/engine/salary/remote/tax/response/calculate/GetASynIndividualIncomeTaxFeedbackResponse.java @@ -0,0 +1,746 @@ +package com.engine.salary.remote.tax.response.calculate; + +import com.engine.salary.annotation.TableTitle; +import com.engine.salary.entity.taxpayment.response.BaseResponse; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.List; + +@Data +@EqualsAndHashCode(callSuper = true) +public class GetASynIndividualIncomeTaxFeedbackResponse extends BaseResponse { + /** + * 返回数据 + */ + private Body body; + + @Data + public static class Body { + /** + * 企业名称 必填:是 + */ + private String qymc; + /** + * 税号 必填:是 + */ + private String nsrsbh; + /** + * 地区编号 必填:是 6位行政区划代码,精确到市级,例如:440100,参考省市区编码 + */ + private String areaid; + /** + * 部门编号 必填:是 + */ + private String bmbh; + /** + * 部门名称 必填:否 + */ + private String bmmc; + /** + * 算税月份 必填:是 + */ + private String skssq; + /** + * 综合所得 必填:是 见综合所得计算结果 + */ + private zhsd zhsd; +// /** +// * 分类所得 必填:是 见分类所得计算结果 +// */ +// private flsd flsd; + /** + * 非居民所得 必填:是 见非居民所得计算结果 + */ + private fjmsd fjmsd; +// /** +// * 限售股所得 必填:是 见限售股所得计算结果 +// */ +// private xsgsd xsgsd; +// /** +// * 人员申报失败列表 必填:是 参考人员代报结果对象 +// */ +// private rysbsblb rysbsblb; + + + @Data + public static class zhsd { + /** + * 人员代代报失败列表 参考人员代报结果对象 + */ + private List rysbsblb; + /** + * 正常工资薪金算税结果对象 参考综合所得算税结果对象 + */ + private ssjgdx zcgzxj; + /** + * 全年一次性奖金收入算税结果对象 参考综合所得算税结果对象 + */ + private ssjgdx qnycxjjsslb; + /** + * 稿酬所得算税结果对象 参考综合所得算税结果对象 + */ + private ssjgdx gcsdlb; + /** + * 一般劳务报酬算税结果对象 参考综合所得算税结果对象 + */ + private ssjgdx lwbclb; + /** + * 解除劳动合同一次性补偿金列表 参考综合所得算税结果对象 + */ + private ssjgdx jcldhtycxbcjlb; + /** + * 保险营销员薪金算税结果对象 参考综合所得算税结果对象 + */ + private ssjgdx bxyxy; + /** + * 证券经纪人薪金算税结果对象 参考综合所得算税结果对象 + */ + private ssjgdx zqjjr; + /** + * 特许权算税结果对象 参考综合所得算税结果对象 + */ + private ssjgdx txq; + /** + * 个人股权激励结果对象 参考综合所得算税结果对象 + */ + private ssjgdx grgqjl; + /** + * 企业年金结果对象 参考综合所得算税结果对象 + */ + private ssjgdx qynj; + /** + * 内退一次性补偿金 参考综合所得算税结果对象 + */ + private ssjgdx ntycxbcjlb; + /** + * 其他连续劳务报酬 参考综合所得算税结果对象 + */ + private ssjgdx qtlxlwbc; + /** + * 其他非连续劳务报酬 参考综合所得算税结果对象 + */ + private ssjgdx qtflxlwbc; + /** + * 提前退休一次性补贴 参考综合所得算税结果对象 + */ + private ssjgdx tqtxycxbt; + /** + * 央企负责人绩效薪金延期兑现收入和任期奖励 参考综合所得算税结果对象 + */ + private ssjgdx yqfzrsrhjl; + /** + * 法律援助劳务报酬 参考综合所得算税结果对象 + */ + private ssjgdx flyzlwbclb; + + + @Data + public static class rysb { + /** + * 姓名 + */ + private String xm; + /** + * 证件类型名称 + */ + private String zzlx; + /** + * 证件号码 + */ + private String zzhm; + /** + * 代报状态 1 待报送 2 代报中 3 代报失败 4 代报成功 + */ + private String sbzt; + /** + * 人员认证状态 + */ + private String rzzt; + /** + * 失败原因 + */ + private String sbyy; + /** + * 专项代报状态 + */ + private String clzt; + /** + * 专项代报结果原因 + */ + private String cljgms; + } + + @Data + public static class ssjgdx { + /** + * 综合算税成功列表 参考综合所得输出结果报文 + */ + private List sscglb; + /** + * 综合算税失败列表 参考综合所得输出结果报文 + */ + private List sssblb; + /** + * 综合算税失败原因列表 参考算税失败原因对象 + */ + private List sssbyylb; + /** + * 参与综合算税总人数 + */ + private int sszrs; + /** + * 综合算税失败总人数 + */ + private int sssbrs; + /** + * 年金上限 + */ + private BigDecimal njsx; + /** + * 住房公积金上限 + */ + private BigDecimal zfgjjsx; + /** + * 年平均工资 + */ + private BigDecimal npjgz; + /** + * 企业上月是否已申报 0:上月未申报 1:上月已申报 2:上上月未申报 + */ + private String qysysfysb; + } + + } + + + @Data + public static class fjmsd { + /** + * 正常工资薪金(无住所个人正常工资薪金)所得列表 参考非居民所得算税结果对象 + */ + private ssjgdx wjgzxjlb; + /** + * 无住所个人数月奖金列表 参考非居民所得算税结果对象 + */ + private ssjgdx wjrysyjjlb; + /** + * 劳务报酬列表 参考非居民所得算税结果对象 + */ + private ssjgdx lwbclb; + /** + * 稿酬所得列表 参考非居民所得算税结果对象 + */ + private ssjgdx gcsdlb; + /** + * 利息姑息红利所得列表 参考非居民所得算税结果对象 + */ + private ssjgdx lxgxhllb; + /** + * 股权转让列表 参考非居民所得算税结果对象 + */ + private ssjgdx gqzrlb; + /** + * 其他财产转让列表 参考非居民所得算税结果对象 + */ + private ssjgdx qtcczrlb; + /** + * 偶然所得列表 参考非居民所得算税结果对象 + */ + private ssjgdx orsdlb; + /** + * 解除劳动合同一次性补偿金列表 参考非居民所得算税结果对象 + */ + private ssjgdx jcldhtycxbcjlb; + /** + * 保险营销员薪金算税结果对象 参考非居民所得算税结果对象 + */ + private ssjgdx bxyxy; + /** + * 证券经纪人薪金算税结果对象 参考非居民所得算税结果对象 + */ + private ssjgdx zqjjr; + /** + * 个人股权激励结果对象 参考非居民所得算税结果对象 + */ + private ssjgdx grgqjl; + /** + * 特许权使用费所得 参考非居民所得算税结果对象 + */ + private ssjgdx txqsyfsd; + /** + * 个人房屋出租所得 参考非居民所得算税结果对象 + */ + private ssjgdx grfwczsd; + + @Data + public static class ssjgdx { + /** + * 非居民算税成功列表 参考输入报文非居民所得输出结果报文 + */ + private List sscglb; + /** + * 非居民算税失败列表 参考输入报文非居民所得输出结果报文 + */ + private List sssblb; + /** + * 非居民算税失败原因列表 参考算税失败原因对象 + */ + private List sssbyylb; + /** + * 参与非居民算税总人数 + */ + private int sszrs; + /** + * 非居民算税失败总人数 + */ + private int sssbrs; + } + } + + @Data + public static class result { + + //--------------综合所得输出结果报文------------------------------ + + /** + * 是否明细申报 必填:否 是或者否 + */ + private String sfmxsb; + /** + * 姓名 必填:否 如果是汇总申报返回空 + */ + @TableTitle(title = "姓名", dataIndex = "xm",key = "xm") + private String xm; + /** + * 证件类型 必填:否 见证件类型字典 如果是汇总申报返回空 + */ + private String zzlx; + /** + * 证件号码 必填:否 如果是汇总申报返回空 + */ + private String zzhm; + /** + * 任职受雇日期 必填:是 格式YYYY-MM-DD + */ + private String rzsgrq; + /** + * 离职日期 必填:否 格式YYYY-MM-DD + */ + private String lzrq; + /** + * 当期收入额 必填:是 不填写默认为0 + */ + @TableTitle(title = "当期收入额", dataIndex = "sre",key = "sre") + private BigDecimal sre; + /** + * 当期免税收入 必填:否 + */ + private BigDecimal mssd; + /** + * 基本养老保险 必填:否 + */ + private BigDecimal jbylaobxf; + /** + * 基本医疗保险 必填:否 + */ + private BigDecimal jbylbxf; + /** + * 失业保险 必填:否 + */ + private BigDecimal sybxf; + /** + * 住房公积金 必填:否 + */ + private BigDecimal zfgjj; + /** + * 子女教育支出 必填:否 + */ + private BigDecimal znjyzc; + /** + * 赡养老人支出 必填:否 + */ + private BigDecimal sylrzc; + /** + * 住房贷款利息支出 必填:否 + */ + private BigDecimal zfdklxzc; + /** + * 住房租金支出 必填:否 + */ + private BigDecimal zfzjzc; + /** + * 继续教育支出 必填:否 + */ + private BigDecimal jxjyzc; + /** + * 非学历继续教育支出 必填:否 + */ + private BigDecimal fxljxjyzc; + /** + * 3岁以下婴幼儿照护支出 必填:否 + */ + private BigDecimal yyezhzc; + /** + * 年金 必填:否 + */ + private BigDecimal nj; + /** + * 商业健康保险 必填:否 + */ + private BigDecimal syjkbx; + /** + * 税延养老保险 必填:否 + */ + private BigDecimal syylbx; + /** + * 其他 必填:否 按法律规定可以在税前扣除的项目 + */ + private BigDecimal qt; + /** + * 准予扣除的捐赠额 必填:否 + */ + private BigDecimal zykcjze; + /** + * 减免税额 必填:否 + */ + private BigDecimal jmse; + /** + * 备注 必填:否 + */ + private String bz; + /** + * 减除费用 必填:否 正常工资薪金的减除费用。 对应保险营销员、证券经纪人的费用 + */ + private BigDecimal jcfy; + /** + * 其他扣除合计 必填:否 + */ + private BigDecimal qtckhj; + /** + * 应纳税所得额 必填:否 正常工资薪金返回否 + */ + @TableTitle(title = "应纳税所得额", dataIndex = "ynssde",key = "ynssde") + private BigDecimal ynssde; + /** + * 应纳税额 必填:否 正常工资薪金返回否 + */ + private BigDecimal ynse; + /** + * 已缴税额 必填:否 正常工资薪金返回否 + */ + private BigDecimal ykjse; + /** + * 应扣缴税额 必填:否 正常工资薪金返回否 + */ + private BigDecimal yingkjse; + /** + * 税率 必填:否 + */ + private BigDecimal sl; + /** + * 速算扣除数 必填:否 + */ + private BigDecimal sskcs; + /** + * 所得项目名称 必填:是 正常工资薪金;全年一次性奖金收入;稿酬所得;劳务报酬 + */ + private String sdxm; + /** + * 应补退税额 必填:否 应补退税额=累计应扣缴税额-累计已缴税额 + */ + @TableTitle(title = "应补退税额", dataIndex = "ybtse",key = "ybtse") + private BigDecimal ybtse; + /** + * 累计收入额 必填:否 + */ + private BigDecimal ljsre; + /** + * 累计免税收入额 必填:否 + */ + private BigDecimal ljmssd; + /** + * 累计专项扣除额 必填:否 三险一金合计 + */ + private BigDecimal ljzxkce; + /** + * 累计专项附加扣除额 必填:否 专项附加合计 + */ + private BigDecimal ljzxfjkce; + /** + * 累计其他扣除额 必填:否 + */ + private BigDecimal ljqtkce; + /** + * 累计减免税额 必填:否 + */ + private BigDecimal ljjmse; + /** + * 累计减除费用额 必填:否 正常工资薪金累计减除费用 必填:否 对应保险营销员、证券经纪人累计费用 + */ + private BigDecimal ljjcfye; + /** + * 累计月减除费用 必填:否 保险营销员、证券经纪人,其他连续劳务报酬的减除费用 + */ + private BigDecimal ljyjcfy; + /** + * 允许扣除税费 必填:否 保险营销员、证券经纪人 + */ + private BigDecimal yxkcsf; + /** + * 展业成本 必填:否 保险营销员、证券经纪人 + */ + private BigDecimal zycb; + /** + * 月减除费用 必填:否 保险营销员、证券经纪人,其他连续劳务报酬的减除费用 + */ + private BigDecimal yjcfy; + /** + * 累计应纳税所得额 必填:否 + */ + @TableTitle(title = "累计应纳税所得额", dataIndex = "ljynssde",key = "ljynssde") + private BigDecimal ljynssde; + /** + * 累计应纳税额 必填:否 + */ + private BigDecimal ljynse; + /** + * 累计应扣缴税额 必填:否 累计应扣缴税额 = 累计应纳税额 - 累计减免税额 + */ + private BigDecimal ljyingkjse; + /** + * 累计已缴税额 必填:否 + */ + private BigDecimal ljykjse; + /** + * 累计子女教育支出 必填:否 + */ + private BigDecimal ljznjyzc; + /** + * 累计继续教育支出 必填:否 + */ + private BigDecimal ljjxjyzc; + /** + * 累计非学历继续教育支持 必填:否 + */ + private BigDecimal ljfxljxjyzc; + /** + * 累计学历继续教育支持 必填:否 + */ + private BigDecimal ljxljxjyzc; + /** + * 累计住房租金支出 必填:否 + */ + private BigDecimal ljzfzjzc; + /** + * 累计房屋贷款支出 必填:否 + */ + private BigDecimal ljzfdklxzc; + /** + * 累计赡养老人支出 必填:否 + */ + private BigDecimal ljsylrzc; + /** + * 累计3岁以下婴幼儿照护支出 必填:否 + */ + private BigDecimal ljyyezhzc; + /** + * 累计准予扣除的捐赠额 必填:否 + */ + private BigDecimal ljzykcjze; + /** + * 累计个人养老金 必填:否 + */ + private BigDecimal ljgrylj; + /** + * 累计个人养老金校验码 必填:否 + */ + private String ljgryljjym; + /** + * 仅在两个月算税场景时使用,当前月分为N月: + * 0表示N-1月(上月)未申报 + * 1表示N-1月(上月)已申报 + * 2表示N-2月(上上个月)未申报 + */ + private String qysysfysb; + + /** + * 当前月分为N,如果N-1(上月)已申报,则返回N-1月员工在税局累计已扣缴的税额; + * 如果N-1月未申报,则返回N-2月工在税局累计已扣缴的税额; + */ + private BigDecimal ygzsjljykjse; + /** + * 本月已累计扣除税额 必填:否 针对一月多次算税的场景字段 + */ + private BigDecimal byyljkjse; + /** + * 本次应扣缴税额 必填:否 针对一月多次算税的场景字段,本次应扣缴税额=本月应扣缴税额-本月已累计税额 + */ + private BigDecimal bcykjse; + /** + * 分摊年度数 必填:否 + */ + private Integer ftnds; + /** + * 年减除费用 必填:否 默认为60000 + */ + private BigDecimal njcfy; + + + //----------非居民所得输出结果报文------------------------------- + + /* + * 姓名 必填:是 + */ +// private String xm; + /* + * 证件类型名称 必填:是 + */ +// private String zzlx; + /* + * 证件号码 必填:是 + */ +// private String zzhm; + /* + * 收入额 必填:是 + */ +// private String sre; + /* + * 累计收入(不含本次) 必填:是 + */ +// private String ljsre; + /* + * 免税收入 必填:是 + */ +// private String mssd; + /** + * 财产原值 必填:是 + */ + private String ccyz; + /* + * 允许扣除的税费 必填:是 + */ +// private String yxkcsf; + /** + * 投资抵扣 必填:是 + */ + private String tzdk; + /* + * 其他 必填:是 + */ +// private String qt; + /* + * 备注 必填:是 + */ +// private String bz; + /** + * 实际工作年限 必填:是 + */ + private String sjgznxs; + /* + * 减除费用 必填:是 + */ +// private String jcfy; + /* + * 准予扣除的捐赠额 必填:是 + */ +// private String zykcjze; + /* + * 税前扣除项目合计 必填:是 + */ +// private String sqkcxmhj; + /* + * 应纳税额所得额 必填:是 + */ +// private String ynssde; + /* + * 应纳税额 必填:是 + */ +// private String ynse; + /* + * 减免税额 必填:是 + */ +// private String jmse; + /* + * 应扣缴税额 必填:是 + */ +// private String yingkjse; + /* + * 已扣缴税额 必填:是 无需填写该值,按0处理 + */ +// private String ykjse; + /* + * 税率 必填:是 + */ +// private String sl; + /* + * 速算扣除数 必填:是 + */ + // private String sskcs; + /** + * 代报方式 必填:是 + */ + private String sbfs; + /* + * 应补退税额 必填:是 + */ + // private String ybtse; + /* + * 非居民所得项目名字 必填:是  非居民所得薪金类别-无住所个人正常工资薪金、全年一次性奖金收入 + */ + // private String sdxm; + /** + * 所得期间起 必填:是 YYYY-MM + */ + private String sdqjq; + /** + * 所得期间止 必填:是 YYYY-MM + */ + private String sdqjz; + + } + + /** + * 算税失败原因对象 + */ + @Data + public static class sssbyy { + /** + * 人员ID + */ + private Integer ygid; + /** + * 人员名称 + */ + private String xm; + /** + * 证件类型 见证件类型字典 + */ + private String zzlx; + /** + * 证件号码 + */ + private String zzhm; + /** + * 错误码 + */ + private String cwm; + /** + * 错误信息 + */ + private String cwxx; + /** + * 所得税的code + */ + private String sdxmdm; + /** + * 所得税的名称 + */ + private String sdxmmc; + } + + } + + +} diff --git a/src/com/engine/salary/service/EmployeeDeclareService.java b/src/com/engine/salary/service/EmployeeDeclareService.java index 3243a0234..94c52cafa 100644 --- a/src/com/engine/salary/service/EmployeeDeclareService.java +++ b/src/com/engine/salary/service/EmployeeDeclareService.java @@ -6,6 +6,7 @@ import com.engine.salary.entity.employeedeclare.dto.EmployeeDeclareListDTO; import com.engine.salary.entity.employeedeclare.dto.EmployeeDeclareRateDTO; import com.engine.salary.entity.employeedeclare.param.*; import com.engine.salary.entity.employeedeclare.po.EmployeeDeclarePO; +import com.engine.salary.entity.salaryacct.po.SalaryAcctTaxAgentPO; import com.engine.salary.util.page.PageInfo; import java.util.Collection; @@ -109,6 +110,14 @@ public interface EmployeeDeclareService{ */ PageInfo listPage4FailByParam(EmployeeDeclareFailListQueryParam param); + /** + * 根据薪资核算记录关系的个税扣缴义务人查询报送人员 + * + * @param salaryAcctTaxAgents + * @return + */ + List listBySalaryAcctTaxAgent(List salaryAcctTaxAgents); + /** * 保存 * diff --git a/src/com/engine/salary/service/SalaryAcctCalcTaxReqService.java b/src/com/engine/salary/service/SalaryAcctCalcTaxReqService.java new file mode 100644 index 000000000..8fe41c879 --- /dev/null +++ b/src/com/engine/salary/service/SalaryAcctCalcTaxReqService.java @@ -0,0 +1,30 @@ +package com.engine.salary.service; + +import com.engine.salary.entity.salaryacct.po.SalaryAcctCalcTaxReqPO; + +import java.util.List; + +public interface SalaryAcctCalcTaxReqService { + + /** + * 根据薪资核算记录查询 + * + * @param salaryAcctRecordId + * @return + */ + List listByRecordId(Long salaryAcctRecordId); + + /** + * 批量保存 + * + * @param salaryAcctCalcTaxReqs + */ + void batchSave(List salaryAcctCalcTaxReqs); + + /** + * 根据薪资核算记录删除 + * + * @param salaryAcctRecordId + */ + void deleteByRecordId(Long salaryAcctRecordId); +} diff --git a/src/com/engine/salary/service/SalaryAcctResultService.java b/src/com/engine/salary/service/SalaryAcctResultService.java index 0090f8330..e2e83b054 100644 --- a/src/com/engine/salary/service/SalaryAcctResultService.java +++ b/src/com/engine/salary/service/SalaryAcctResultService.java @@ -116,6 +116,7 @@ public interface SalaryAcctResultService { * @param salaryAcctResultPOS 薪资核算结果 */ void batchSave(List salaryAcctResultPOS); + void batchUpdate(List salaryAcctResultPOS); /** * 根据薪资核算人员id删除薪资核算结果 diff --git a/src/com/engine/salary/service/SalaryCalcTaxService.java b/src/com/engine/salary/service/SalaryCalcTaxService.java new file mode 100644 index 000000000..7e6efec5c --- /dev/null +++ b/src/com/engine/salary/service/SalaryCalcTaxService.java @@ -0,0 +1,29 @@ +package com.engine.salary.service; + +import com.engine.salary.entity.salaryacct.dto.SalaryCalcTaxInfoDTO; +import com.engine.salary.entity.salaryacct.param.SalaryCalcTaxParam; + +public interface SalaryCalcTaxService { + + /** + * 根据薪资核算记录id获取在线计算个税的相关信息 + * + * @param salaryCalcTaxParam + * @return + */ + SalaryCalcTaxInfoDTO getCalcTaxInfo(SalaryCalcTaxParam salaryCalcTaxParam); + + /** + * 计算个税 + * + * @param salaryCalcTaxParam + */ + void calcTax(SalaryCalcTaxParam salaryCalcTaxParam); + + /** + * 计算个税获取反馈 + * + * @param salaryCalcTaxParam + */ + void calcTaxFeedback(SalaryCalcTaxParam salaryCalcTaxParam); +} diff --git a/src/com/engine/salary/service/impl/EmployeeDeclareServiceImpl.java b/src/com/engine/salary/service/impl/EmployeeDeclareServiceImpl.java index a88612e7e..264a83e56 100644 --- a/src/com/engine/salary/service/impl/EmployeeDeclareServiceImpl.java +++ b/src/com/engine/salary/service/impl/EmployeeDeclareServiceImpl.java @@ -20,6 +20,7 @@ import com.engine.salary.entity.employeedeclare.po.EmployeeDeclarePO; import com.engine.salary.entity.employeedeclare.po.EmployeeDeclareRecordPO; import com.engine.salary.entity.employeedeclare.response.DeclareEmployeeFeedbackResponse; import com.engine.salary.entity.employeedeclare.response.DeclareEmployeeInfoResponse; +import com.engine.salary.entity.salaryacct.po.SalaryAcctTaxAgentPO; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO; import com.engine.salary.entity.salaryarchive.po.SalaryArchivePO; import com.engine.salary.entity.taxagent.bo.TaxAgentTaxReturnBO; @@ -188,6 +189,24 @@ public class EmployeeDeclareServiceImpl extends Service implements EmployeeDecla return page; } + @Override + public List listBySalaryAcctTaxAgent(List salaryAcctTaxAgents) { + if (CollectionUtils.isEmpty(salaryAcctTaxAgents)) { + return Collections.emptyList(); + } + Map employeeDeclareParamMap = new HashMap<>(); + for (SalaryAcctTaxAgentPO po : salaryAcctTaxAgents) { + employeeDeclareParamMap.putIfAbsent(po.getTaxAgentId() + "-" + po.getTaxCycle(), po); + } + List employeeDeclares = new ArrayList<>(); + for (Map.Entry entry : employeeDeclareParamMap.entrySet()) { + SalaryAcctTaxAgentPO salaryAcctTaxAgent = entry.getValue(); + List temp = listByTaxCycleAndTaxAgentId(salaryAcctTaxAgent.getTaxCycle(), salaryAcctTaxAgent.getTaxAgentId()); + employeeDeclares.addAll(temp); + } + return employeeDeclares; + } + @Override public void save(EmployeeDeclareSaveParam saveParam) { Date now = new Date(); diff --git a/src/com/engine/salary/service/impl/SalaryAcctCalcTaxReqServiceImpl.java b/src/com/engine/salary/service/impl/SalaryAcctCalcTaxReqServiceImpl.java new file mode 100644 index 000000000..c23a9b87c --- /dev/null +++ b/src/com/engine/salary/service/impl/SalaryAcctCalcTaxReqServiceImpl.java @@ -0,0 +1,37 @@ +package com.engine.salary.service.impl; + +import com.engine.core.impl.Service; +import com.engine.salary.entity.salaryacct.po.SalaryAcctCalcTaxReqPO; +import com.engine.salary.mapper.salaryacct.SalaryAcctCalcTaxReqMapper; +import com.engine.salary.service.SalaryAcctCalcTaxReqService; +import com.engine.salary.util.db.MapperProxyFactory; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +public class SalaryAcctCalcTaxReqServiceImpl extends Service implements SalaryAcctCalcTaxReqService { + + private SalaryAcctCalcTaxReqMapper getSalaryAcctCalcTaxReqMapper() { + return MapperProxyFactory.getProxy(SalaryAcctCalcTaxReqMapper.class); + } + + + @Override + public List listByRecordId(Long salaryAcctRecordId) { + return getSalaryAcctCalcTaxReqMapper().listSome(SalaryAcctCalcTaxReqPO.builder().salaryAcctRecordId(salaryAcctRecordId).build()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void batchSave(List salaryAcctCalcTaxReqs) { + if (CollectionUtils.isNotEmpty(salaryAcctCalcTaxReqs)) { + salaryAcctCalcTaxReqs.forEach(getSalaryAcctCalcTaxReqMapper()::insertIgnoreNull); + } + } + + @Override + public void deleteByRecordId(Long salaryAcctRecordId) { + getSalaryAcctCalcTaxReqMapper().deleteByRecordId(salaryAcctRecordId); + } +} diff --git a/src/com/engine/salary/service/impl/SalaryAcctResultServiceImpl.java b/src/com/engine/salary/service/impl/SalaryAcctResultServiceImpl.java index 32a23ed79..0bb2244ae 100644 --- a/src/com/engine/salary/service/impl/SalaryAcctResultServiceImpl.java +++ b/src/com/engine/salary/service/impl/SalaryAcctResultServiceImpl.java @@ -704,6 +704,15 @@ public class SalaryAcctResultServiceImpl extends Service implements SalaryAcctRe } } + public void batchUpdate(List salaryAcctResultPOS) { + if (CollectionUtils.isNotEmpty(salaryAcctResultPOS)) { + // 数据加密 + encryptUtil.encryptList(salaryAcctResultPOS, SalaryAcctResultPO.class); + List> partition = Lists.partition(salaryAcctResultPOS, 100); + partition.forEach(getSalaryAcctResultMapper()::batchUpdate); + } + } + @Override public void deleteBySalaryAcctEmployeeIds(Collection salaryAcctEmployeeIds) { diff --git a/src/com/engine/salary/service/impl/SalaryCalcTaxServiceImpl.java b/src/com/engine/salary/service/impl/SalaryCalcTaxServiceImpl.java new file mode 100644 index 000000000..4edb5b06a --- /dev/null +++ b/src/com/engine/salary/service/impl/SalaryCalcTaxServiceImpl.java @@ -0,0 +1,315 @@ +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); + } +} diff --git a/src/com/engine/salary/util/SalaryEntityUtil.java b/src/com/engine/salary/util/SalaryEntityUtil.java index 81e5b12d9..f14a1a2d8 100644 --- a/src/com/engine/salary/util/SalaryEntityUtil.java +++ b/src/com/engine/salary/util/SalaryEntityUtil.java @@ -163,6 +163,36 @@ public class SalaryEntityUtil { Collectors.collectingAndThen(Collectors.toList(), e -> e.stream().map(valueMapper).collect(Collectors.toList())))); } + public static Map> list2Map(Collection objs, Function function1, Function function2, Function function3) { + if (CollectionUtils.isEmpty(objs)) { + return Maps.newHashMap(); + } + Map> collect = objs.stream().collect(Collectors.groupingBy(function1)); + Map> map = new HashMap<>(); + for (Map.Entry> entry: collect.entrySet()) { + Map values = map.getOrDefault(entry.getKey(), new HashMap<>()); + entry.getValue().forEach(e -> values.put(function2.apply(e), function3.apply(e))); + map.put(entry.getKey(), values); + } + return map; + } + + public static Map> list2Map(Collection objs, Function function1, Function function2) { + if (CollectionUtils.isEmpty(objs)) { + return Maps.newHashMap(); + } + Map> collect = objs.stream().collect(Collectors.groupingBy(function1)); + Map> map = new HashMap<>(); + for (Map.Entry> entry: collect.entrySet()) { + Map values = map.getOrDefault(entry.getKey(), new HashMap<>()); + entry.getValue().forEach(e -> values.put(function2.apply(e), e)); + map.put(entry.getKey(), values); + } + return map; + } + + + /** * LinkedHashMap有序去重 * @@ -211,9 +241,10 @@ public class SalaryEntityUtil { /** * 进位规则 - * @param newScale 小数位 + * + * @param newScale 小数位 * @param rententionRule 进位规则 - * @param value 值 + * @param value 值 * @return */ public static BigDecimal carryRule(Integer newScale, Integer rententionRule, BigDecimal value) { @@ -374,7 +405,6 @@ public class SalaryEntityUtil { } - public static String null2String(Object obj) { if (Objects.isNull(obj)) { return ""; diff --git a/src/com/engine/salary/web/SalaryAcctController.java b/src/com/engine/salary/web/SalaryAcctController.java index 52d95a469..b70d97416 100644 --- a/src/com/engine/salary/web/SalaryAcctController.java +++ b/src/com/engine/salary/web/SalaryAcctController.java @@ -11,6 +11,7 @@ import com.engine.salary.util.ResponseResult; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.page.PageInfo; import com.engine.salary.wrapper.*; +import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.parameters.RequestBody; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -494,6 +495,33 @@ public class SalaryAcctController { return new ResponseResult(user).run(getSalaryAcctResultWrapper(user)::calculate, param); } + @POST + @Path("/acctresult/getCalcTaxInfo") + @ApiOperation("获取「计算个税」和「获取个税计算反馈」反馈的显示与否") + @Produces(MediaType.APPLICATION_JSON) + public String getCalcTaxInfo(@Context HttpServletRequest request, @Context HttpServletResponse response,@RequestBody SalaryCalcTaxParam salaryCalcTaxParam) { + User user = HrmUserVarify.getUser(request, response); + return new ResponseResult(user).run(getSalaryAcctResultWrapper(user)::getCalcTaxInfo, salaryCalcTaxParam); + } + + @POST + @Path("/acctresult/calcTax") + @ApiOperation("计算个税") + @Produces(MediaType.APPLICATION_JSON) + public String calcTax(@Context HttpServletRequest request, @Context HttpServletResponse response,@RequestBody SalaryCalcTaxParam salaryCalcTaxParam) { + User user = HrmUserVarify.getUser(request, response); + return new ResponseResult(user).run(getSalaryAcctResultWrapper(user)::calcTax, salaryCalcTaxParam); + } + + @POST + @Path("/acctresult/calcTaxFeedback") + @ApiOperation("获取个税计算反馈") + @Produces(MediaType.APPLICATION_JSON) + public String calcTaxFeedback(@Context HttpServletRequest request, @Context HttpServletResponse response,@RequestBody SalaryCalcTaxParam salaryCalcTaxParam) { + User user = HrmUserVarify.getUser(request, response); + return new ResponseResult(user).run(getSalaryAcctResultWrapper(user)::calcTaxFeedback, salaryCalcTaxParam); + } + //导出核算结果 @GET @Path("/acctresult/export") @@ -692,7 +720,7 @@ public class SalaryAcctController { // @GetMapping("/checkresult/getCount") // @ApiOperation(("获取校验结果(异常)总数")) -// @WeaPermission +// @Produces(MediaType.APPLICATION_JSON) // public WeaResult getCheckResultCount(@RequestParam(value = "salaryAcctRecordId") Long salaryAcctRecordId) { // Integer salaryCheckResultCount = salaryAcctCheckResultWrapper.countBySalaryAcctRecordId(salaryAcctRecordId, TenantContext.getCurrentTenantKey()); // return WeaResult.success(salaryCheckResultCount); @@ -700,7 +728,7 @@ public class SalaryAcctController { // // @PostMapping("/checkresult/list") // @ApiOperation("校验结果列表") -// @WeaPermission +// @Produces(MediaType.APPLICATION_JSON) // public WeaResult> listCheckResult(@RequestBody @Validated SalaryCheckResultQueryParam queryParam) { // WeaTable weaTable = salaryAcctCheckResultWrapper.listPage(queryParam, TenantContext.getCurrentTenantKey()); // return WeaResult.success(weaTable); @@ -708,7 +736,7 @@ public class SalaryAcctController { // // @PostMapping("/checkresultdetail/list") // @ApiOperation("校验结果明细列表") -// @WeaPermission +// @Produces(MediaType.APPLICATION_JSON) // public WeaResult> listCheckResultRecord(@RequestBody @Validated SalaryCheckResultRecordQueryParam queryParam) { // WeaTable weaTable = salaryAcctCheckResultWrapper.listPage4CheckResultRecord(queryParam, TenantContext.getCurrentTenantKey()); // return WeaResult.success(weaTable); @@ -716,7 +744,7 @@ public class SalaryAcctController { // // @PostMapping("/checkresult/ignore") // @ApiOperation("校验结果列表") -// @WeaPermission +// @Produces(MediaType.APPLICATION_JSON) // public WeaResult ignoreCheckResult(@RequestParam(value = "id") Long id) { // salaryAcctCheckResultWrapper.ignoreById(id, TenantContext.getCurrentTenantKey()); // return WeaResult.success(null); @@ -724,7 +752,7 @@ public class SalaryAcctController { // // @PostMapping("/checkresult/ignoreAll") // @ApiOperation("校验结果列表") -// @WeaPermission +// @Produces(MediaType.APPLICATION_JSON) // public WeaResult ignoreAllCheckResult(@RequestParam(value = "salaryAcctRecordId") Long salaryAcctRecordId) { // salaryAcctCheckResultWrapper.ignoreBySalaryAcctRecordId(salaryAcctRecordId, TenantContext.getCurrentTenantKey()); // return WeaResult.success(null); @@ -732,7 +760,7 @@ public class SalaryAcctController { // // @PostMapping("/acctresult/check") // @ApiOperation(("薪资核算结果校验")) -// @WeaPermission +// @Produces(MediaType.APPLICATION_JSON) // public WeaResult check(@RequestBody @Validated SalaryAcctCheckParam checkParam) { // salaryAcctResultWrapper.check(checkParam, UserContext.getCurrentUser(), TenantContext.getCurrentTenantKey()); // return WeaResult.success(null); @@ -740,7 +768,7 @@ public class SalaryAcctController { // // @PostMapping("/checkresult/export") // @ApiOperation("校验异常导出") -// @WeaPermission +// @Produces(MediaType.APPLICATION_JSON) // public WeaResult> exportCheckResult(@RequestBody @Validated SalaryCheckResultExportParam exportParam) { // DataCollectionEmployee simpleEmployee = UserContext.getCurrentUser(); // String tenantKey = TenantContext.getCurrentTenantKey(); @@ -751,7 +779,7 @@ public class SalaryAcctController { // // @PostMapping("/checkresultRecord/export") // @ApiOperation("校验异常明细导出") -// @WeaPermission +// @Produces(MediaType.APPLICATION_JSON) // public WeaResult> exportCheckResultDetail(@RequestParam(value = "checkResultId") Long checkResultId) { // DataCollectionEmployee simpleEmployee = UserContext.getCurrentUser(); // String tenantKey = TenantContext.getCurrentTenantKey(); diff --git a/src/com/engine/salary/web/SalarySobController.java b/src/com/engine/salary/web/SalarySobController.java index 3782721f4..1fe36dbdb 100644 --- a/src/com/engine/salary/web/SalarySobController.java +++ b/src/com/engine/salary/web/SalarySobController.java @@ -103,6 +103,13 @@ public class SalarySobController { return new ResponseResult>(user).run(getSalarySobWrapper(user)::listAll); } + @GET + @Path("/incomeCategoryList") + @Produces(MediaType.APPLICATION_JSON) + public String getSalarySobBasicForm(@Context HttpServletRequest request, @Context HttpServletResponse response) { + User user = HrmUserVarify.getUser(request, response); + return new ResponseResult>>(user).run(getSalarySobWrapper(user)::incomeCategoryList); + } /** * 薪资账套基本信息表单 diff --git a/src/com/engine/salary/wrapper/SalaryAcctResultWrapper.java b/src/com/engine/salary/wrapper/SalaryAcctResultWrapper.java index cae703b1c..d8ebc1009 100644 --- a/src/com/engine/salary/wrapper/SalaryAcctResultWrapper.java +++ b/src/com/engine/salary/wrapper/SalaryAcctResultWrapper.java @@ -9,6 +9,7 @@ import com.engine.salary.entity.progress.ProgressDTO; import com.engine.salary.entity.salaryacct.dto.ConsolidatedTaxDetailDTO; import com.engine.salary.entity.salaryacct.dto.SalaryAcctResultDetailDTO; import com.engine.salary.entity.salaryacct.dto.SalaryAcctResultListColumnDTO; +import com.engine.salary.entity.salaryacct.dto.SalaryCalcTaxInfoDTO; import com.engine.salary.entity.salaryacct.param.*; import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO; import com.engine.salary.exception.SalaryRunTimeException; @@ -75,6 +76,10 @@ public class SalaryAcctResultWrapper extends Service implements SalaryAcctResult return ServiceUtil.getService(SalarySysConfServiceImpl.class, user); } + private SalaryCalcTaxService getSalaryCalcTaxService(User user) { + return ServiceUtil.getService(SalaryCalcTaxServiceImpl.class, user); + } + /** * 薪资核算列表 * @@ -298,4 +303,32 @@ public class SalaryAcctResultWrapper extends Service implements SalaryAcctResult // }; // ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.OTHER, "salaryAcctCheck", localRunnable); // } + + /** + * 根据薪资核算记录id获取在线计算个税的相关信息 + * + * @param salaryCalcTaxParam + * @return + */ + public SalaryCalcTaxInfoDTO getCalcTaxInfo(SalaryCalcTaxParam salaryCalcTaxParam) { + return getSalaryCalcTaxService(user).getCalcTaxInfo(salaryCalcTaxParam); + } + + /** + * 计算个税 + * + * @param salaryCalcTaxParam + */ + public void calcTax(SalaryCalcTaxParam salaryCalcTaxParam) { + getSalaryCalcTaxService(user).calcTax(salaryCalcTaxParam); + } + + /** + * 计算个税获取反馈 + * + * @param salaryCalcTaxParam + */ + public void calcTaxFeedback(SalaryCalcTaxParam salaryCalcTaxParam) { + getSalaryCalcTaxService(user).calcTaxFeedback(salaryCalcTaxParam); + } } diff --git a/src/com/engine/salary/wrapper/SalarySobWrapper.java b/src/com/engine/salary/wrapper/SalarySobWrapper.java index e0f456a5f..72f9f1518 100644 --- a/src/com/engine/salary/wrapper/SalarySobWrapper.java +++ b/src/com/engine/salary/wrapper/SalarySobWrapper.java @@ -269,4 +269,18 @@ public class SalarySobWrapper extends Service { return taxAgentIds.contains(salarySobPO.getTaxAgentId()) || Objects.isNull(salarySobPO.getTaxAgentId()); } + public List> incomeCategoryList() { + IncomeCategoryEnum[] values = IncomeCategoryEnum.values(); + List> list = new ArrayList<>(values.length); + for (IncomeCategoryEnum value : values) { + Map map = new HashMap(); + map.put("enum", value); + map.put("value", value.getValue()); + map.put("defaultLabel", value.getDefaultLabel()); + map.put("labelId", value.getLabelId()); + map.put("reportTypeName", value.getReportType().getDefaultLabel()); + list.add(map); + } + return list; + } } diff --git a/test/ParseTaxApi.java b/test/ParseTaxApi.java index 56bb4a986..716d56807 100644 --- a/test/ParseTaxApi.java +++ b/test/ParseTaxApi.java @@ -7,9 +7,9 @@ import java.util.List; public class ParseTaxApi { public static void main(String[] args) { - readExcel("H:\\code\\salary\\test\\ApiDes.xlsx"); +// readExcel("H:\\code\\salary\\test\\ApiDes.xlsx"); -// readExcel2("H:\\code\\salary\\test\\ApiDes.xlsx"); + readExcel2("H:\\code\\salary\\test\\ApiDes.xlsx"); }