易迪希二开,分段计薪

This commit is contained in:
钱涛 2025-10-21 16:54:16 +08:00
parent 9205c736ba
commit 3c22d5602d
2 changed files with 50 additions and 13 deletions

View File

@ -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<FormulaVarValue> 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<FormulaVarValue> handleSalaryArchiveItemVal(SalaryAcctCalculateBO salaryAcctCalculateBO,
private List<FormulaVarValue> handleSalaryArchiveItemVal(Long employeeId, SalaryAcctCalculateBO salaryAcctCalculateBO,
List<SalaryArchiveItemDataDTO> salaryArchiveItemDataList,
Map<Long, SalarySobAdjustRulePO> 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<SalaryArchiveItemDataDTO> 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:
// = 调薪前工资

View File

@ -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);
}
}