package com.engine.salary.service.impl; import cn.hutool.core.util.NumberUtil; import com.cloudstore.eccom.pc.table.WeaTableColumn; import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; import com.engine.salary.constant.SalaryDefaultTenantConstant; import com.engine.salary.encrypt.EncryptUtil; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.employeedeclare.po.EmployeeDeclarePO; import com.engine.salary.entity.extemp.po.ExtEmpPO; import com.engine.salary.entity.taxdeclaration.bo.TaxDeclarationValueList; import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationValueListDTO; import com.engine.salary.entity.taxdeclaration.param.TaxDeclarationValueListQueryParam; import com.engine.salary.entity.taxdeclaration.param.TaxDeclareRecordDetailSaveParam; import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationPO; import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationValuePO; import com.engine.salary.entity.taxdeclaration.po.TaxDeclareRecordPO; import com.engine.salary.entity.taxdeclaration.po.TaxReportColumnPO; import com.engine.salary.enums.salaryaccounting.EmployeeTypeEnum; import com.engine.salary.enums.salaryitem.SalaryDataTypeEnum; import com.engine.salary.enums.salarysob.IncomeCategoryEnum; import com.engine.salary.enums.sicategory.DeleteTypeEnum; import com.engine.salary.enums.taxdeclaration.SourceEnum; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.mapper.taxdeclaration.TaxDeclarationValueMapper; import com.engine.salary.mapper.taxdeclaration.TaxDeclareRecordMapper; import com.engine.salary.remote.tax.client.DeclareClient; import com.engine.salary.remote.tax.response.employee.GetDeclareTaxResultFeedbackResponse; import com.engine.salary.service.*; import com.engine.salary.util.JsonUtil; import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.SalaryEnumUtil; import com.engine.salary.util.db.MapperProxyFactory; import com.engine.salary.util.page.PageInfo; import com.engine.salary.util.page.SalaryPageUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import dm.jdbc.util.IdGenerator; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import weaver.general.Util; import weaver.hrm.User; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * 个税申报表 *

Copyright: Copyright (c) 2023

*

Company: 泛微软件

* * @author qiantao * @version 1.0 **/ @Slf4j public class TaxDeclarationValueServiceImpl extends Service implements TaxDeclarationValueService { public EncryptUtil encryptUtil = new EncryptUtil(); private TaxDeclarationValueMapper getTaxDeclarationValueMapper() { return MapperProxyFactory.getProxy(TaxDeclarationValueMapper.class); } private TaxDeclareRecordMapper getTaxDeclareRecordMapper() { return MapperProxyFactory.getProxy(TaxDeclareRecordMapper.class); } private SalaryEmployeeService getSalaryEmployeeService(User user) { return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user); } private ExtEmpService getExtEmpService(User user) { return ServiceUtil.getService(ExtEmpServiceImpl.class, user); } private EmployeeDeclareService getEmployeeDeclareService(User user) { return ServiceUtil.getService(EmployeeDeclareServiceImpl.class, user); } private TaxReportColumnService getTaxReportColumnService(User user) { return ServiceUtil.getService(TaxReportColumnServiceImpl.class, user); } private TaxDeclarationService getTaxDeclarationService(User user) { return ServiceUtil.getService(TaxDeclarationServiceImpl.class, user); } @Override public PageInfo listPageByTaxDeclarationIds(TaxDeclarationValueListQueryParam queryParam, Collection taxDeclarationIds) { List taxDeclarationValuePOS = getTaxDeclarationValueMapper().listSome(TaxDeclarationValuePO.builder().taxDeclarationIds(taxDeclarationIds).build()); taxDeclarationValuePOS = decryptBatch(taxDeclarationValuePOS); return SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), taxDeclarationValuePOS, TaxDeclarationValuePO.class); } @Override public List listByTaxDeclarationIds(Collection taxDeclarationIds) { List taxDeclarationValues = getTaxDeclarationValueMapper().listSome(TaxDeclarationValuePO.builder().taxDeclarationIds(taxDeclarationIds).build()); return decryptBatch(taxDeclarationValues); } @Override public List listByTaxDeclarationId(Long taxDeclarationId) { List taxDeclarationValues = getTaxDeclarationValueMapper().listSome(TaxDeclarationValuePO.builder().taxDeclarationId(taxDeclarationId).build()); return decryptBatch(taxDeclarationValues); } @Override public List listByTaxDeclarationIdsNoDecrypt(Collection taxDeclarationIds) { return getTaxDeclarationValueMapper().listSome(TaxDeclarationValuePO.builder().taxDeclarationIds(taxDeclarationIds).build()); } @Override public TaxDeclarationValueListDTO convert2List(TaxDeclarationPO taxDeclaration, List taxDeclarationValues) { // 查询个税申报表表头 IncomeCategoryEnum incomeCategoryEnum = SalaryEnumUtil.enumMatchByValue(taxDeclaration.getIncomeCategory(), IncomeCategoryEnum.class); List taxReportColumns = getTaxReportColumnService(user).listByIncomeCategory(incomeCategoryEnum, 0); // 人员id Set employeeIds = SalaryEntityUtil.properties(taxDeclarationValues, TaxDeclarationValuePO::getEmployeeId); // 查询报送的人员 List employeeDeclares = getEmployeeDeclareService(user).listByTaxCycleAndTaxAgentIdAndEmployeeIds(taxDeclaration.getTaxCycle(), taxDeclaration.getTaxAgentId(), employeeIds); // 查询人员信息 List simpleEmployeeIds = taxDeclarationValues.stream() .filter(taxDeclarationValue -> taxDeclarationValue.getEmployeeType() == null || Objects.equals(taxDeclarationValue.getEmployeeType(), EmployeeTypeEnum.ORGANIZATION.getValue())) .map(TaxDeclarationValuePO::getEmployeeId) .distinct() .collect(Collectors.toList()); List simpleEmployees = getSalaryEmployeeService(user).getEmployeeByIds(simpleEmployeeIds); // 查询人员薪资(身份证号码等) List simpleUserInfos = getSalaryEmployeeService(user).getEmployeeByIds(simpleEmployeeIds); // 查询外部人员 List extEmployeeIds = taxDeclarationValues.stream() .filter(taxDeclarationValue -> Objects.equals(taxDeclarationValue.getEmployeeType(), EmployeeTypeEnum.EXT_EMPLOYEE.getValue())) .map(TaxDeclarationValuePO::getEmployeeId) .collect(Collectors.toList()); List extEmployees = getExtEmpService(user).getExtEmpByIds(extEmployeeIds); // 列表表头 List weaTableColumns = TaxDeclarationValueList.buildTableColumns(taxReportColumns); // 列表数据 List> data = TaxDeclarationValueList.buildTableData(incomeCategoryEnum, taxReportColumns, taxDeclarationValues, employeeDeclares, simpleEmployees, simpleUserInfos, extEmployees, false); return new TaxDeclarationValueListDTO().setColumns(weaTableColumns).setData(data); } @Override public void batchSave(List taxDeclarationValues) { if (CollectionUtils.isNotEmpty(taxDeclarationValues)) { // 加密 taxDeclarationValues.forEach(taxDeclarationValue -> taxDeclarationValue.setResultValueJson(JsonUtil.toJsonString(taxDeclarationValue.getResultValue()))); taxDeclarationValues = encryptUtil.encryptList(taxDeclarationValues, TaxDeclarationValuePO.class); // 分批保存 List> partition = Lists.partition(taxDeclarationValues, 100); for (List subTaxDeclarationValues : partition) { subTaxDeclarationValues.forEach(getTaxDeclarationValueMapper()::insertIgnoreNull); } } } @Override public void batchEdit(List taxDeclarationValues) { if (CollectionUtils.isNotEmpty(taxDeclarationValues)) { // 加密 taxDeclarationValues.forEach(taxDeclarationValue -> taxDeclarationValue.setResultValueJson(JsonUtil.toJsonString(taxDeclarationValue.getResultValue()))); taxDeclarationValues = encryptUtil.encryptList(taxDeclarationValues, TaxDeclarationValuePO.class); // 分批保存 List> partition = Lists.partition(taxDeclarationValues, 100); for (List subTaxDeclarationValues : partition) { subTaxDeclarationValues.forEach(getTaxDeclarationValueMapper()::updateIgnoreNull); } } } @Override public void save(TaxDeclareRecordDetailSaveParam param) { TaxDeclarationPO taxDeclaration = getTaxDeclarationService(user).getById(param.getTaxDeclarationId()); if (taxDeclaration == null) { throw new SalaryRunTimeException("个税申报表不存在!"); } Long taxDeclareRecordId = taxDeclaration.getTaxDeclareRecordId(); TaxDeclareRecordPO declareRecordPO = getTaxDeclareRecordMapper().getById(taxDeclareRecordId); if (declareRecordPO == null) { throw new SalaryRunTimeException("个税申报记录不存在!"); } TaxDeclarationValuePO po = TaxDeclarationValuePO.builder() .id(IdGenerator.generate()) .taxDeclarationId(param.getTaxDeclarationId()) .taxDeclareRecordId(taxDeclareRecordId) .employeeId(param.getEmployeeId()) .employeeType(param.getEmployeeType()) .resultValue(param.getTaxReportColumnValues()) .resultValueJson(JsonUtil.toJsonString(param.getTaxReportColumnValues())) .createTime(new Date()) .updateTime(new Date()) .source(SourceEnum.ADD.getValue()) .creator((long) user.getUID()) .deleteType(0) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .build(); encryptUtil.encrypt(po, TaxDeclarationValuePO.class); getTaxDeclarationValueMapper().insertIgnoreNull(po); //新增年终奖 if (IncomeCategoryEnum.ONETIME_ANNUAL_BONUS.getValue().equals(taxDeclaration.getIncomeCategory())) { autoAddWagesDeclare(declareRecordPO); } } @Override public void edit(TaxDeclareRecordDetailSaveParam param) { TaxDeclarationValuePO po = getById(param.getId()); po.setResultValue(param.getTaxReportColumnValues()); po.setResultValueJson(JsonUtil.toJsonString(param.getTaxReportColumnValues())); po.setUpdateTime(new Date()); po.setSource(SourceEnum.EDIT.getValue()); encryptUtil.encrypt(po, TaxDeclarationValuePO.class); getTaxDeclarationValueMapper().updateIgnoreNull(po); } @Override public TaxDeclarationValuePO getById(Long id) { TaxDeclarationValuePO po = getTaxDeclarationValueMapper().getById(id); if (po == null) { throw new SalaryRunTimeException("个税申报明细不存在!"); } encryptUtil.decrypt(po, TaxDeclarationValuePO.class); po.setResultValue(JsonUtil.parseMap(po.getResultValueJson(), String.class)); return po; } @Override public void deleteByTaxDeclareRecordIds(Collection taxDeclareRecordIds) { if (CollectionUtils.isEmpty(taxDeclareRecordIds)) { return; } getTaxDeclarationValueMapper().deleteBytaxDeclareRecordIds(taxDeclareRecordIds); } private List decryptBatch(List taxDeclarationValues) { if (CollectionUtils.isEmpty(taxDeclarationValues)) { return Collections.emptyList(); } // 解密 taxDeclarationValues = encryptUtil.decryptList(taxDeclarationValues, TaxDeclarationValuePO.class); taxDeclarationValues.forEach(salaryAcctResultValue -> { salaryAcctResultValue.setResultValue(JsonUtil.parseMap(salaryAcctResultValue.getResultValueJson(), String.class)); }); return taxDeclarationValues; } @Override public void autoAddWagesDeclare(TaxDeclareRecordPO taxDeclareRecord) { Long taxDeclareRecordId = taxDeclareRecord.getId(); Date now = new Date(); //非正常薪资的人员 List notWagesEmpIds = getTaxDeclarationValueMapper().queryNotWagesEmpIds(taxDeclareRecordId); if (CollectionUtils.isEmpty(notWagesEmpIds)) { return; } //正常薪资人员 List wagesEmpIds = getTaxDeclarationValueMapper().queryWagesEmpIds(taxDeclareRecordId); //比较差异 List autoAddIds = notWagesEmpIds.stream().filter(id -> !wagesEmpIds.contains(id)).collect(Collectors.toList()); if (CollectionUtils.isEmpty(autoAddIds)) { return; } //正常薪资的表头 List taxReportColumns = getTaxReportColumnService(user).listByIncomeCategory(IncomeCategoryEnum.WAGES_AND_SALARIES, 0); Map valueMap = Maps.newHashMap(); for (TaxReportColumnPO taxReportColumn : taxReportColumns) { String value = Objects.equals(taxReportColumn.getDataType(), SalaryDataTypeEnum.NUMBER.getValue()) ? "0.00" : ""; valueMap.put(taxReportColumn.getReportColumnDataIndex(), value); } //当前申报表是否含正常申报 List list = getTaxDeclarationService(user).listByTaxDeclareRecordId(taxDeclareRecordId, IncomeCategoryEnum.WAGES_AND_SALARIES.getValue()); TaxDeclarationPO taxDeclarationPO; if (CollectionUtils.isNotEmpty(list)) { if (list.size() > 1) { throw new SalaryRunTimeException("存在多条正常工资薪金申报表数据"); } taxDeclarationPO = list.get(0); } else { taxDeclarationPO = TaxDeclarationPO .builder() .id(IdGenerator.generate()) .taxDeclareRecordId(taxDeclareRecordId) .incomeCategory(IncomeCategoryEnum.WAGES_AND_SALARIES.getValue()) .taxAgentId(taxDeclareRecord.getTaxAgentId()) .salaryMonth(taxDeclareRecord.getSalaryMonth()) .taxCycle(taxDeclareRecord.getTaxCycle()) .description(taxDeclareRecord.getRemark()) .controlView(0) .creator((long) user.getUID()) .createTime(now) .updateTime(now) .deleteType(DeleteTypeEnum.NOT_DELETED.getValue()) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .build(); List taxList = new ArrayList<>(); getTaxDeclarationService(user).saveBatch(taxList); } //组装数据,自动补足 List autoAddValuePOs = autoAddIds.stream().map((empId -> { TaxDeclarationValuePO taxDeclarationValue = TaxDeclarationValuePO.builder() .id(IdGenerator.generate()) .taxDeclareRecordId(taxDeclarationPO.getTaxDeclareRecordId()) .taxDeclarationId(taxDeclarationPO.getId()) .employeeType(0) .employeeId(empId) .resultValue(valueMap) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .creator((long) user.getUID()) .deleteType(DeleteTypeEnum.NOT_DELETED.getValue()) .createTime(now) .updateTime(now) .source(SourceEnum.AUTO.getValue()) .build(); return taxDeclarationValue; })).collect(Collectors.toList()); batchSave(autoAddValuePOs); } @Override public Map contrast(Long taxDeclarationId) { TaxDeclarationPO taxDeclaration = getTaxDeclarationService(user).getById(taxDeclarationId); if (taxDeclaration == null) { throw new SalaryRunTimeException("无申报表"); } TaxDeclareRecordPO taxDeclareRecordPO = getTaxDeclareRecordMapper().getById(taxDeclaration.getTaxDeclareRecordId()); if (taxDeclareRecordPO == null) { throw new SalaryRunTimeException("申报记录不存在!"); } //线上数据 DeclareClient declareClient = new DeclareClient(taxDeclareRecordPO.getTaxAgentId()); GetDeclareTaxResultFeedbackResponse declareTaxResultFeedbackResponse = declareClient.getDeclareTaxResultFeedback(taxDeclareRecordPO.getDeclareRequestId()); Map>> onlineDataMap = new HashMap<>(); List list = getTaxDeclarationService(user).listByTaxDeclareRecordId(taxDeclareRecordPO.getId()); list.stream().map(TaxDeclarationPO::getIncomeCategory).map(IncomeCategoryEnum::parseByValue).forEach(e -> e.parseGetDeclareTaxResultFeedbackResponse(onlineDataMap, declareTaxResultFeedbackResponse)); Map resultList = new HashMap<>(); List taxDeclarationValues = listByTaxDeclarationId(taxDeclaration.getId()); // 查询个税申报表表头 IncomeCategoryEnum incomeCategoryEnum = SalaryEnumUtil.enumMatchByValue(taxDeclaration.getIncomeCategory(), IncomeCategoryEnum.class); List taxReportColumns = getTaxReportColumnService(user).listByIncomeCategory(incomeCategoryEnum); List columns = SalaryEntityUtil.properties(taxReportColumns, TaxReportColumnPO::getReportColumnName, Collectors.toList()); // 人员id Set employeeIds = SalaryEntityUtil.properties(taxDeclarationValues, TaxDeclarationValuePO::getEmployeeId); // 查询报送的人员 List employeeDeclares = getEmployeeDeclareService(user).listByTaxCycleAndTaxAgentIdAndEmployeeIds(taxDeclaration.getTaxCycle(), taxDeclaration.getTaxAgentId(), employeeIds); // 查询人员信息 List simpleEmployeeIds = taxDeclarationValues.stream() .filter(taxDeclarationValue -> taxDeclarationValue.getEmployeeType() == null || Objects.equals(taxDeclarationValue.getEmployeeType(), EmployeeTypeEnum.ORGANIZATION.getValue())) .map(TaxDeclarationValuePO::getEmployeeId) .distinct() .collect(Collectors.toList()); List simpleEmployees = getSalaryEmployeeService(user).getEmployeeByIds(simpleEmployeeIds); // 查询人员薪资(身份证号码等) List simpleUserInfos = getSalaryEmployeeService(user).getEmployeeByIds(simpleEmployeeIds); // 查询外部人员 List extEmployeeIds = taxDeclarationValues.stream() .filter(taxDeclarationValue -> Objects.equals(taxDeclarationValue.getEmployeeType(), EmployeeTypeEnum.EXT_EMPLOYEE.getValue())) .map(TaxDeclarationValuePO::getEmployeeId) .collect(Collectors.toList()); List extEmployees = getExtEmpService(user).getExtEmpByIds(extEmployeeIds); // 列表数据 List> localList = TaxDeclarationValueList.buildTableData(incomeCategoryEnum, taxReportColumns, taxDeclarationValues, employeeDeclares, simpleEmployees, simpleUserInfos, extEmployees, true); Map> localMap = new HashMap<>(); for (Map map : localList) { String no = map.getOrDefault("证件号码", "").toString(); localMap.put(no, map); } List> onlineData = onlineDataMap.get(incomeCategoryEnum.getDefaultLabel()); List heads = onlineData.get(0); List> data = onlineData.subList(1, onlineData.size()); List> onlineMap = new ArrayList<>(); for (int i = 0; i < data.size(); i++) { List row = data.get(i); Map m = new HashMap<>(); for (int j = 0; j < heads.size(); j++) { String key = heads.get(j).toString(); m.put(key, row.get(j)); } onlineMap.add(m); } Map> onlineNoMap = new HashMap<>(); for (Map map : onlineMap) { String no = map.getOrDefault("证件号码", "").toString(); onlineNoMap.put(no, map); } List> oneResultList = new ArrayList<>(); for (Map local : localList) { Map result = new HashMap<>(); result.put("姓名", local.get("姓名")); result.put("证件类型", local.get("证件类型")); result.put("证件号码", local.get("证件号码")); String no = local.getOrDefault("证件号码", "").toString(); Map online = onlineNoMap.get(no); taxReportColumns.forEach(col -> { Map temp = Maps.newHashMap(); // 系统值 String localValue = Util.null2String(local.get(col.getReportColumnName())); // 线上值 String onlineValue = Util.null2String(online.get(col.getReportColumnName())); temp.put("local", localValue); temp.put("online", onlineValue); if (NumberUtil.isNumber(localValue) && NumberUtil.isNumber(onlineValue)) { BigDecimal diff = new BigDecimal(localValue).subtract(new BigDecimal(onlineValue)); if (diff.compareTo(new BigDecimal(0)) != 0) { temp.put("diff", diff); } } else { if (!Objects.equals(localValue, onlineValue)) { temp.put("diff", localValue); } } result.put(col.getReportColumnName(), temp); }); oneResultList.add(result); } resultList.put("columns", columns); resultList.put("data", oneResultList); return resultList; } }