From 3c22d5602de261eb590e898c50eb9b0cf9ef6399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=92=B1=E6=B6=9B?= <15850646081@163.com> Date: Tue, 21 Oct 2025 16:54:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=98=93=E8=BF=AA=E5=B8=8C=E4=BA=8C=E5=BC=80?= =?UTF-8?q?=EF=BC=8C=E5=88=86=E6=AE=B5=E8=AE=A1=E8=96=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../salaryacct/bo/CalculateFormulaVarBO.java | 58 ++++++++++++++----- .../engine/salary/util/SalaryDateUtil.java | 5 ++ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/com/engine/salary/entity/salaryacct/bo/CalculateFormulaVarBO.java b/src/com/engine/salary/entity/salaryacct/bo/CalculateFormulaVarBO.java index cd66dd76c..c2b863aaa 100644 --- a/src/com/engine/salary/entity/salaryacct/bo/CalculateFormulaVarBO.java +++ b/src/com/engine/salary/entity/salaryacct/bo/CalculateFormulaVarBO.java @@ -1,6 +1,7 @@ package com.engine.salary.entity.salaryacct.bo; import cn.hutool.core.util.NumberUtil; +import com.api.customization.kq.service.PayRollDaysService; import com.engine.salary.annotation.SalaryFormulaVar; import com.engine.salary.common.LocalDateRange; import com.engine.salary.constant.SalaryFormulaFieldConstant; @@ -31,6 +32,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.Data; import lombok.experimental.Accessors; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import weaver.general.Util; @@ -38,7 +40,6 @@ import weaver.general.Util; import java.lang.reflect.Field; import java.math.BigDecimal; import java.math.RoundingMode; -import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; @@ -54,6 +55,7 @@ import static com.engine.salary.util.SalaryDateUtil.DATE_TIME_FORMATTER_PATTERN; **/ @Data @Accessors(chain = true) +@Slf4j public class CalculateFormulaVarBO { /** @@ -276,7 +278,7 @@ public class CalculateFormulaVarBO { String key = salaryArchiveDataDTO.getEmployeeId() + "_" + salaryArchiveTaxAgentDataDTO.getTaxAgentId(); List formulaVarValues = resultMap.computeIfAbsent(key, k -> Lists.newArrayList()); // 将薪资档案的值转换成公式中的变量,填充到返回结果集中 - formulaVarValues.addAll(handleSalaryArchiveItemVal(salaryAcctCalculateBO, salaryArchiveTaxAgentDataDTO.getSalaryItemValues(), salarySobAdjustRulePOMap)); + formulaVarValues.addAll(handleSalaryArchiveItemVal(salaryArchiveDataDTO.getEmployeeId(), salaryAcctCalculateBO, salaryArchiveTaxAgentDataDTO.getSalaryItemValues(), salarySobAdjustRulePOMap)); } } } @@ -310,7 +312,7 @@ public class CalculateFormulaVarBO { * @param salarySobAdjustRulePOMap * @return */ - private List handleSalaryArchiveItemVal(SalaryAcctCalculateBO salaryAcctCalculateBO, + private List handleSalaryArchiveItemVal(Long employeeId, SalaryAcctCalculateBO salaryAcctCalculateBO, List salaryArchiveItemDataList, Map salarySobAdjustRulePOMap) { // 薪资周期 @@ -331,18 +333,18 @@ public class CalculateFormulaVarBO { SalarySobAdjustRulePO salaryAdjustmentRulePO = salarySobAdjustRulePOMap.get(entry.getKey()); if (entry.getValue().size() > 2) { // 如果薪资项目在薪资周期内经历了多次调薪,则默认分段计薪 - value = calculateBySalarySobAdjustRule(salaryCycle, SalarySobAdjustRuleTypeEnum.PARTITION, entry.getValue()); + value = calculateBySalarySobAdjustRule(employeeId, salaryCycle, SalarySobAdjustRuleTypeEnum.PARTITION, entry.getValue()); } else if (salaryAdjustmentRulePO == null || entry.getValue().size() < 2) { // 如果薪资项目没有设置调薪计薪规则,默认取薪资周期内薪资档案中最新的值 // 如果薪资项目在薪资周期内没有调薪,默认取薪资周期内薪资档案中最新的值 - value = calculateBySalarySobAdjustRule(salaryCycle, SalarySobAdjustRuleTypeEnum.USE_AFTER_ADJUSTMENT, entry.getValue()); + value = calculateBySalarySobAdjustRule(employeeId, salaryCycle, SalarySobAdjustRuleTypeEnum.USE_AFTER_ADJUSTMENT, entry.getValue()); } else { // 如果薪资项目在薪资周期内只有一次调薪,则根据调薪计薪规则处理 SalarySobAdjustRuleTypeEnum adjustRuleTypeEnum = salaryAdjustmentRulePO.getDayOfMonth() < SalaryDateUtil.dateToLocalDate(entry.getValue().get(0).getEffectiveDateRange().getEndDate()).getDayOfMonth() ? SalarySobAdjustRuleTypeEnum.parseByValue(salaryAdjustmentRulePO.getAfterAdjustmentType()) : SalarySobAdjustRuleTypeEnum.parseByValue(salaryAdjustmentRulePO.getBeforeAdjustmentType()); // 根据调薪计薪规则处理薪资档案的调薪 - value = calculateBySalarySobAdjustRule(salaryCycle, adjustRuleTypeEnum, entry.getValue()); + value = calculateBySalarySobAdjustRule(employeeId, salaryCycle, adjustRuleTypeEnum, entry.getValue()); } String fieldId = SalaryFormulaReferenceEnum.SALARY_ARCHIVES.getValue() + SalaryFormulaFieldConstant.FIELD_ID_SEPARATOR @@ -359,7 +361,7 @@ public class CalculateFormulaVarBO { * @param salaryArchiveItemDataDTOS * @return */ - private String calculateBySalarySobAdjustRule(LocalDateRange salaryCycle, + private String calculateBySalarySobAdjustRule(Long employeeId, LocalDateRange salaryCycle, SalarySobAdjustRuleTypeEnum adjustRuleTypeEnum, List salaryArchiveItemDataDTOS) { if (Objects.isNull(adjustRuleTypeEnum)) { @@ -378,16 +380,46 @@ public class CalculateFormulaVarBO { // 可能存在多次调薪 // = (第一段的值*第一段的自然日+第二段的值*第二段的自然日+……)/薪资所属月自然日 BigDecimal valueSum = BigDecimal.ZERO; + log.info("分段计薪开始。。。共{}段", salaryArchiveItemDataDTOS.size()); + //获取当月计薪天数 + String fromDate = SalaryDateUtil.getFormatLocalDate(salaryCycle.getFromDate()); + String endDate = SalaryDateUtil.getFormatLocalDate(salaryCycle.getEndDate()); + int payRollDays = PayRollDaysService.getPayRollDays(employeeId.toString(), fromDate, endDate, true); + BigDecimal totalPayRollDays = new BigDecimal(payRollDays); + log.info("分段计薪,总计薪天数{},人员id:{},{}~{}", employeeId, totalPayRollDays, fromDate, endDate); for (int i = 0; i < salaryArchiveItemDataDTOS.size(); i++) { SalaryArchiveItemDataDTO dataDTO = salaryArchiveItemDataDTOS.get(i); - BigDecimal dayDiff = new BigDecimal(SalaryDateUtil.dateToLocalDate(dataDTO.getEffectiveDateRange().getFromDate()).until(SalaryDateUtil.dateToLocalDate(dataDTO.getEffectiveDateRange().getEndDate()), ChronoUnit.DAYS)); - // 最后一段日期范围需要加一 - if (Objects.equals(i, salaryArchiveItemDataDTOS.size() - 1)) { - dayDiff = dayDiff.add(BigDecimal.ONE); + BigDecimal effectDays; + BigDecimal segmentationData; + if (Objects.equals(i, 0)) { + // 第一段,结束日期-1 + String formatLocalDate = SalaryDateUtil.getFormatLocalDate(dataDTO.getEffectiveDateRange().getFromDate()); + String endLocalDate = SalaryDateUtil.getFormatLocalDate(SalaryDateUtil.plusDays(dataDTO.getEffectiveDateRange().getEndDate(), -1)); + effectDays = new BigDecimal(PayRollDaysService.getPayRollDays(employeeId.toString(), formatLocalDate, endLocalDate, true)); + BigDecimal dataValue = SalaryEntityUtil.empty2Zero(dataDTO.getValue()); + segmentationData = dataValue.multiply(effectDays).divide(totalPayRollDays, 2, RoundingMode.HALF_UP); + log.info("分段计薪第{}段,人员id:{},{}~{},档案薪资:{} * 计薪天数:{} / 总计薪天数{} = 分段结果:{}", i + 1, employeeId, formatLocalDate, endLocalDate, dataValue, effectDays, totalPayRollDays, segmentationData); + } else if (Objects.equals(i, salaryArchiveItemDataDTOS.size() - 1)) { + // 最后一段,起始日期+1 + String formatLocalDate = SalaryDateUtil.getFormatLocalDate(dataDTO.getEffectiveDateRange().getFromDate()); + String endLocalDate = SalaryDateUtil.getFormatLocalDate(dataDTO.getEffectiveDateRange().getEndDate()); + effectDays = new BigDecimal(PayRollDaysService.getPayRollDays(employeeId.toString(), formatLocalDate, endLocalDate, true)); + BigDecimal dataValue = SalaryEntityUtil.empty2Zero(dataDTO.getValue()); + segmentationData = dataValue.multiply(effectDays).divide(totalPayRollDays, 2, RoundingMode.HALF_UP); + log.info("分段计薪第{}段,人员id:{},{}~{},档案薪资:{} * 计薪天数:{} / 总计薪天数{} = 分段结果:{}", i + 1, employeeId, formatLocalDate, endLocalDate, dataValue, effectDays, totalPayRollDays, segmentationData); + } else { + //中间分段,结束日期-1 + String formatLocalDate = SalaryDateUtil.getFormatLocalDate(dataDTO.getEffectiveDateRange().getFromDate()); + String endLocalDate = SalaryDateUtil.getFormatLocalDate(SalaryDateUtil.plusDays(dataDTO.getEffectiveDateRange().getEndDate(), -1)); + effectDays = new BigDecimal(PayRollDaysService.getPayRollDays(employeeId.toString(), formatLocalDate, endLocalDate, true)); + BigDecimal dataValue = SalaryEntityUtil.empty2Zero(dataDTO.getValue()); + segmentationData = dataValue.multiply(effectDays).divide(totalPayRollDays, 2, RoundingMode.HALF_UP); + log.info("分段计薪第{}段,人员id:{},{}~{},档案薪资:{} * 计薪天数:{} / 总计薪天数{} = 分段结果:{}", i + 1, employeeId, formatLocalDate, endLocalDate, dataValue, effectDays, totalPayRollDays, segmentationData); } - valueSum = valueSum.add(SalaryEntityUtil.empty2Zero(dataDTO.getValue()).multiply(dayDiff)); + valueSum = valueSum.add(segmentationData); } - value = valueSum.divide(new BigDecimal(SalaryDateUtil.dateToLocalDate(salaryCycle.getFromDate()).until(SalaryDateUtil.dateToLocalDate(salaryCycle.getEndDate()), ChronoUnit.DAYS)).add(BigDecimal.ONE), 2, RoundingMode.HALF_UP).toPlainString(); + value = valueSum.toPlainString(); + log.info("分段计薪结束,人员id:{},{}~{},总计薪天数:{},分段结果:{}", employeeId, fromDate, endDate, totalPayRollDays, value); break; case USE_BEFORE_ADJUSTMENT: // = 调薪前工资 diff --git a/src/com/engine/salary/util/SalaryDateUtil.java b/src/com/engine/salary/util/SalaryDateUtil.java index 09983dd1f..500080226 100644 --- a/src/com/engine/salary/util/SalaryDateUtil.java +++ b/src/com/engine/salary/util/SalaryDateUtil.java @@ -604,6 +604,11 @@ public class SalaryDateUtil { LocalDate localDate = SalaryDateUtil.dateToLocalDate(date).plusMonths(i); return SalaryDateUtil.localDateToDate(localDate); } + + public static Date plusDays(Date date, int i) { + LocalDate localDate = SalaryDateUtil.dateToLocalDate(date).plusDays(i); + return SalaryDateUtil.localDateToDate(localDate); + } }