yudao-module-hrm-api/src/main/java/cn/iocoder/yudao/module/hrm/enums/ErrorCodeConstants.java
@@ -128,6 +128,7 @@ ErrorCode CONTRACT_TEMPLATE_TYPE_NOT_SUPPORT = new ErrorCode(1_030_005_029, "不支持的合同模板类型"); ErrorCode CONTRACT_TEMPLATE_LOAD_FAILED = new ErrorCode(1_030_005_030, "合同模板加载失败"); ErrorCode EMPLOYEE_REGULARIZE_NEED_LABOR_CONTRACT = new ErrorCode(1_030_005_031, "该员工当前合同不是劳动合同,无法转正"); ErrorCode SALARY_CALCULATION_UPDATE_FAIL = new ErrorCode(1_030_005_032, "修改失败,原因:仅待确认状态可修改,请先撤销确认"); // ========== 班次管理 1-030-009-000 ========== ErrorCode SHIFT_NOT_EXISTS = new ErrorCode(1_030_009_000, "班次不存在"); yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/salary/HrmSalaryCalculationController.java
@@ -215,4 +215,13 @@ return success(true); } @PutMapping("/update") @Operation(summary = "修改薪酬核算记录", description = "仅待确认状态可修改;实发工资由后端按收入/扣除项重算") @PreAuthorize("@ss.hasPermission('hrm:salary:calculate')") public CommonResult<Boolean> updateSalaryCalculation(@Valid @RequestBody HrmSalaryCalculationRespVO updateReqVO) { HrmSalaryCalculationDO calculation = BeanUtils.toBean(updateReqVO, HrmSalaryCalculationDO.class); salaryCalculationService.updateSalaryCalculation(calculation); return success(true); } } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationService.java
@@ -81,4 +81,11 @@ */ void saveSalaryCalculationList(List<HrmSalaryCalculationDO> calculationList); /** * 修改单条薪酬核算记录(仅待确认状态可修改,实发工资由后端重算) * * @param calculation 核算记录 */ void updateSalaryCalculation(HrmSalaryCalculationDO calculation); } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java
@@ -663,6 +663,53 @@ } } @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()); // 实发工资由后端重算,避免前端传入值与明细不一致 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; } /** * 内部生成发放台账方法(供自动生成调用) */