package com.engine.salary.service.impl; import com.engine.common.util.ServiceUtil; import com.engine.salary.annotation.SalaryFormulaVar; import com.engine.salary.constant.SalaryDefaultTenantConstant; import com.engine.salary.entity.datacollection.AddUpSituation; import com.engine.salary.entity.salaryitem.bo.SysSalaryItemBO; import com.engine.salary.entity.salaryitem.po.SalaryItemPO; import com.engine.salary.entity.salaryitem.po.SysSalaryItemPO; import com.engine.salary.entity.salarysob.bo.SalarySobInitEnv; import com.engine.salary.entity.salarysob.param.SalarySobBasicSaveParam; import com.engine.salary.entity.salarysob.po.*; import com.engine.salary.entity.taxdeclaration.po.TaxReportColumnPO; import com.engine.salary.enums.SalaryCycleTypeEnum; import com.engine.salary.enums.salarysob.IncomeCategoryEnum; import com.engine.salary.enums.sicategory.DeleteTypeEnum; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.mapper.salarysob.SalarySobMapper; import com.engine.salary.service.*; import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.db.MapperProxyFactory; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import dm.jdbc.util.IdGenerator; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import weaver.hrm.User; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors; /** * @description: 薪资账套初始化 * @author: xiajun * @modified By: xiajun * @date: Created in 2023/5/18 15:32 * @version:v1.0 */ public class SalarySobInitServiceImpl extends AbstractSalarySobInitService { private SalarySobMapper getSalarySobMapper() { return MapperProxyFactory.getProxy(SalarySobMapper.class); } private SalarySobDefaultEmpFieldService getSalarySobDefaultEmpFieldService(User user) { return ServiceUtil.getService(SalarySobDefaultEmpFieldServiceImpl.class, user); } private SalarySobEmpFieldService getSalarySobEmpFieldService(User user) { return ServiceUtil.getService(SalarySobEmpFieldServiceImpl.class, user); } private SalarySobDefaultItemGroupService getSalarySobDefaultItemGroupService(User user) { return ServiceUtil.getService(SalarySobDefaultItemGroupServiceImpl.class, user); } private SalarySobDefaultItemService getSalarySobDefaultItemService(User user) { return ServiceUtil.getService(SalarySobDefaultItemServiceImpl.class, user); } private SysSalaryItemService getSysSalaryItemService(User user) { return ServiceUtil.getService(SysSalaryItemServiceImpl.class, user); } private SalaryItemService getSalaryItemService(User user) { return ServiceUtil.getService(SalaryItemServiceImpl.class, user); } private SalarySobItemGroupService getSalarySobItemGroupService(User user) { return ServiceUtil.getService(SalarySobItemGroupServiceImpl.class, user); } private SalarySobItemService getSalarySobItemService(User user) { return ServiceUtil.getService(SalarySobItemServiceImpl.class, user); } private SalarySobBackItemService getSalarySobBackItemService(User user) { return ServiceUtil.getService(SalarySobBackItemServiceImpl.class, user); } private SalarySobAddUpRuleService getSalarySobAddUpRuleService(User user) { return ServiceUtil.getService(SalarySobAddUpRuleServiceImpl.class, user); } private TaxReportColumnService getTaxReportColumnService(User user) { return ServiceUtil.getService(TaxReportColumnServiceImpl.class, user); } private SalarySobTaxReportRuleService getSalarySobTaxReportRuleService(User user) { return ServiceUtil.getService(SalarySobTaxReportRuleServiceImpl.class, user); } @Override protected void initBasic(SalarySobInitEnv env) { if (env == null || env.getSaveParam() == null || env.getCurrentUser() == null) { throw new SalaryRunTimeException("Invalid arguments"); } // 因为薪资账套的「名称」支持了"小地球",所以在打开新建表单时,后端就会将id传给前端,所以新建保存的时候前端是会将id传给后端的 // 当前端未将id传给后端时,后端自动生成一个id SalarySobBasicSaveParam saveParam = env.getSaveParam(); if (saveParam.getId() == null) { saveParam.setId(IdGenerator.generate()); } Date now = new Date(); SalarySobPO salarySob = new SalarySobPO() // .setId(saveParam.getId()) .setTaxAgentId(saveParam.getTaxAgentId()) .setName(saveParam.getName()) .setIncomeCategory(saveParam.getTaxableItems()) .setSalaryCycleType(saveParam.getSalaryCycleType()) .setSalaryCycleFromDay(saveParam.getSalaryCycleFromDay()) .setTaxCycleType(SalaryCycleTypeEnum.THIS_MONTH.getValue()) .setAttendCycleType(saveParam.getAttendCycleType()) .setAttendCycleFromDay(saveParam.getAttendCycleFromDay()) .setSocialSecurityCycleType(saveParam.getSocialSecurityCycleType()) .setDisable(0) .setDescription(saveParam.getDescription()) // .setOriginSalarySobId(saveParam.getId()) .setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .setCreator((long) env.getCurrentUser().getUID()) .setDeleteType(DeleteTypeEnum.NOT_DELETED.getValue()) .setCreateTime(now) .setUpdateTime(now); getSalarySobMapper().insertIgnoreNull(salarySob); env.setSalarySob(salarySob); } @Override protected void initEmpField(SalarySobInitEnv env) { if (env == null || env.getSaveParam() == null || env.getCurrentUser() == null) { throw new SalaryRunTimeException("Invalid arguments"); } // 查询薪资账套默认的员工信息字段 List salarySobDefaultEmpFields = getSalarySobDefaultEmpFieldService(user).list(); Date now = new Date(); List salarySobEmpFields = salarySobDefaultEmpFields.stream() .map(field -> new SalarySobEmpFieldPO() // .setId(IdGenerator.generate()) .setSalarySobId(env.getSalarySob().getId()) .setFieldCode(field.getFieldCode()) .setSortedIndex(field.getSortedIndex()) .setCanDelete(field.getCanDelete()) .setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .setCreator((long) env.getCurrentUser().getUID()) .setDeleteType(DeleteTypeEnum.NOT_DELETED.getValue()) .setCreateTime(now) .setUpdateTime(now)) .collect(Collectors.toList()); getSalarySobEmpFieldService(user).batchSave(salarySobEmpFields); } @Override protected void initItem(SalarySobInitEnv env) { if (env == null || env.getSaveParam() == null || env.getCurrentUser() == null) { throw new SalaryRunTimeException("Invalid arguments"); } Date now = new Date(); // 根据所得项目查询默认的账套薪资项目分组 List salarySobDefaultItemGroups = getSalarySobDefaultItemGroupService(user) .listByIncomeCategoryIn(Collections.singletonList(IncomeCategoryEnum.parseByValue(env.getSaveParam().getTaxableItems()))); // 根据所得项目查询默认的账套薪资项目 List salarySobDefaultItems = getSalarySobDefaultItemService(user) .listByIncomeCategory(IncomeCategoryEnum.parseByValue(env.getSaveParam().getTaxableItems())); // 根据默认的账套薪资项目查询关联的系统薪资项目id Set sysSalaryItemIds = SalaryEntityUtil.properties(salarySobDefaultItems, SalarySobDefaultItemPO::getSysSalaryItemId); List sysSalaryItems = getSysSalaryItemService(user).listByIds(sysSalaryItemIds); Map sysSalaryItemMap = SalaryEntityUtil.convert2Map(sysSalaryItems, SysSalaryItemPO::getId); // 根据系统薪资项目id查询当前租户的自定义薪资项目 // 如果默认的账套薪资项目查询关联的系统薪资项目id没有生成自定义薪资项目,需要自动生成对应的自定义薪资项目 List needInsertSalaryItems = new ArrayList<>(); List salaryItems = getSalaryItemService(user).listBySysSalaryItemIds(sysSalaryItemIds); // key:系统薪资项目id;value:薪资项目po Map salaryItemMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getSysSalaryItemId); for (SysSalaryItemPO sysSalaryItem : sysSalaryItems) { salaryItemMap.computeIfAbsent(sysSalaryItem.getId(), key -> { SalaryItemPO salaryItem = SysSalaryItemBO.convert2SalaryItemPO(sysSalaryItem, now, (long) env.getCurrentUser().getUID()); needInsertSalaryItems.add(salaryItem); return salaryItem; }); } // key:默认的账套薪资项目分组id;value:账套薪资项目分组po Map salarySobItemGroupMap = Maps.newHashMapWithExpectedSize(salarySobDefaultItemGroups.size()); // 遍历默认的账套薪资项目分组,生成账套薪资项目分组po for (SalarySobDefaultItemGroupPO salarySobDefaultItemGroup : salarySobDefaultItemGroups) { SalarySobItemGroupPO salarySobItemGroup = SalarySobItemGroupPO.builder() .id(IdGenerator.generate()) .name(salarySobDefaultItemGroup.getName()) .salarySobId(env.getSalarySob().getId()) .sortedIndex(salarySobDefaultItemGroup.getSortedIndex()) .description(salarySobDefaultItemGroup.getDescription()) // .incomeCategory(salarySobDefaultItemGroup.getIncomeCategory().toString()) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .creator((long) env.getCurrentUser().getUID()) .deleteType(DeleteTypeEnum.NOT_DELETED.getValue()) .createTime(now) .updateTime(now) .build(); salarySobItemGroupMap.put(salarySobDefaultItemGroup.getId(), salarySobItemGroup); } List salarySobItems = new ArrayList<>(salarySobDefaultItems.size()); // 遍历默认的账套薪资项目,生成账套薪资项目po for (SalarySobDefaultItemPO salarySobDefaultItem : salarySobDefaultItems) { // 账套薪资项目分组 SalarySobItemGroupPO salarySobItemGroup = salarySobItemGroupMap.get(salarySobDefaultItem.getSobDefaultItemGroupId()); // 关联的薪资项目、系统薪资项目 SalaryItemPO salaryItem = salaryItemMap.get(salarySobDefaultItem.getSysSalaryItemId()); SysSalaryItemPO sysSalaryItem = sysSalaryItemMap.get(salarySobDefaultItem.getSysSalaryItemId()); if (salaryItem == null || sysSalaryItem == null) { throw new SalaryRunTimeException("Invalid arguments,salaryItem can not be null"); } SalarySobItemPO salarySobItem = SalarySobItemPO.builder() // .id(IdGenerator.generate()) .salarySobId(env.getSalarySob().getId()) .incomeCategory(salarySobDefaultItem.getIncomeCategory().toString()) .salaryItemId(salaryItem.getId()) .salaryItemCode(salaryItem.getCode()) .salarySobItemGroupId(Optional.ofNullable(salarySobItemGroup).map(SalarySobItemGroupPO::getId).orElse(0L)) // .useInEmployeeSalary(0) // .dataType(salaryItem.getDataType()) // .roundingMode(sysSalaryItem.getRoundingMode()) // .pattern(sysSalaryItem.getPattern()) // .valueType(sysSalaryItem.getValueType()) .formulaId(sysSalaryItem.getFormulaId()) // .hideSwitch(0) // .sumSwitch(0) // .readonlySwitch(0) .sortedIndex(salarySobDefaultItem.getSortedIndex()) .description(salaryItem.getDescription()) // .canEdit(1) .canDelete(1) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .creator((long) env.getCurrentUser().getUID()) .deleteType(DeleteTypeEnum.NOT_DELETED.getValue()) .createTime(now) .updateTime(now) .build(); salarySobItems.add(salarySobItem); } if (CollectionUtils.isNotEmpty(needInsertSalaryItems)) { getSalaryItemService(user).batchSave(needInsertSalaryItems); } if (MapUtils.isNotEmpty(salarySobItemGroupMap)) { getSalarySobItemGroupService(user).batchSave(salarySobItemGroupMap.values()); } if (CollectionUtils.isNotEmpty(salarySobItems)) { getSalarySobItemService(user).batchSave(salarySobItems); } env.setSalarySobItems(salarySobItems); } @Override protected void initBackItem(SalarySobInitEnv env) { // 只有「正常工资薪金」才默认生成回算薪资项目 boolean contains = Objects.equals(env.getSaveParam().getTaxableItems(), IncomeCategoryEnum.WAGES_AND_SALARIES.getValue()); if (!contains) { return; } // 746777981115629575L--已发薪资合计 // 746777981115629576L--补发薪资合计 List sysSalaryItemIds = Lists.newArrayList(746777981115629575L, 746777981115629576L); List sysSalaryItems = getSysSalaryItemService(user).listByIds(sysSalaryItemIds); // 根据系统薪资项目id查询当前租户的自定义薪资项目 // 如果默认的账套薪资项目查询关联的系统薪资项目id没有生成自定义薪资项目,需要自动生成对应的自定义薪资项目 List salaryItems = getSalaryItemService(user).listBySysSalaryItemIds(sysSalaryItemIds); Map salaryItemMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getSysSalaryItemId); Date now = new Date(); List needInsertSalaryItems = new ArrayList<>(); List salarySobBackItems = new ArrayList<>(); for (SysSalaryItemPO sysSalaryItem : sysSalaryItems) { SalaryItemPO salaryItem = salaryItemMap.computeIfAbsent(sysSalaryItem.getId(), key -> { SalaryItemPO temp = SysSalaryItemBO.convert2SalaryItemPO(sysSalaryItem, now, (long) env.getCurrentUser().getUID()); needInsertSalaryItems.add(temp); return temp; }); SalarySobBackItemPO salarySobBackItem = SalarySobBackItemPO.builder() .id(IdGenerator.generate()) .salarySobId(env.getSalarySob().getId()) // .incomeCategory(IncomeCategoryEnum.WAGES_AND_SALARIES.getValue().toString()) .salaryItemId(salaryItem.getId()) .salaryItemCode(salaryItem.getCode()) .dataType(salaryItem.getDataType()) .roundingMode(sysSalaryItem.getRoundingMode()) .pattern(sysSalaryItem.getPattern()) .valueType(sysSalaryItem.getValueType()) .formulaId(sysSalaryItem.getFormulaId()) // .hideSwitch(0) // .sumSwitch(0) // .readonlySwitch(0) // .sortedIndex(0) .backCalcType(Objects.equals(sysSalaryItem.getId(), 746777981115629575L) ? 0 : 1) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) // .breator((long) env.getCurrentUser().getUID()) .deleteType(DeleteTypeEnum.NOT_DELETED.getValue()) .createTime(now) .updateTime(now) .build(); salarySobBackItems.add(salarySobBackItem); } if (CollectionUtils.isNotEmpty(needInsertSalaryItems)) { getSalaryItemService(user).batchSave(needInsertSalaryItems); } if (CollectionUtils.isNotEmpty(salarySobBackItems)) { getSalarySobBackItemService(user).batchInsert(salarySobBackItems); } } @Override protected void initAddUpRule(SalarySobInitEnv env) { // 只有「正常工资薪金」才默认生成累计字段对应规则 boolean contains = Objects.equals(env.getSaveParam().getTaxableItems(), IncomeCategoryEnum.WAGES_AND_SALARIES.getValue()); if (!contains) { return; } Date now = new Date(); List salarySobAddUpRules = new ArrayList<>(); // 账套薪资项目 List salarySobItems = env.getSalarySobItems().stream() .filter(e -> Objects.equals(e.getIncomeCategory(), IncomeCategoryEnum.WAGES_AND_SALARIES.getValue().toString())) .collect(Collectors.toList()); // AddUpSituationPO.class带有SalaryFormulaVar.class注解字段的name和账套薪资项目的code都是对应的,除了「addUpAdvanceTax」 // 遍历AddUpSituationPO.class的SalaryFormulaVar.class注解,生成累计字段对应规则po Map salarySobItemMap = SalaryEntityUtil.convert2Map(salarySobItems, SalarySobItemPO::getSalaryItemCode); for (Field declaredField : AddUpSituation.class.getDeclaredFields()) { SalarySobItemPO salarySobItem = salarySobItemMap.get(declaredField.getName()); if (Objects.equals(declaredField.getName(), "addUpAdvanceTax")) { salarySobItem = salarySobItemMap.get("addUpTaxPayable"); } if (!declaredField.isAnnotationPresent(SalaryFormulaVar.class) || Objects.isNull(salarySobItem)) { continue; } SalarySobAddUpRulePO salarySobAddUpRule = new SalarySobAddUpRulePO() .setId(IdGenerator.generate()) .setSalarySobId(env.getSalarySob().getId()) .setIncomeCategory(IncomeCategoryEnum.WAGES_AND_SALARIES.getValue().toString()) .setSalaryItemId(salarySobItem.getSalaryItemId()) .setAddUpColumnDataIndex(declaredField.getName()) .setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .setCreator((long) env.getCurrentUser().getUID()) .setDeleteType(DeleteTypeEnum.NOT_DELETED.getValue()) .setCreateTime(now) .setUpdateTime(now); salarySobAddUpRules.add(salarySobAddUpRule); } if (CollectionUtils.isNotEmpty(salarySobAddUpRules)) { getSalarySobAddUpRuleService(user).saveBatch(salarySobAddUpRules); } } @Override protected void initTaxReportRule(SalarySobInitEnv env) { // 查询个税申报表的表头 List taxReportColumns = new ArrayList<>(getTaxReportColumnService(user).listByIncomeCategory(IncomeCategoryEnum.parseByValue(env.getSaveParam().getTaxableItems()))); Date now = new Date(); // 个税申报表表头的reportColumnDataIndex和账套薪资项目的code都是对应的 // 遍历个税申报表的表头,生成个税申报表字段对应规则po List salarySobTaxReportRules = Lists.newArrayList(); Map salarySobItemMap = SalaryEntityUtil.convert2Map(env.getSalarySobItems(), e -> e.getIncomeCategory() + "-" + e.getSalaryItemCode()); for (TaxReportColumnPO taxReportColumn : taxReportColumns) { SalarySobItemPO salarySobItem = salarySobItemMap.get(taxReportColumn.getIncomeCategory() + "-" + taxReportColumn.getReportColumnDataIndex()); if (Objects.nonNull(salarySobItem)) { SalarySobTaxReportRulePO salarySobTaxReportRule = new SalarySobTaxReportRulePO() .setId(IdGenerator.generate()) .setSalarySobId(env.getSalarySob().getId()) .setIncomeCategory(salarySobItem.getIncomeCategory()) .setReportColumnDataIndex(taxReportColumn.getReportColumnDataIndex()) .setSalaryItemId(salarySobItem.getSalaryItemId()) .setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .setCreator((long) env.getCurrentUser().getUID()) .setDeleteType(DeleteTypeEnum.NOT_DELETED.getValue()) .setCreateTime(now) .setUpdateTime(now); salarySobTaxReportRules.add(salarySobTaxReportRule); } } if (CollectionUtils.isNotEmpty(salarySobTaxReportRules)) { getSalarySobTaxReportRuleService(user).saveBatch(salarySobTaxReportRules); } } }