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

379 lines
23 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationDetailListDTO;
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.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.google.common.collect.Lists;
import dm.jdbc.util.IdGenerator;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import weaver.hrm.User;
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())
.salaryMonth(e.getSalaryMonth())
.taxAgentId(e.getTaxAgentId())
.taxAgentName(taxAgentNameMap.getOrDefault(e.getTaxAgentId(), ""))
.taxCycle(e.getTaxCycle())
.operateEmployeeId(e.getCreator())
.operateEmployeeName(employeeNameMap.getOrDefault(e.getCreator(), ""))
.operateTime(SalaryDateUtil.getFormatLocalDateTime(e.getCreateTime()))
.description(e.getDescription())
.build()).collect(Collectors.toList());
}
public static void buildDetailListDTO(Long taxDeclarationId,
PageInfo<TaxDeclarationDetailListDTO> page,
List<TaxDeclarationDetailPO> taxDeclarationDetails,
List<DataCollectionEmployee> simpleEmployees) {
if (CollectionUtils.isEmpty(taxDeclarationDetails)) {
return;
}
int index = (page.getNextPage() - 1) * page.getSize();
List<TaxDeclarationDetailListDTO> dtos = Lists.newArrayListWithExpectedSize(simpleEmployees.size());
Map<Long, List<TaxDeclarationDetailPO>> taxDeclarationDetailMap = SalaryEntityUtil.group2Map(taxDeclarationDetails, TaxDeclarationDetailPO::getEmployeeId);
for (DataCollectionEmployee simpleEmployee : simpleEmployees) {
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);
}
page.setList(dtos);
}
public static Result handle(TaxDeclarationSaveParam saveParam,
Date taxCycle,
User user,
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,user, taxCycle, k);
result.getNeedInsertTaxDeclarations().add(taxDeclaration);
// 处理个税申报明细以及累计情况
handleTaxDeclarationDetail(result, taxDeclaration, v, 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) -> {
Long employeeId = k;
Map<String, BigDecimal> valueMap = new HashMap<>();
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 addUpTaxFreeIncome = findAddUpValue("addUpTaxFreeIncome", resultMap, salaryItemMap);
valueMap.put("addUpTaxFreeIncome", addUpTaxFreeIncome);
// 累计减除费用
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 addUpIllnessMedical = findAddUpValue("addUpIllnessMedical", resultMap, salaryItemMap);
valueMap.put("addUpIllnessMedical", addUpIllnessMedical);
// 累计婴幼儿照护
BigDecimal addUpInfantCare = findAddUpValue("addUpInfantCare", resultMap, salaryItemMap);
valueMap.put("addUpInfantCare", addUpInfantCare);
// 累计其他扣除
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 taxDeduction = findValue("taxDeduction", resultMap, salaryItemMap);
valueMap.put("taxDeduction", taxDeduction);
// 应补缴税额
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())
.createTime(taxDeclaration.getCreateTime())
.updateTime(taxDeclaration.getUpdateTime())
.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(employeeId)
.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())
.addUpIllnessMedical(addUpIllnessMedical.toPlainString())
.addUpInfantCare(addUpInfantCare.toPlainString())
.addUpOtherDeduction(addUpOtherDeduction.toPlainString())
.addUpTaxExemptIncome(addUpTaxFreeIncome.toPlainString())
.addUpAllowedDonation(addUpAllowedDonation.toPlainString())
.addUpAdvanceTax(addUpTaxPayable.toPlainString())
// .addUpTaxSavings(taxDeduction.toPlainString())
.creator(taxDeclaration.getCreator())
.createTime(taxDeclaration.getCreateTime())
.updateTime(taxDeclaration.getUpdateTime())
.tenantKey(taxDeclaration.getTenantKey())
.deleteType(NumberUtils.INTEGER_ZERO)
.build();
result.getNeedInsertAccumulatedSituations().add(accumulatedSituation);
});
}
private static TaxDeclarationPO convert2PO(TaxDeclarationSaveParam saveParam, User user,Date taxCycle, Long taxAgentId) {
LocalDateTime now = LocalDateTime.now();
if(saveParam.getDescription()==null){
saveParam.setDescription("");
}
return TaxDeclarationPO.builder()
.id(IdGenerator.generate())
.taxAgentId(taxAgentId)
.salaryMonth(SalaryDateUtil.localDateToDate(saveParam.getSalaryMonth().atDay(1)))
.taxCycle(taxCycle)
.description(saveParam.getDescription())
.creator((long)user.getUID())
.createTime(SalaryDateUtil.localDateTimeToDate(now))
.updateTime(SalaryDateUtil.localDateTimeToDate(now))
.deleteType(0)
.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();
}
}
}