| | |
| | | } |
| | | |
| | | /** |
| | | * 保存前按九泓工资表口径重算合计,避免前端漏算或旧客户端传入不一致的合计值。 |
| | | * 保存前补齐合计字段。 |
| | | * |
| | | * 加项合计 = 工龄工资 + 夜班补助 + 学历补贴 + 体检 + 优秀员工奖 + 其他补助 + 部门绩效 |
| | | * 扣款合计 = 漏打卡 + 迟到早退 + 其他扣款 |
| | | * 税后工资 = 应付工资 + 加项合计 - 扣款合计 - 社保 - 公积金 - 个税 |
| | | * |
| | | * 仅当本次记录带有「应付工资」时重算;只有旧字段的老数据保持原样,避免把未维护的新字段清成 0。 |
| | | * 工资表的每个数值字段都允许在自动计算后手工调整,因此这里**只补空值、不覆盖提交值**: |
| | | * 前端预览页已经按同口径重算好应付工资/加项合计/扣款合计/税后工资并一起提交, |
| | | * 直接落库才能保住用户手工改过的数;只有字段为空(旧客户端、接口直调)时才按口径补算。 |
| | | */ |
| | | private void normalizeSalaryTotals(HrmSalaryCalculationDO calculation) { |
| | | if (calculation.getPayableSalary() == null) { |
| | | return; |
| | | } |
| | | // 应付工资 = 标准出勤工资 + 加班工资 + 法定假工资 + 安全环保奖 + 浮动绩效工资 |
| | | // 仅当本次记录带新版标准项时重算,避免旧数据(无这些列)被清零 |
| | | if (calculation.getStandardAttendancePay() != null) { |
| | | if (calculation.getPayableSalary() == null && calculation.getStandardAttendancePay() != null) { |
| | | calculation.setPayableSalary(nvl(calculation.getStandardAttendancePay()) |
| | | .add(nvl(calculation.getOvertimePay())) |
| | | .add(nvl(calculation.getLegalHolidayPay())) |
| | |
| | | .add(nvl(calculation.getFloatingPerformancePay())) |
| | | .setScale(2, RoundingMode.HALF_UP)); |
| | | } |
| | | BigDecimal additionTotal = nvl(calculation.getSeniorityPay()) |
| | | .add(nvl(calculation.getNightShiftAllowance())) |
| | | .add(nvl(calculation.getEducationAllowance())) |
| | | .add(nvl(calculation.getHealthCheckAllowance())) |
| | | .add(nvl(calculation.getExcellentEmployeeAward())) |
| | | .add(nvl(calculation.getOtherSubsidy())) |
| | | .add(nvl(calculation.getDeptPerformance())); |
| | | BigDecimal deductionTotal = nvl(calculation.getMissedPunchDeduction()) |
| | | .add(nvl(calculation.getLateEarlyDeduction())) |
| | | .add(nvl(calculation.getOtherDeduction())); |
| | | calculation.setAdditionTotal(additionTotal.setScale(2, RoundingMode.HALF_UP)); |
| | | calculation.setDeductionTotal(deductionTotal.setScale(2, RoundingMode.HALF_UP)); |
| | | calculation.setActualSalary(calculation.getPayableSalary() |
| | | .add(calculation.getAdditionTotal()) |
| | | .subtract(calculation.getDeductionTotal()) |
| | | .subtract(nvl(calculation.getSocialSecurityDeduction())) |
| | | .subtract(nvl(calculation.getHousingFundDeduction())) |
| | | .subtract(nvl(calculation.getTaxDeduction())) |
| | | .setScale(2, RoundingMode.HALF_UP)); |
| | | if (calculation.getAdditionTotal() == null) { |
| | | BigDecimal additionTotal = nvl(calculation.getSeniorityPay()) |
| | | .add(nvl(calculation.getNightShiftAllowance())) |
| | | .add(nvl(calculation.getEducationAllowance())) |
| | | .add(nvl(calculation.getHealthCheckAllowance())) |
| | | .add(nvl(calculation.getExcellentEmployeeAward())) |
| | | .add(nvl(calculation.getOtherSubsidy())) |
| | | .add(nvl(calculation.getDeptPerformance())); |
| | | calculation.setAdditionTotal(additionTotal.setScale(2, RoundingMode.HALF_UP)); |
| | | } |
| | | if (calculation.getDeductionTotal() == null) { |
| | | BigDecimal deductionTotal = nvl(calculation.getMissedPunchDeduction()) |
| | | .add(nvl(calculation.getLateEarlyDeduction())) |
| | | .add(nvl(calculation.getOtherDeduction())); |
| | | calculation.setDeductionTotal(deductionTotal.setScale(2, RoundingMode.HALF_UP)); |
| | | } |
| | | if (calculation.getActualSalary() == null && calculation.getPayableSalary() != null) { |
| | | calculation.setActualSalary(calculation.getPayableSalary() |
| | | .add(nvl(calculation.getAdditionTotal())) |
| | | .subtract(nvl(calculation.getDeductionTotal())) |
| | | .subtract(nvl(calculation.getSocialSecurityDeduction())) |
| | | .subtract(nvl(calculation.getHousingFundDeduction())) |
| | | .subtract(nvl(calculation.getTaxDeduction())) |
| | | .setScale(2, RoundingMode.HALF_UP)); |
| | | } |
| | | } |
| | | |
| | | /** |