From f81b963f9d1b7d4757446970830cb72264c6dc0c Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 04 十一月 2026 15:18:57 +0800
Subject: [PATCH] 九鸿:工资表按客户口径重构 + 修复考勤汇总生成、新增节假日报错
---
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java | 218 +++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 191 insertions(+), 27 deletions(-)
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java
index c2b563e..edc86ab 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java
@@ -6,6 +6,7 @@
import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmSalaryCalculationPageReqVO;
import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmLeaveApplicationDO;
import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmOvertimeApplicationDO;
+import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceRecordDO;
import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmEmployeeScheduleDO;
import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmShiftDO;
import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
@@ -21,6 +22,7 @@
import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmEmployeeScheduleMapper;
import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmShiftMapper;
import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmOvertimeApplicationMapper;
+import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmAttendanceRecordMapper;
import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper;
import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmEmployeeSalaryMapper;
import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmEmployeeSocialSecurityMapper;
@@ -32,6 +34,7 @@
import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmSalaryStructureMapper;
import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
+import cn.iocoder.yudao.module.hrm.enums.HrmAttendanceClockTypeEnum;
import cn.iocoder.yudao.module.hrm.enums.HrmOvertimeTypeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -110,6 +113,8 @@
private HrmEmployeeScheduleMapper employeeScheduleMapper;
@Resource
private HrmShiftMapper shiftMapper;
+ @Resource
+ private HrmAttendanceRecordMapper attendanceRecordMapper;
@Override
public PageResult<HrmSalaryCalculationDO> getSalaryCalculationPage(HrmSalaryCalculationPageReqVO pageReqVO) {
@@ -235,17 +240,65 @@
BigDecimal mealAllowance = employeeSalary.getMealAllowance() != null ? employeeSalary.getMealAllowance() : BigDecimal.ZERO;
BigDecimal transportAllowance = employeeSalary.getTransportAllowance() != null ? employeeSalary.getTransportAllowance() : BigDecimal.ZERO;
BigDecimal otherAllowance = employeeSalary.getOtherAllowance() != null ? employeeSalary.getOtherAllowance() : BigDecimal.ZERO;
- OvertimeSalary overtimeSalary = calculateOvertimeSalary(employee, employeeSalary, period, baseSalary);
- BigDecimal overtimePay = overtimeSalary.pay();
- // 鎸夋帓鐝疮璁″嚭鍕ゅぉ鏁颁笌鎺掔彮鎬诲伐鏃讹紙鏃犳帓鐝椂鍑哄嫟澶╂暟鍥為��榛樿 22锛�
+ // ========== 涔濇硴宸ヨ祫琛細鏍囧噯椤瑰彇鑷憳宸ユ。妗� ==========
+ BigDecimal standardSalary = nvl(employee.getStandardSalary());
+ BigDecimal postSalary = nvl(employee.getPostSalary());
+ BigDecimal overtimeHourlyRate = employee.getOvertimeHourlyRate();
+ BigDecimal safetyAwardStandard = nvl(employee.getSafetyAwardStandard());
+ BigDecimal performanceStandard = nvl(employee.getPerformanceStandard());
+ // 鏍囧噯宸ヨ祫鏈崟鐙淮鎶ゆ椂锛屾寜銆屽熀鏈伐璧� + 宀椾綅宸ヨ祫銆嶅悎鎴�
+ if (standardSalary.signum() == 0 && (baseSalary.signum() > 0 || postSalary.signum() > 0)) {
+ standardSalary = baseSalary.add(postSalary);
+ }
+
+ // 鎸夋帓鐝疮璁″簲鍑哄嫟澶╂暟涓庢爣鍑嗗伐鏃讹紙鏃犳帓鐝椂鍥為�� 22 澶� 脳 8 灏忔椂锛�
ScheduleStat scheduleStat = calculateScheduleStat(employeeId, period);
Integer workDays = scheduleStat.scheduledDays() > 0 ? scheduleStat.scheduledDays() : 22;
BigDecimal totalWorkHours = scheduleStat.totalWorkHours();
+ BigDecimal standardWorkHours = scheduleStat.scheduledDays() > 0
+ ? scheduleStat.totalWorkHours()
+ : BigDecimal.valueOf(workDays).multiply(BigDecimal.valueOf(8));
- // 搴斿彂宸ヨ祫鎬婚
- BigDecimal totalIncome = baseSalary.add(performanceSalary).add(mealAllowance)
- .add(transportAllowance).add(otherAllowance).add(overtimePay);
+ // 璁¤柂鍑哄嫟 = 鏍囧噯鍑哄嫟澶╂暟 - 缂哄嫟澶╂暟锛堣�冨嫟璁板綍涓己鍗$殑澶╂暟锛屾寜澶╁幓閲嶏級
+ int absentDays = countAbsentDays(employeeId, period);
+ BigDecimal paidAttendanceDays = BigDecimal.valueOf(Math.max(workDays - absentDays, 0));
+
+ // 鍔犵彮宸ヨ祫 / 娉曞畾鍋囧伐璧勶紙鍔犵彮宸ヨ祫鏍囧噯涓虹┖鏃跺洖閫�鍒� 鍩烘湰宸ヨ祫 / 21.75 / 8 脳 鍊嶇巼锛�
+ OvertimeSalary overtimeSalary = calculateOvertimeSalary(employee, employeeSalary, period, baseSalary, overtimeHourlyRate);
+ BigDecimal overtimeHours = overtimeSalary.hours();
+ BigDecimal overtimePay = overtimeSalary.pay();
+ BigDecimal legalHolidayHours = overtimeSalary.legalHolidayHours();
+ BigDecimal legalHolidayPay = overtimeSalary.legalHolidayPay();
+
+ // 鍑哄嫟鎶樼畻姣斾緥锛岀敤浜庢寜瀹為檯璁¤柂鍑哄嫟鎶樼畻鏍囧噯椤�
+ BigDecimal attendanceRatio = workDays > 0
+ ? paidAttendanceDays.divide(BigDecimal.valueOf(workDays), 6, RoundingMode.HALF_UP)
+ : BigDecimal.ZERO;
+ BigDecimal standardAttendancePay = standardSalary.multiply(attendanceRatio).setScale(2, RoundingMode.HALF_UP);
+ BigDecimal safetyAward = safetyAwardStandard.multiply(attendanceRatio).setScale(2, RoundingMode.HALF_UP);
+ BigDecimal floatingPerformancePay = performanceStandard.multiply(attendanceRatio).setScale(2, RoundingMode.HALF_UP);
+
+ // 搴斾粯宸ヨ祫 = 鏍囧噯鍑哄嫟宸ヨ祫 + 鍔犵彮宸ヨ祫 + 娉曞畾鍋囧伐璧� + 瀹夊叏鐜繚濂� + 娴姩缁╂晥宸ヨ祫
+ BigDecimal payableSalary = standardAttendancePay.add(overtimePay).add(legalHolidayPay)
+ .add(safetyAward).add(floatingPerformancePay);
+
+ // 鍔犻」锛堝伐榫勫伐璧�/澶滅彮琛ュ姪/瀛﹀巻琛ヨ创/浣撴/浼樼鍛樺伐濂�/鍏朵粬琛ュ姪/閮ㄩ棬缁╂晥锛変笌鎵i」
+ // 锛堟紡鎵撳崱/杩熷埌鏃╅��/鍏朵粬鎵f锛夌敓鎴愭椂榛樿涓� 0锛屾牳绠楅〉鍙墜宸ヨ皟鏁村悗淇濆瓨
+ BigDecimal seniorityPay = BigDecimal.ZERO;
+ BigDecimal nightShiftAllowance = BigDecimal.ZERO;
+ BigDecimal educationAllowance = BigDecimal.ZERO;
+ BigDecimal healthCheckAllowance = BigDecimal.ZERO;
+ BigDecimal excellentEmployeeAward = BigDecimal.ZERO;
+ BigDecimal otherSubsidy = BigDecimal.ZERO;
+ BigDecimal deptPerformance = BigDecimal.ZERO;
+ BigDecimal additionTotal = BigDecimal.ZERO;
+ BigDecimal missedPunchDeduction = BigDecimal.ZERO;
+ BigDecimal lateEarlyDeduction = BigDecimal.ZERO;
+ BigDecimal deductionTotal = BigDecimal.ZERO;
+
+ // 璁$◣鍙e緞锛氬簲浠樺伐璧� + 鍔犻」鍚堣 - 鎵f鍚堣
+ BigDecimal totalIncome = payableSalary.add(additionTotal).subtract(deductionTotal);
// 鑾峰彇绀句繚鍩烘暟锛氬憳宸ョぞ淇濇。妗� > 鏂规榛樿缂磋垂鍩烘暟 > 鍛樺伐鍩烘湰宸ヨ祫
BigDecimal socialSecurityBase = (socialSecurity != null && socialSecurity.getSocialSecurityBase() != null)
@@ -284,8 +337,8 @@
// 鍏Н閲戞墸闄� = 鍩烘暟 脳 鍏Н閲戜釜浜烘瘮渚�
BigDecimal housingFundDeduction = housingFundBase.multiply(housingFundPersonalRatio).setScale(2, RoundingMode.HALF_UP);
- // 璁$畻璇峰亣鎵f
- BigDecimal leaveDeduction = calculateLeaveDeduction(employee, period, baseSalary);
+ // 璇峰亣鎵f锛氭柊鐗堝伐璧勮〃鎸夈�岃钖嚭鍕ゃ�嶆姌鍑忔爣鍑嗗嚭鍕ゅ伐璧勶紝涓嶅啀鍗曠嫭閲嶅鎵d竴娆★紝淇濈暀瀛楁鍏煎鏃ф暟鎹�
+ BigDecimal leaveDeduction = BigDecimal.ZERO;
// 璁$畻涓◣鎵i櫎
// 搴旂撼绋庢墍寰楅 = 搴斿彂宸ヨ祫 - 绀句繚鎵i櫎 - 鍏Н閲戞墸闄� - 璧峰緛鐐�(5000)
@@ -301,15 +354,43 @@
BigDecimal otherDeduction = BigDecimal.ZERO;
- // 璁$畻瀹炲彂宸ヨ祫 = 搴斿彂 - 鎵i櫎
- BigDecimal totalDeduction = socialSecurityDeduction.add(housingFundDeduction)
- .add(taxDeduction).add(otherDeduction).add(leaveDeduction);
- BigDecimal actualSalary = totalIncome.subtract(totalDeduction);
+ // 绋庡悗宸ヨ祫 = 搴斾粯宸ヨ祫 + 鍔犻」鍚堣 - 鎵f鍚堣 - 绀句繚 - 鍏Н閲� - 涓◣
+ BigDecimal actualSalary = payableSalary.add(additionTotal).subtract(deductionTotal)
+ .subtract(socialSecurityDeduction).subtract(housingFundDeduction)
+ .subtract(taxDeduction);
return HrmSalaryCalculationDO.builder()
.period(period)
.userId(employeeId) // 浣跨敤鍛樺伐ID
.deptId(employee.getDeptId())
+ // 涔濇硴宸ヨ祫琛細鏍囧噯椤�
+ .standardSalary(standardSalary)
+ .postSalary(postSalary)
+ .overtimeHourlyRate(overtimeHourlyRate)
+ .safetyAwardStandard(safetyAwardStandard)
+ .performanceStandard(performanceStandard)
+ // 涔濇硴宸ヨ祫琛細鍑哄嫟涓庤钖�
+ .paidAttendanceDays(paidAttendanceDays)
+ .standardWorkHours(standardWorkHours)
+ .legalHolidayHours(legalHolidayHours)
+ .standardAttendancePay(standardAttendancePay)
+ .legalHolidayPay(legalHolidayPay)
+ .safetyAward(safetyAward)
+ .floatingPerformancePay(floatingPerformancePay)
+ .payableSalary(payableSalary)
+ // 涔濇硴宸ヨ祫琛細鍔犻」 / 鎵i」
+ .seniorityPay(seniorityPay)
+ .nightShiftAllowance(nightShiftAllowance)
+ .educationAllowance(educationAllowance)
+ .healthCheckAllowance(healthCheckAllowance)
+ .excellentEmployeeAward(excellentEmployeeAward)
+ .otherSubsidy(otherSubsidy)
+ .deptPerformance(deptPerformance)
+ .additionTotal(additionTotal)
+ .missedPunchDeduction(missedPunchDeduction)
+ .lateEarlyDeduction(lateEarlyDeduction)
+ .deductionTotal(deductionTotal)
+ // 鍏煎鏃у瓧娈�
.baseSalary(baseSalary)
.performanceSalary(performanceSalary)
.overtimePay(overtimePay)
@@ -323,7 +404,7 @@
.leaveDeduction(leaveDeduction)
.actualSalary(actualSalary)
.workDays(workDays) // 鎸夋帓鐝疮璁″簲鍑哄嫟澶╂暟锛屾棤鎺掔彮鏃跺洖閫� 22
- .overtimeHours(overtimeSalary.hours())
+ .overtimeHours(overtimeHours)
.totalWorkHours(totalWorkHours)
.status(0) // 寰呯‘璁�
.build();
@@ -406,19 +487,24 @@
}
/**
- * 姹囨�诲綋鏈堝鎵归�氳繃鐨勫姞鐝敵璇枫�傚皬鏃跺伐璧勬寜鍩烘湰宸ヨ祫 / 21.75 / 8 璁$畻锛�
- * 宸ヤ綔鏃ラ粯璁� 1.5 鍊嶃�佷紤鎭棩榛樿 2 鍊嶃�佹硶瀹氳妭鍋囨棩榛樿 3 鍊嶏紝鍧囧彲鐢辫柂閰粨鏋勮鐩栥��
+ * 姹囨�诲綋鏈堝鎵归�氳繃鐨勫姞鐝敵璇枫��
+ *
+ * 鍛樺伐妗f缁存姢浜嗐�屽姞鐝伐璧勬爣鍑嗭紙鍏�/灏忔椂锛夈�嶆椂锛氬姞鐝伐璧� = 鍔犵彮鏃堕暱 脳 鍗曚环锛�
+ * 娉曞畾鍋囧伐璧� = 娉曞畾鍋囨棩鏃堕暱 脳 鍗曚环 脳 娉曞畾鑺傚亣鏃ュ�嶇巼锛堥粯璁� 3锛夈��
+ * 鏈淮鎶ゅ崟浠锋椂鍥為��鏃у彛寰勶細鍩烘湰宸ヨ祫 / 21.75 / 8 脳 鍚勭被鍨嬪�嶇巼銆�
+ *
+ * 娉曞畾鑺傚亣鏃ュ姞鐝崟鐙粺璁★紝涓嶈鍏ャ�屽姞鐝椂闀裤�嶅垪锛岄伩鍏嶄笌銆屾硶瀹氬亣宸ヨ祫銆嶉噸澶嶈钖��
*/
private OvertimeSalary calculateOvertimeSalary(HrmEmployeeDO employee, HrmEmployeeSalaryDO employeeSalary,
- String period, BigDecimal baseSalary) {
+ String period, BigDecimal baseSalary, BigDecimal overtimeHourlyRate) {
if (employee.getUserId() == null) {
- return new OvertimeSalary(BigDecimal.ZERO, BigDecimal.ZERO);
+ return OvertimeSalary.EMPTY;
}
YearMonth month = YearMonth.parse(period);
List<HrmOvertimeApplicationDO> applications = overtimeApplicationMapper.selectApprovedByUserAndDateRange(
employee.getUserId(), month.atDay(1), month.atEndOfMonth());
if (CollUtil.isEmpty(applications)) {
- return new OvertimeSalary(BigDecimal.ZERO, BigDecimal.ZERO);
+ return OvertimeSalary.EMPTY;
}
Long structureId = employeeSalary.getSalaryStructureId() != null
? employeeSalary.getSalaryStructureId() : employee.getSalaryStructureId();
@@ -429,29 +515,62 @@
? structure.getRestDayOvertimePayRatio() : HrmOvertimeTypeEnum.REST_DAY.getSalaryMultiplier();
BigDecimal legalHolidayMultiplier = structure != null && structure.getLegalHolidayOvertimePayRatio() != null
? structure.getLegalHolidayOvertimePayRatio() : HrmOvertimeTypeEnum.LEGAL_HOLIDAY.getSalaryMultiplier();
- BigDecimal hourlySalary = baseSalary.divide(new BigDecimal("21.75"), 8, RoundingMode.HALF_UP)
- .divide(new BigDecimal("8"), 8, RoundingMode.HALF_UP);
+ BigDecimal hourlySalary = overtimeHourlyRate != null && overtimeHourlyRate.signum() > 0
+ ? overtimeHourlyRate
+ : baseSalary.divide(new BigDecimal("21.75"), 8, RoundingMode.HALF_UP)
+ .divide(new BigDecimal("8"), 8, RoundingMode.HALF_UP);
BigDecimal totalHours = BigDecimal.ZERO;
BigDecimal totalPay = BigDecimal.ZERO;
+ BigDecimal legalHolidayHours = BigDecimal.ZERO;
+ BigDecimal legalHolidayPay = BigDecimal.ZERO;
for (HrmOvertimeApplicationDO application : applications) {
BigDecimal hours = application.getDuration() == null ? BigDecimal.ZERO : application.getDuration();
HrmOvertimeTypeEnum type = HrmOvertimeTypeEnum.valueOfType(application.getOvertimeType());
if (type == null || hours.signum() <= 0) {
continue;
}
- BigDecimal multiplier = switch (type) {
- case WORKDAY -> workdayMultiplier;
- case REST_DAY -> restDayMultiplier;
- case LEGAL_HOLIDAY -> legalHolidayMultiplier;
- };
+ if (type == HrmOvertimeTypeEnum.LEGAL_HOLIDAY) {
+ legalHolidayHours = legalHolidayHours.add(hours);
+ legalHolidayPay = legalHolidayPay.add(hourlySalary.multiply(hours).multiply(legalHolidayMultiplier));
+ continue;
+ }
+ BigDecimal multiplier = type == HrmOvertimeTypeEnum.WORKDAY ? workdayMultiplier : restDayMultiplier;
totalHours = totalHours.add(hours);
totalPay = totalPay.add(hourlySalary.multiply(hours).multiply(multiplier));
}
return new OvertimeSalary(totalHours.setScale(1, RoundingMode.HALF_UP),
- totalPay.setScale(2, RoundingMode.HALF_UP));
+ totalPay.setScale(2, RoundingMode.HALF_UP),
+ legalHolidayHours.setScale(1, RoundingMode.HALF_UP),
+ legalHolidayPay.setScale(2, RoundingMode.HALF_UP));
}
- private record OvertimeSalary(BigDecimal hours, BigDecimal pay) {}
+ /**
+ * 缁熻褰撴湀鑰冨嫟璁板綍涓己鍗$殑澶╂暟锛堝悓涓�鏃ユ湡澶氭缂哄崱鍙畻涓�澶╋級
+ */
+ private int countAbsentDays(Long employeeId, String period) {
+ YearMonth month = YearMonth.parse(period);
+ List<HrmAttendanceRecordDO> records = attendanceRecordMapper.selectListByUserIdAndDateBetween(
+ employeeId, month.atDay(1), month.atEndOfMonth());
+ if (CollUtil.isEmpty(records)) {
+ return 0;
+ }
+ return (int) records.stream()
+ .filter(record -> HrmAttendanceClockTypeEnum.MISSING.getType().equals(record.getClockInType())
+ || HrmAttendanceClockTypeEnum.MISSING.getType().equals(record.getClockOutType()))
+ .map(HrmAttendanceRecordDO::getDate)
+ .distinct()
+ .count();
+ }
+
+ private static BigDecimal nvl(BigDecimal value) {
+ return value == null ? BigDecimal.ZERO : value;
+ }
+
+ private record OvertimeSalary(BigDecimal hours, BigDecimal pay,
+ BigDecimal legalHolidayHours, BigDecimal legalHolidayPay) {
+ private static final OvertimeSalary EMPTY = new OvertimeSalary(
+ BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
+ }
private record ScheduleStat(int scheduledDays, BigDecimal totalWorkHours) {}
@@ -594,6 +713,7 @@
@Transactional(rollbackFor = Exception.class)
public void saveSalaryCalculationList(List<HrmSalaryCalculationDO> calculationList) {
for (HrmSalaryCalculationDO calculation : calculationList) {
+ normalizeSalaryTotals(calculation);
if (calculation.getId() == null) {
// 鏂板璁板綍锛岀敓鎴愭牳绠楀崟鍙�
String no = noRedisDAO.generateSalaryCalculationNo();
@@ -611,6 +731,50 @@
}
/**
+ * 淇濆瓨鍓嶆寜涔濇硴宸ヨ祫琛ㄥ彛寰勯噸绠楀悎璁★紝閬垮厤鍓嶇婕忕畻鎴栨棫瀹㈡埛绔紶鍏ヤ笉涓�鑷寸殑鍚堣鍊笺��
+ *
+ * 鍔犻」鍚堣 = 宸ラ緞宸ヨ祫 + 澶滅彮琛ュ姪 + 瀛﹀巻琛ヨ创 + 浣撴 + 浼樼鍛樺伐濂� + 鍏朵粬琛ュ姪 + 閮ㄩ棬缁╂晥
+ * 鎵f鍚堣 = 婕忔墦鍗� + 杩熷埌鏃╅�� + 鍏朵粬鎵f
+ * 绋庡悗宸ヨ祫 = 搴斾粯宸ヨ祫 + 鍔犻」鍚堣 - 鎵f鍚堣 - 绀句繚 - 鍏Н閲� - 涓◣
+ *
+ * 浠呭綋鏈璁板綍甯︽湁銆屽簲浠樺伐璧勩�嶆椂閲嶇畻锛涘彧鏈夋棫瀛楁鐨勮�佹暟鎹繚鎸佸師鏍凤紝閬垮厤鎶婃湭缁存姢鐨勬柊瀛楁娓呮垚 0銆�
+ */
+ private void normalizeSalaryTotals(HrmSalaryCalculationDO calculation) {
+ if (calculation.getPayableSalary() == null) {
+ return;
+ }
+ // 搴斾粯宸ヨ祫 = 鏍囧噯鍑哄嫟宸ヨ祫 + 鍔犵彮宸ヨ祫 + 娉曞畾鍋囧伐璧� + 瀹夊叏鐜繚濂� + 娴姩缁╂晥宸ヨ祫
+ // 浠呭綋鏈璁板綍甯︽柊鐗堟爣鍑嗛」鏃堕噸绠楋紝閬垮厤鏃ф暟鎹紙鏃犺繖浜涘垪锛夎娓呴浂
+ if (calculation.getStandardAttendancePay() != null) {
+ calculation.setPayableSalary(nvl(calculation.getStandardAttendancePay())
+ .add(nvl(calculation.getOvertimePay()))
+ .add(nvl(calculation.getLegalHolidayPay()))
+ .add(nvl(calculation.getSafetyAward()))
+ .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));
+ }
+
+ /**
* 鍐呴儴鐢熸垚鍙戞斁鍙拌处鏂规硶锛堜緵鑷姩鐢熸垚璋冪敤锛�
*/
private void generatePaymentInternal(String period, List<HrmSalaryCalculationDO> calculationList) {
--
Gitblit v1.9.3