| | |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateSalaryCalculation(HrmSalaryCalculationDO calculation) { |
| | | HrmSalaryCalculationDO exist = salaryCalculationMapper.selectById(calculation.getId()); |
| | | if (exist == null) { |
| | | throw exception(SALARY_CALCULATION_NOT_EXISTS); |
| | | } |
| | | // 仅待确认状态可修改:已确认需先撤销;已发放不可改 |
| | | if (exist.getStatus() == null || !Objects.equals(exist.getStatus(), 0)) { |
| | | throw exception(SALARY_CALCULATION_UPDATE_FAIL); |
| | | } |
| | | // 以下字段不允许通过修改接口变更,一律以库中为准 |
| | | calculation.setNo(exist.getNo()); |
| | | calculation.setPeriod(exist.getPeriod()); |
| | | calculation.setUserId(exist.getUserId()); |
| | | calculation.setDeptId(exist.getDeptId()); |
| | | calculation.setStatus(exist.getStatus()); |
| | | calculation.setConfirmTime(exist.getConfirmTime()); |
| | | calculation.setConfirmUserId(exist.getConfirmUserId()); |
| | | calculation.setPaymentTime(exist.getPaymentTime()); |
| | | // 金额字段为 null 时统一按 0 处理:MyBatis-Plus 的 updateById 默认忽略 null, |
| | | // 否则会出现「实发工资按 0 计算、但明细仍保留旧值」的不一致 |
| | | calculation.setBaseSalary(nvl(calculation.getBaseSalary())); |
| | | calculation.setPerformanceSalary(nvl(calculation.getPerformanceSalary())); |
| | | calculation.setOvertimePay(nvl(calculation.getOvertimePay())); |
| | | calculation.setMealAllowance(nvl(calculation.getMealAllowance())); |
| | | calculation.setTransportAllowance(nvl(calculation.getTransportAllowance())); |
| | | calculation.setOtherAllowance(nvl(calculation.getOtherAllowance())); |
| | | calculation.setSocialSecurityDeduction(nvl(calculation.getSocialSecurityDeduction())); |
| | | calculation.setHousingFundDeduction(nvl(calculation.getHousingFundDeduction())); |
| | | calculation.setTaxDeduction(nvl(calculation.getTaxDeduction())); |
| | | calculation.setOtherDeduction(nvl(calculation.getOtherDeduction())); |
| | | calculation.setLeaveDeduction(nvl(calculation.getLeaveDeduction())); |
| | | // 实发工资由后端重算,避免前端传入值与明细不一致 |
| | | calculation.setActualSalary(calcActualSalary(calculation)); |
| | | salaryCalculationMapper.updateById(calculation); |
| | | } |
| | | |
| | | /** |
| | | * 计算实发工资 = 收入项合计 - 扣除项合计,保留两位小数 |
| | | */ |
| | | private static BigDecimal calcActualSalary(HrmSalaryCalculationDO c) { |
| | | BigDecimal income = nvl(c.getBaseSalary()) |
| | | .add(nvl(c.getPerformanceSalary())) |
| | | .add(nvl(c.getOvertimePay())) |
| | | .add(nvl(c.getMealAllowance())) |
| | | .add(nvl(c.getTransportAllowance())) |
| | | .add(nvl(c.getOtherAllowance())); |
| | | BigDecimal deduction = nvl(c.getSocialSecurityDeduction()) |
| | | .add(nvl(c.getHousingFundDeduction())) |
| | | .add(nvl(c.getTaxDeduction())) |
| | | .add(nvl(c.getOtherDeduction())) |
| | | .add(nvl(c.getLeaveDeduction())); |
| | | return income.subtract(deduction).setScale(2, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | private static BigDecimal nvl(BigDecimal v) { |
| | | return v == null ? BigDecimal.ZERO : v; |
| | | } |
| | | |
| | | /** |
| | | * 内部生成发放台账方法(供自动生成调用) |
| | | */ |