weaver-hrm-salary/src/com/engine/salary/entity/taxdeclaration/bo/TaxDeclarationBO.java

376 lines
23 KiB
Java
Raw Normal View History

2022-04-16 15:33:51 +08:00
package com.engine.salary.entity.taxdeclaration.bo;
import com.engine.salary.entity.datacollection.AddUpSituation;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
2022-04-18 18:56:17 +08:00
import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationDetailListDTO;
2022-04-16 15:33:51 +08:00
import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationListDTO;
import com.engine.salary.entity.taxdeclaration.param.TaxDeclarationSaveParam;
import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationDetailPO;
import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationPO;
import com.engine.salary.entity.taxrate.TaxAgent;
import com.engine.salary.enums.salarysob.IncomeCategoryEnum;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
2022-04-18 18:56:17 +08:00
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
2022-04-16 15:33:51 +08:00
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import dm.jdbc.util.IdGenerator;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* @description: 个税申报表
* @author: xiajun
* @modified By: xiajun
* @date: Created in 12/15/21 10:01 AM
* @version:v1.0
*/
public class TaxDeclarationBO {
public static List<TaxDeclarationListDTO> convert2ListDTO(List<TaxDeclarationPO> taxDeclarations,
List<DataCollectionEmployee> simpleEmployees,
List<TaxAgent> taxAgents) {
if (CollectionUtils.isEmpty(simpleEmployees)) {
return Collections.emptyList();
}
Map<Long, String> taxAgentNameMap = SalaryEntityUtil.convert2Map(taxAgents, TaxAgent::getId, TaxAgent::getName);
Map<Long, String> employeeNameMap = SalaryEntityUtil.convert2Map(simpleEmployees, DataCollectionEmployee::getEmployeeId, DataCollectionEmployee::getUsername);
return taxDeclarations.stream().map(e -> TaxDeclarationListDTO.builder()
.id(e.getId())
2022-04-19 20:58:30 +08:00
.salaryMonth(e.getSalaryMonth())
2022-04-16 15:33:51 +08:00
.taxAgentId(e.getTaxAgentId())
.taxAgentName(taxAgentNameMap.getOrDefault(e.getTaxAgentId(), ""))
2022-04-19 20:58:30 +08:00
.taxCycle(e.getTaxCycle())
2022-04-16 15:33:51 +08:00
.operateEmployeeId(e.getCreator())
.operateEmployeeName(employeeNameMap.getOrDefault(e.getCreator(), ""))
.operateTime(SalaryDateUtil.getFormatLocalDateTime(e.getCreateTime()))
.description(e.getDescription())
.build()).collect(Collectors.toList());
}
2022-04-18 18:56:17 +08:00
public static void buildDetailListDTO(Long taxDeclarationId,
PageInfo<TaxDeclarationDetailListDTO> page,
2022-04-16 15:33:51 +08:00
List<TaxDeclarationDetailPO> taxDeclarationDetails,
2022-04-18 18:56:17 +08:00
List<DataCollectionEmployee> simpleEmployees) {
2022-04-16 15:33:51 +08:00
if (CollectionUtils.isEmpty(taxDeclarationDetails)) {
return;
}
2022-04-18 18:56:17 +08:00
int index = (page.getNextPage() - 1) * page.getSize();
2022-04-16 15:33:51 +08:00
List<TaxDeclarationDetailListDTO> dtos = Lists.newArrayListWithExpectedSize(simpleEmployees.size());
Map<Long, List<TaxDeclarationDetailPO>> taxDeclarationDetailMap = SalaryEntityUtil.group2Map(taxDeclarationDetails, TaxDeclarationDetailPO::getEmployeeId);
2022-04-18 18:56:17 +08:00
for (DataCollectionEmployee simpleEmployee : simpleEmployees) {
2022-04-16 15:33:51 +08:00
Map<String, String> valueMap = SalaryEntityUtil.convert2Map(taxDeclarationDetailMap.get(simpleEmployee.getEmployeeId()), TaxDeclarationDetailPO::getFieldCode, TaxDeclarationDetailPO::getFieldValue);
TaxDeclarationDetailListDTO dto = new TaxDeclarationDetailListDTO();
dto.setId(simpleEmployee.getEmployeeId());
dto.setTaxDeclarationId(taxDeclarationId);
dto.setSeq(++index);
dto.setEmployeeId(simpleEmployee.getEmployeeId());
dto.setEmployeeName(simpleEmployee.getUsername());
dto.setIdCardType(SalaryI18nUtil.getI18nLabel(101696,"身份证"));
dto.setIdCardNo("");
dto.setTaxpayerIdNo("");
dto.setResidentType(SalaryI18nUtil.getI18nLabel(101697,"居民"));
dto.setIncomeType(SalaryI18nUtil.getI18nLabel(101698,"工资、薪金"));
dto.setIncome(valueMap.getOrDefault("income",""));
dto.setFee(valueMap.getOrDefault("fee", ""));
dto.setTaxFreeIncome(valueMap.getOrDefault("taxFreeIncome", ""));
dto.setSubtraction(valueMap.getOrDefault("subtraction", ""));
dto.setEndowmentInsurance(valueMap.getOrDefault("endowmentInsurance", ""));
dto.setMedicalInsurance(valueMap.getOrDefault("medicalInsurance",""));
dto.setUnemploymentInsurance(valueMap.getOrDefault("unemploymentInsurance",""));
dto.setHousingProvidentFund(valueMap.getOrDefault("housingProvidentFund",""));
dto.setAnnuity(valueMap.getOrDefault("annuity",""));
dto.setCommercialHealthInsurance(valueMap.getOrDefault("commercialHealthInsurance",""));
dto.setTaxDeferredEndowmentInsurance(valueMap.getOrDefault("taxDeferredEndowmentInsurance",""));
dto.setOriginalValueOfProperty(valueMap.getOrDefault("originalValueOfProperty",""));
dto.setDeductedTax(valueMap.getOrDefault("deductedTax",""));
dto.setOther(valueMap.getOrDefault("other",""));
dto.setAddUpIncome(valueMap.getOrDefault("addUpIncome",""));
dto.setAddUpSubtraction(valueMap.getOrDefault("addUpSubtraction",""));
dto.setAddUpSpecialDeduction(valueMap.getOrDefault("addUpSpecialDeduction",""));
dto.setAddUpChildEducation(valueMap.getOrDefault("addUpChildEducation",""));
dto.setAddUpContinuingEducation(valueMap.getOrDefault("addUpContinuingEducation",""));
dto.setAddUpHousingLoanInterest(valueMap.getOrDefault("addUpHousingLoanInterest",""));
dto.setAddUpHousingRent(valueMap.getOrDefault("addUpHousingRent",""));
dto.setAddUpSupportElderly(valueMap.getOrDefault("addUpSupportElderly",""));
dto.setAddUpOther(valueMap.getOrDefault("addUpOtherDeduction",""));
dto.setLessTaxProportion(valueMap.getOrDefault("lessTaxProportion",""));
dto.setAllowedDonation(valueMap.getOrDefault("addUpAllowedDonation",""));
dto.setTaxableIncome(valueMap.getOrDefault("addUpTaxableIncome",""));
dto.setTaxRate(valueMap.getOrDefault("taxRate",""));
dto.setQuickDeductionFactor(valueMap.getOrDefault("quickDeductionFactor",""));
dto.setTaxPayable(valueMap.getOrDefault("addUpTaxPayable",""));
dto.setTaxSavings(valueMap.getOrDefault("addUpTaxDeduction",""));
dto.setTaxWithheld(valueMap.getOrDefault("taxWithheld",""));
dto.setRefundedOrSupplementedTax(valueMap.getOrDefault("refundedOrSupplementedTax",""));
dtos.add(dto);
}
2022-04-18 18:56:17 +08:00
page.setList(dtos);
}
2022-04-16 15:33:51 +08:00
public static Result handle(TaxDeclarationSaveParam saveParam,
Date taxCycle,
List<SalaryItemPO> salaryItems,
List<SalarySobPO> salarySobs,
List<SalaryAcctResultPO> salaryAcctResults
) {
Result result = new Result();
if (CollectionUtils.isEmpty(salaryAcctResults)) {
return result;
}
// 薪资项目聚合成map为了根据code获取id
Map<String, Long> salaryItemMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getCode, SalaryItemPO::getId);
// 薪资账套聚合成map为了根据id获取incomeCategory
Map<Long, SalarySobPO> salarySobPOMap = SalaryEntityUtil.convert2Map(salarySobs, SalarySobPO::getId);
// 薪资核算结果按照个税扣缴义务人id、所用薪资账套的incomeCategory聚合成map
/* Map<Long, Map<Integer, List<SalaryAcctResultPO>>> taxAgentIdKeyAcctResultMap = salaryAcctResults.stream()
.collect(Collectors.groupingBy(SalaryAcctResultPO::getTaxAgentId,
Collectors.groupingBy(salaryAcctResultPO -> salarySobPOMap.get(salaryAcctResultPO.getSalarySobId()).getIncomeCategory())));
*/// 一个个税扣缴义务人,一种薪资类型生成一张个税申报表
Map<Long, List<SalaryAcctResultPO>> taxAgentIdKeyAcctResultMap = SalaryEntityUtil.group2Map(salaryAcctResults, SalaryAcctResultPO::getTaxAgentId);
taxAgentIdKeyAcctResultMap.forEach((k, v) -> {
// 新增的个税申报表
TaxDeclarationPO taxDeclaration = convert2PO(saveParam, taxCycle, k);
result.getNeedInsertTaxDeclarations().add(taxDeclaration);
// 处理个税申报明细以及累计情况
handleTaxDeclarationDetail(result, taxDeclaration, v, salaryItemMap);
});
/*taxAgentIdKeyAcctResultMap.forEach((taxAgentId, incomeCategoryKeyAcctResultPOMap) -> {
incomeCategoryKeyAcctResultPOMap.forEach((incomeCategory, salaryAcctResultPOS) -> {
// 新增的个税申报表
TaxDeclarationPO taxDeclaration = convert2PO(saveParam, taxCycle, taxAgentId, incomeCategory, employeeId);
result.getNeedInsertTaxDeclarations().add(taxDeclaration);
if (Objects.equals(incomeCategory, IncomeCategoryEnum.WAGES_AND_SALARIES.getValue())) {
// 生成个税申报表
handleTaxDeclaration4Wage(result, taxDeclaration, salaryAcctResultPOS, salaryItemMap);
// 生成往期累计情况
handleAddUpSituation(result, taxDeclaration, salaryAcctResultPOS, salaryItemMap);
}
if (Objects.equals(incomeCategory, IncomeCategoryEnum.REMUNERATION_FOR_LABOR.getValue())) {
// 生成个税申报表
handleTaxDeclaration4Labor(result, taxDeclaration, salaryAcctResultPOS, salaryItemMap);
}
});
});*/
return result;
}
private static void handleTaxDeclarationDetail(Result result,
TaxDeclarationPO taxDeclaration,
List<SalaryAcctResultPO> salaryAcctResults,
Map<String, Long> salaryItemMap) {
if (CollectionUtils.isEmpty(salaryAcctResults)) {
return;
}
// 核算结果按照人员id分类
Map<Long, List<SalaryAcctResultPO>> acctResultMap = SalaryEntityUtil.group2Map(salaryAcctResults, SalaryAcctResultPO::getEmployeeId);
acctResultMap.forEach((k, v) -> {
Map<String, BigDecimal> valueMap = Maps.newHashMapWithExpectedSize(32);
Map<Long, List<SalaryAcctResultPO>> resultMap = SalaryEntityUtil.group2Map(v, SalaryAcctResultPO::getSalaryItemId);
// 收入
BigDecimal income = SalaryEntityUtil.reduce(resultMap.get(salaryItemMap.getOrDefault("income", 0L)), e -> SalaryEntityUtil.empty2Zero(e.getResultValue()));
valueMap.put("income", income);
// 费用
BigDecimal fee = BigDecimal.ZERO;
valueMap.put("fee", fee);
// 免税收入
BigDecimal taxFreeIncome = BigDecimal.ZERO;
valueMap.put("taxFreeIncome", taxFreeIncome);
// 减除费用
BigDecimal subtraction = findValue("subtraction", resultMap, salaryItemMap);
valueMap.put("subtraction", subtraction);
// 基本养老保险
BigDecimal endowmentInsurance = findValue("endowmentInsurance", resultMap, salaryItemMap);
valueMap.put("endowmentInsurance", endowmentInsurance);
// 基本医疗保险
BigDecimal medicalInsurance = findValue("medicalInsurance", resultMap, salaryItemMap);
valueMap.put("medicalInsurance", medicalInsurance);
// 失业保险
BigDecimal unemploymentInsurance = findValue("unemploymentInsurance", resultMap, salaryItemMap);
valueMap.put("unemploymentInsurance", unemploymentInsurance);
// 住房公积金
BigDecimal housingProvidentFund = findValue("housingProvidentFund", resultMap, salaryItemMap);
valueMap.put("housingProvidentFund", housingProvidentFund);
// 年金
BigDecimal annuity = findValue("annuity", resultMap, salaryItemMap);
valueMap.put("annuity", annuity);
// 商业健康保险
BigDecimal commercialHealthInsurance = findValue("commercialHealthInsurance", resultMap, salaryItemMap);
valueMap.put("commercialHealthInsurance", commercialHealthInsurance);
// 税延养老保险
BigDecimal taxDeferredEndowmentInsurance = findValue("taxDeferredEndowmentInsurance", resultMap, salaryItemMap);
valueMap.put("taxDeferredEndowmentInsurance", taxDeferredEndowmentInsurance);
// 财产原值
BigDecimal originalValueOfProperty = findValue("originalValueOfProperty", resultMap, salaryItemMap);
valueMap.put("originalValueOfProperty", originalValueOfProperty);
// 允许扣除的税费
BigDecimal deductedTax = findValue("deductedTax", resultMap, salaryItemMap);
valueMap.put("deductedTax", deductedTax);
// 其他
BigDecimal other = findValue("other", resultMap, salaryItemMap);
valueMap.put("other", other);
// 累计收入
BigDecimal addUpIncome = findAddUpValue("addUpIncome", resultMap, salaryItemMap);
valueMap.put("addUpIncome", addUpIncome);
// 累计减除费用
BigDecimal addUpSubtraction = findAddUpValue("addUpSubtraction", resultMap, salaryItemMap);
valueMap.put("addUpSubtraction", addUpSubtraction);
// 累计专项扣除
BigDecimal addUpSpecialDeduction = findAddUpValue("addUpSpecialDeduction", resultMap, salaryItemMap);
valueMap.put("addUpSpecialDeduction", addUpSpecialDeduction);
// 累计子女教育
BigDecimal addUpChildEducation = findAddUpValue("addUpChildEducation", resultMap, salaryItemMap);
valueMap.put("addUpChildEducation", addUpChildEducation);
// 累计继续教育
BigDecimal addUpContinuingEducation = findAddUpValue("addUpContinuingEducation", resultMap, salaryItemMap);
valueMap.put("addUpContinuingEducation", addUpContinuingEducation);
// 累计住房贷款利息
BigDecimal addUpHousingLoanInterest = findAddUpValue("addUpHousingLoanInterest", resultMap, salaryItemMap);
valueMap.put("addUpHousingLoanInterest", addUpHousingLoanInterest);
// 累计住房租金
BigDecimal addUpHousingRent = findAddUpValue("addUpHousingRent", resultMap, salaryItemMap);
valueMap.put("addUpHousingRent", addUpHousingRent);
// 累计赡养老人
BigDecimal addUpSupportElderly = findAddUpValue("addUpSupportElderly", resultMap, salaryItemMap);
valueMap.put("addUpSupportElderly", addUpSupportElderly);
// 累计其他扣除
BigDecimal addUpOtherDeduction = findAddUpValue("addUpOtherDeduction", resultMap, salaryItemMap);
valueMap.put("addUpOtherDeduction", addUpOtherDeduction);
// 减按计税比例
BigDecimal lessTaxProportion = BigDecimal.ONE;
valueMap.put("lessTaxProportion", lessTaxProportion);
// 准允扣除的捐赠额
BigDecimal addUpAllowedDonation = findAddUpValue("addUpAllowedDonation", resultMap, salaryItemMap);
valueMap.put("addUpAllowedDonation", addUpAllowedDonation);
// 应纳税所得额
BigDecimal addUpTaxableIncome = findAddUpValue("addUpTaxableIncome", resultMap, salaryItemMap);
valueMap.put("addUpTaxableIncome", addUpTaxableIncome);
// 税率
BigDecimal taxRate = findAddUpValue("taxRate", resultMap, salaryItemMap);
valueMap.put("taxRate", taxRate);
// 速算扣除数
BigDecimal quickDeductionFactor = findAddUpValue("quickDeductionFactor", resultMap, salaryItemMap);
valueMap.put("quickDeductionFactor", quickDeductionFactor);
// 应纳税额
BigDecimal addUpTaxPayable = findAddUpValue("addUpTaxPayable", resultMap, salaryItemMap);
valueMap.put("addUpTaxPayable", addUpTaxPayable);
// 减免税额
BigDecimal addUpTaxDeduction = BigDecimal.ZERO;
valueMap.put("addUpTaxDeduction", addUpTaxDeduction);
// 应补缴税额
BigDecimal refundedOrSupplementedTax = SalaryEntityUtil.reduce(resultMap.get(salaryItemMap.getOrDefault("refundedOrSupplementedTax", 0L)),
e -> SalaryEntityUtil.empty2Zero(e.getResultValue()));
valueMap.put("refundedOrSupplementedTax", refundedOrSupplementedTax);
// 已扣缴税额
BigDecimal taxWithheld = addUpTaxPayable.subtract(refundedOrSupplementedTax);
valueMap.put("taxWithheld", taxWithheld);
valueMap.forEach((key, value) -> {
TaxDeclarationDetailPO detailPO = TaxDeclarationDetailPO.builder()
.id(IdGenerator.generate())
.taxDeclarationId(taxDeclaration.getId())
.employeeId(k)
.fieldCode(key)
.fieldValue(value.toPlainString())
.creator(taxDeclaration.getCreator())
2022-04-19 20:58:30 +08:00
.createTime(taxDeclaration.getCreateTime())
.updateTime(taxDeclaration.getUpdateTime())
2022-04-16 15:33:51 +08:00
.deleteType(0)
.tenantKey(taxDeclaration.getTenantKey())
.build();
result.getNeedInsertTaxDeclarationDetails().add(detailPO);
});
// 累计社保个人合计
BigDecimal addUpSocialSecurityTotal = findAddUpValue("addUpSocialSecurityTotal", resultMap, salaryItemMap);
// 累计公积金个人合计
BigDecimal addUpAccumulationFundTotal = findAddUpValue("addUpAccumulationFundTotal", resultMap, salaryItemMap);
// 累计年金及其他福利合计
BigDecimal addUpEnterpriseAndOther = findAddUpValue("addUpEnterpriseAndOther", resultMap, salaryItemMap);
// 更新累计情况
AddUpSituation accumulatedSituation = AddUpSituation.builder()
.id(IdGenerator.generate())
.employeeId(k)
.taxAgentId(taxDeclaration.getTaxAgentId())
.taxYearMonth((taxDeclaration.getSalaryMonth()))
.year(taxDeclaration.getSalaryMonth().getYear())
.addUpIncome(addUpIncome.toPlainString())
.addUpSocialSecurityTotal(addUpSocialSecurityTotal.toPlainString())
.addUpAccumulationFundTotal(addUpAccumulationFundTotal.toPlainString())
.addUpEnterpriseAndOther(addUpEnterpriseAndOther.toPlainString())
.addUpSubtraction(addUpSubtraction.toPlainString())
.addUpChildEducation(addUpChildEducation.toPlainString())
.addUpContinuingEducation(addUpContinuingEducation.toPlainString())
.addUpHousingLoanInterest(addUpHousingLoanInterest.toPlainString())
.addUpHousingRent(addUpHousingRent.toPlainString())
.addUpSupportElderly(addUpSupportElderly.toPlainString())
.addUpOtherDeduction(addUpOtherDeduction.toPlainString())
.addUpTaxExemptIncome("0")
.addUpAllowedDonation(addUpAllowedDonation.toPlainString())
.addUpAdvanceTax(addUpTaxPayable.toPlainString())
.creator(taxDeclaration.getCreator())
.createTime(taxDeclaration.getCreateTime())
.updateTime(taxDeclaration.getUpdateTime())
.tenantKey(taxDeclaration.getTenantKey())
.deleteType(0)
.build();
result.getNeedInsertAccumulatedSituations().add(accumulatedSituation);
});
}
private static TaxDeclarationPO convert2PO(TaxDeclarationSaveParam saveParam, Date taxCycle, Long taxAgentId) {
LocalDateTime now = LocalDateTime.now();
return TaxDeclarationPO.builder()
.id(IdGenerator.generate())
.taxAgentId(taxAgentId)
.salaryMonth(SalaryDateUtil.localDateToDate(saveParam.getSalaryMonth().atDay(1)))
.taxCycle(taxCycle)
.description(saveParam.getDescription())
// .creator(employeeId)
.createTime(SalaryDateUtil.localDateTimeToDate(now))
.updateTime(SalaryDateUtil.localDateTimeToDate(now))
.deleteType(0)
//.tenantKey(tenantKey)
.build();
}
private static BigDecimal findValue(String fieldCode, Map<Long, List<SalaryAcctResultPO>> resultMap, Map<String, Long> salaryItemMap) {
return resultMap.getOrDefault(salaryItemMap.getOrDefault(fieldCode, 0L), Collections.emptyList()).stream()
.map(e -> SalaryEntityUtil.empty2Zero(e.getResultValue()))
.filter(e -> e.compareTo(BigDecimal.ZERO) > 0)
.findAny()
.orElse(BigDecimal.ZERO);
}
private static BigDecimal findAddUpValue(String fieldCode, Map<Long, List<SalaryAcctResultPO>> resultMap, Map<String, Long> salaryItemMap) {
return resultMap.getOrDefault(salaryItemMap.getOrDefault(fieldCode, 0L), Collections.emptyList()).stream()
.map(e -> SalaryEntityUtil.empty2Zero(e.getResultValue()))
.max(Comparator.comparingDouble(BigDecimal::doubleValue))
.orElse(BigDecimal.ZERO);
}
@Data
public static class Result {
private Collection<TaxDeclarationPO> needInsertTaxDeclarations;
private Collection<TaxDeclarationDetailPO> needInsertTaxDeclarationDetails;
private Collection<AddUpSituation> needInsertAccumulatedSituations;
public Result() {
this.needInsertTaxDeclarations = Lists.newArrayList();
this.needInsertTaxDeclarationDetails = Lists.newArrayList();
this.needInsertAccumulatedSituations = Lists.newArrayList();
}
}
}