From ba100c651a81162a9a9a4533ff4d072f2889171a Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期五, 06 十一月 2026 09:38:46 +0800
Subject: [PATCH] fix(hrm): 考勤统计支持员工姓名搜索;缺卡统计补全(与考勤记录联动)
---
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java | 71 ++++++++++++++++++++++++-----------
1 files changed, 48 insertions(+), 23 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 faa80ef..aa54240 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
@@ -281,7 +281,7 @@
.add(fullAttendanceBonus)
.add(mealAllowance).add(transportAllowance).add(otherAllowance).add(overtimePay);
- // 鑾峰彇绀句繚鍩烘暟锛氬憳宸ョぞ淇濇。妗� > 鍛樺伐鍩烘湰宸ヨ祫
+ // 绀句繚鍩烘暟锛氬彧鍙栧憳宸ョぞ淇濇。妗堥噷閰嶇疆鐨勭即绾冲熀鏁帮紱鏈厤缃椂鐢ㄥ熀鏈伐璧�
BigDecimal socialSecurityBase = (socialSecurity != null && socialSecurity.getSocialSecurityBase() != null)
? socialSecurity.getSocialSecurityBase() : baseSalary;
@@ -292,17 +292,31 @@
? scheme.getMedicalPersonalRatio() : DEFAULT_MEDICAL_PERSONAL_RATIO;
BigDecimal unemploymentPersonalRatio = (scheme != null && scheme.getUnemploymentPersonalRatio() != null)
? scheme.getUnemploymentPersonalRatio() : DEFAULT_UNEMPLOYMENT_PERSONAL_RATIO;
+ // 澶х梾鍖荤枟 / 闀挎湡鎶ょ悊鐨勪釜浜烘瘮渚嬶細鏂规閲屽彲鑳戒负绌猴紝涓虹┖瑙嗕负 0锛堜笉鎵o級
+ BigDecimal seriousIllnessPersonalRatio = (scheme != null && scheme.getSeriousIllnessPersonalRatio() != null)
+ ? scheme.getSeriousIllnessPersonalRatio() : BigDecimal.ZERO;
+ BigDecimal longTermCarePersonalRatio = (scheme != null && scheme.getLongTermCarePersonalRatio() != null)
+ ? scheme.getLongTermCarePersonalRatio() : BigDecimal.ZERO;
// 鍏Н閲戜釜浜烘瘮渚嬶細鍙彇鏂规閰嶇疆鍊硷紝涓嶅啀鍥為��榛樿姣斾緥銆�
// 鍚﹀垯銆屽叕鍙告病閰嶅叕绉噾鏂规銆嶆椂浼氳鎸夐粯璁� 12% 鎵f锛堣繖灏辨槸瀹㈡埛鍙嶉鐨勯棶棰橈級銆�
BigDecimal housingFundPersonalRatio = scheme != null ? scheme.getHousingFundPersonalRatio() : null;
- // 绀句繚鎵i櫎 = 鍩烘暟 脳 (鍏昏�佷釜浜烘瘮渚� + 鍖荤枟涓汉姣斾緥 + 澶变笟涓汉姣斾緥)
- BigDecimal socialSecurityDeduction = socialSecurityBase
- .multiply(pensionPersonalRatio)
- .add(socialSecurityBase.multiply(medicalPersonalRatio))
- .add(socialSecurityBase.multiply(unemploymentPersonalRatio))
- .setScale(2, RoundingMode.HALF_UP);
+ // 绀句繚鎵i櫎锛氬繀椤汇�屽憳宸ラ厤缃簡绀句繚妗f銆嶆墠鎵f銆�
+ // 涔嬪墠鏃犺鏈夋病鏈夌ぞ淇濇。妗堥兘鎸� 鍩烘暟 脳 榛樿姣斾緥(0.08+0.02+0.005=10.5%) 鎵f锛�
+ // 瀵艰嚧 102 涓病鍔犵ぞ淇濈殑鍛樺伐琚墸浜� 204.75锛�= 鍩烘湰宸ヨ祫 1950 脳 10.5%锛夈��
+ // 涓汉搴旂即 = 鍏昏�� + 鍖荤枟 + 澶变笟 + 澶х梾鍖荤枟 + 闀挎湡鎶ょ悊銆�
+ // 娉ㄦ剰锛氬師鏉ユ紡绠椾簡鍚庝袱椤癸紝浣垮緱銆屽叺鍥簲闄┿�嶄笌銆屽湴鏂逛簲闄┿�嶄袱涓柟妗堢畻鍑烘潵鐨勬墸娆惧畬鍏ㄤ竴鏍枫��
+ BigDecimal socialSecurityDeduction = BigDecimal.ZERO;
+ if (socialSecurity != null) {
+ BigDecimal personalTotalRatio = pensionPersonalRatio
+ .add(medicalPersonalRatio)
+ .add(unemploymentPersonalRatio)
+ .add(seriousIllnessPersonalRatio)
+ .add(longTermCarePersonalRatio);
+ socialSecurityDeduction = socialSecurityBase.multiply(personalTotalRatio)
+ .setScale(2, RoundingMode.HALF_UP);
+ }
// 鍏Н閲戞墸闄わ細蹇呴』鍚屾椂婊¤冻銆屾柟妗堥厤缃簡鍏Н閲戞瘮渚� > 0銆嶄笖銆屽憳宸ユ。妗堥厤缃簡鍏Н閲戝熀鏁� > 0銆嶆墠鎵f锛�
// 浠讳竴涓嶆弧瓒抽兘瑙嗕负鍏徃鏈即绾冲叕绉噾锛屾墸娆句负 0銆�
@@ -314,9 +328,14 @@
.setScale(2, RoundingMode.HALF_UP);
}
- // 璁$畻璇峰亣鎵f
- // 璁$畻缂哄嫟鎵f锛堣鍋� + 鏃峰伐锛�
- BigDecimal leaveDeduction = calculateAttendanceDeduction(employee, period, baseSalary, workDays, actualDays);
+ // 缂哄嫟鎵f锛堣鍋� + 鏃峰伐锛�
+ // 璁¤柂鍩烘暟 = 鍩烘湰宸ヨ祫 + 宀椾綅宸ヨ祫 + 宸ラ緞宸ヨ祫 + 缁╂晥宸ヨ祫锛堣繖浜涗笌鍑哄嫟澶╂暟鐩存帴鐩稿叧锛夛紱
+ // 涓嶅惈鍔犵彮璐�/鍚勯」琛ヨ创/鍏ㄥ嫟濂栵紙杩欎簺涓嶉殢鍑哄嫟澶╂暟鎶樼畻锛夈��
+ // 娉ㄦ剰锛氫笉鑳界敤"鍩烘湰宸ヨ祫"褰撳熀鏁扳�斺�斿緢澶氬憳宸ュ伐璧勪富浣撴槸宀椾綅宸ヨ祫锛屽惁鍒欏疄鍑� 0 澶╂椂鍙墸鎺夊熀鏈伐璧勶紝宀椾綅宸ヨ祫鐓у彂銆�
+ BigDecimal attendanceBaseSalary = baseSalary
+ .add(postSalary).add(senioritySalary).add(performanceSalary);
+ BigDecimal leaveDeduction = calculateAttendanceDeduction(
+ employee, period, attendanceBaseSalary, workDays, actualDays);
// 璁$畻涓◣鎵i櫎
// 搴旂撼绋庢墍寰楅 = 搴斿彂宸ヨ祫 - 绀句繚鎵i櫎 - 鍏Н閲戞墸闄� - 璧峰緛鐐�(5000)
@@ -376,18 +395,18 @@
* <li>鎵f鎬婚灏侀《涓哄熀鏈伐璧勶紝閬垮厤鍑虹幇璐熷伐璧勩��</li>
* </ol>
*
- * @param employee 鍛樺伐淇℃伅
- * @param period 鏍哥畻鍛ㄦ湡锛堝 2026-02锛�
- * @param baseSalary 鍩烘湰宸ヨ祫
- * @param workDays 搴斿嚭澶╂暟锛堟帓鐝疮璁★紝鏃犳帓鐝椂浼� 22锛�
- * @param actualDays 瀹炲嚭澶╂暟锛堝彇鑷�冨嫟姹囨�伙紱null 琛ㄧず璇ユ湀鏈敓鎴愭眹鎬伙級
- * @return 缂哄嫟鎵f閲戦
+ * @param employee 鍛樺伐淇℃伅
+ * @param period 鏍哥畻鍛ㄦ湡锛堝 2026-02锛�
+ * @param attendanceBase 璁¤柂鍩烘暟 = 鍩烘湰 + 宀椾綅 + 宸ラ緞 + 缁╂晥锛堜笌鍑哄嫟鐩存帴鐩稿叧鐨勫浐瀹氬伐璧勶級
+ * @param workDays 搴斿嚭澶╂暟锛堟帓鐝疮璁★紝鏃犳帓鐝椂浼� 22锛�
+ * @param actualDays 瀹炲嚭澶╂暟锛堝彇鑷�冨嫟姹囨�伙紱null 琛ㄧず璇ユ湀鏈敓鎴愭眹鎬伙級
+ * @return 缂哄嫟鎵f閲戦锛堝皝椤朵负璁¤柂鍩烘暟锛�
*/
private BigDecimal calculateAttendanceDeduction(HrmEmployeeDO employee, String period,
- BigDecimal baseSalary, Integer workDays, Integer actualDays) {
+ BigDecimal attendanceBase, Integer workDays, Integer actualDays) {
int shouldDays = (workDays != null && workDays > 0) ? workDays : 22;
- // 鏃ュ伐璧� = 鍩烘湰宸ヨ祫 / 搴斿嚭澶╂暟锛堜繚鐣� 4 浣嶏紝鏈�鍚庣粺涓�淇濈暀 2 浣嶏級
- BigDecimal dailySalary = baseSalary.divide(new BigDecimal(shouldDays), 4, RoundingMode.HALF_UP);
+ // 鏃ュ伐璧� = 璁¤柂鍩烘暟 / 搴斿嚭澶╂暟锛堜繚鐣� 4 浣嶏紝鏈�鍚庣粺涓�淇濈暀 2 浣嶏級
+ BigDecimal dailySalary = attendanceBase.divide(new BigDecimal(shouldDays), 4, RoundingMode.HALF_UP);
BigDecimal totalDeduction = BigDecimal.ZERO;
BigDecimal leaveDays = BigDecimal.ZERO;
@@ -428,7 +447,7 @@
// 3. 灏侀《锛氭墸娆句笉瓒呰繃鍩烘湰宸ヨ祫
BigDecimal result = totalDeduction.setScale(2, RoundingMode.HALF_UP);
- BigDecimal cap = baseSalary.setScale(2, RoundingMode.HALF_UP);
+ BigDecimal cap = attendanceBase.setScale(2, RoundingMode.HALF_UP);
return result.compareTo(cap) > 0 ? cap : result;
}
@@ -766,16 +785,22 @@
* 閲嶇畻銆岀己鍕ゆ墸娆俱�嶄笌銆屽疄鍙戝伐璧勩��
*
* <p>鏍哥畻鍗� userId 瀛樼殑鏄憳宸D锛坔rm_employee.id锛夈�傛寜銆屽簲鍑哄ぉ鏁� / 瀹炲嚭澶╂暟 + 璇峰亣鍗曘�嶉噸绠�
- * 缂哄嫟鎵f锛堣鍋囨寜閰嶇疆姣斾緥鎵c�佹椃宸ユ寜 100% 鎵c�佸皝椤跺熀鏈伐璧勶級锛屽啀閲嶇畻瀹炲彂宸ヨ祫锛堜笉鍙负璐燂級銆�
- * 鏌ヤ笉鍒板憳宸ユ垨鏍哥畻鍛ㄦ湡鏃讹紝淇濈暀鍘熺己鍕ゆ墸娆撅紝鍙噸绠楀疄鍙戙��
+ * 缂哄嫟鎵f锛堣鍋囨寜閰嶇疆姣斾緥鎵c�佹椃宸ユ寜 100% 鎵c�佸皝椤惰钖熀鏁帮級锛屽啀閲嶇畻瀹炲彂宸ヨ祫锛堜笉鍙负璐燂級銆�
+ *
+ * <p>璁¤柂鍩烘暟 = 鍩烘湰 + 宀椾綅 + 宸ラ緞 + 缁╂晥锛堜笌鍑哄嫟鐩存帴鐩稿叧鐨勫浐瀹氬伐璧勯儴鍒嗭級锛�
+ * 涓嶈兘鐢ㄥ熀鏈伐璧勫崟鐙皝椤讹紝鍚﹀垯宸ヨ祫涓讳綋涓哄矖浣嶅伐璧勭殑鍛樺伐瀹炲嚭 0 澶╂椂浠嶄細鍙戞斁澶ч儴鍒嗗伐璧勩��
*/
private void recalcAttendanceDeduction(HrmSalaryCalculationDO calculation) {
HrmEmployeeDO employee = calculation.getUserId() != null
? employeeMapper.selectById(calculation.getUserId()) : null;
if (employee != null && calculation.getPeriod() != null) {
+ BigDecimal attendanceBaseSalary = nvl(calculation.getBaseSalary())
+ .add(nvl(calculation.getPostSalary()))
+ .add(nvl(calculation.getSenioritySalary()))
+ .add(nvl(calculation.getPerformanceSalary()));
BigDecimal deduction = calculateAttendanceDeduction(
employee, calculation.getPeriod(),
- nvl(calculation.getBaseSalary()),
+ attendanceBaseSalary,
calculation.getWorkDays(),
calculation.getActualDays());
calculation.setLeaveDeduction(deduction);
--
Gitblit v1.9.3