Эх сурвалжийг харах

feat(performance): 实现绩效排名人数自动计算功能

- 新增总排名输入时自动计算各等级理论人数逻辑
- 添加计算理论人数的辅助方法,支持四舍五入
- 从配置中读取各评价结果的比例用于计算
- 更新保存校验逻辑以适应新的计算方式
- 对特定组织(集团本部)跳过人数一致性校验
- 修复部分注释和代码结构问题
wyc 2 цаг өмнө
parent
commit
b76e413ad1

+ 47 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/performance/PerfRankMgmtFormPlugin.java

@@ -59,6 +59,8 @@ import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 import nckd.jxccl.hr.psms.helper.PositionFileHelper;
 import org.apache.commons.lang3.StringUtils;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
@@ -185,11 +187,55 @@ public class PerfRankMgmtFormPlugin extends AbstractFormPlugin implements Wizard
                 this.getModel().setValue(PerfRankMgmtConstant.NCKD_POSTALLOWANCE, hasAllowance,changeSet[0].getRowIndex());
                 this.getView().updateView(PerfRankMgmtConstant.NCKD_POSTALLOWANCE,changeSet[0].getRowIndex());
             }
-
+        }else if(PerfRankMgmtConstant.NCKD_TOPRANKS.equalsIgnoreCase(name)){
+            //输入总排名
+            ChangeData[] changeSet = e.getChangeSet();
+            Object newValue = changeSet[0].getNewValue();
+            Object oldValue = changeSet[0].getOldValue();
+//            优秀人数、基本合格人数、不合格人数
+            if(!Objects.equals(newValue, oldValue)) {
+                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                        .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, PerfRankMgmtConstant.NCKD_RATIO)
+                        .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY, PositionStructureConstant.NCKD_APPRAISALRESULT}, FormConstant.NUMBER_KEY);
+                DynamicObjectCollection query = QueryServiceHelper.query(PerfRankMgmtConstant.RANKRATIOCONF_ENTITYID, queryFieldBuilder.buildSelect(), null);
+                Map<String, BigDecimal> appraisalResultRatioMap = new HashMap<>();
+                query.forEach(dynamicObject -> {
+                    String key = dynamicObject.getString(String.join(".", FormConstant.NCKD_ENTRYENTITY, PositionStructureConstant.NCKD_APPRAISALRESULT, FormConstant.NUMBER_KEY));
+                    BigDecimal value = dynamicObject.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, PerfRankMgmtConstant.NCKD_RATIO));
+                    appraisalResultRatioMap.put(key, value);
+                });
+
+                // 获取配置比例
+                BigDecimal excellentRatio = appraisalResultRatioMap.get(AppraisalResultEnum.EXCELLENT.getCode());
+                BigDecimal qualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.QUALIFIED.getCode());
+                BigDecimal basicallyQualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.BASICALLY_QUALIFIED.getCode());
+                BigDecimal unQualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.UN_QUALIFIED.getCode());
+
+                // 计算各等级的理论人数(四舍五入)
+                int expectedExcellent = calculateExpectedCount(ConvertUtil.toInt(newValue, 0), excellentRatio);
+                int expectedQualified = calculateExpectedCount(ConvertUtil.toInt(newValue, 0), qualifiedRatio);
+                int expectedBasic = calculateExpectedCount(ConvertUtil.toInt(newValue, 0), basicallyQualifiedRatio);
+                int expectedFail = calculateExpectedCount(ConvertUtil.toInt(newValue, 0), unQualifiedRatio);
+
+                this.getModel().setValue(PerfRankMgmtConstant.NCKD_EXCELLENTS, expectedExcellent);
+//                this.getModel().setValue(PerfRankMgmtConstant.NCKD_BASICS, expectedQualified);
+                this.getModel().setValue(PerfRankMgmtConstant.NCKD_BASICS, expectedBasic);
+                this.getModel().setValue(PerfRankMgmtConstant.NCKD_FAILS, expectedFail);
+            }
         }
 
     }
 
+    /**
+     * 计算理论人数(四舍五入)
+     */
+    private int calculateExpectedCount(int totalCount, BigDecimal ratio) {
+        // 将百分比转换为小数进行计算
+        BigDecimal decimalRatio = ratio.divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
+        BigDecimal expected = decimalRatio.multiply(BigDecimal.valueOf(totalCount));
+        return expected.setScale(0, RoundingMode.HALF_UP).intValue();
+    }
+
     @Override
     public void beforeImportEntry(BeforeImportEntryEventArgs e) {
         super.beforeImportEntry(e);

+ 48 - 30
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/performance/validate/PerfRankMgmtSaveValidate.java

@@ -1,5 +1,6 @@
 package nckd.jxccl.hr.psms.plugin.operate.performance.validate;
 
+import akka.routing.FromConfig;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.entity.ExtendedDataEntity;
@@ -113,25 +114,38 @@ public class PerfRankMgmtSaveValidate extends AbstractValidator {
         // 不合格人数
         int failCount = context.failCount;
 
-        // 获取配置比例
+      /*  // 获取配置比例
         BigDecimal excellentRatio = appraisalResultRatioMap.get(AppraisalResultEnum.EXCELLENT.getCode());
         BigDecimal qualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.QUALIFIED.getCode());
         BigDecimal basicallyQualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.BASICALLY_QUALIFIED.getCode());
-        BigDecimal unQualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.UN_QUALIFIED.getCode());
+        BigDecimal unQualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.UN_QUALIFIED.getCode());*/
 
         // 计算各等级的理论人数(四舍五入)
-        int expectedExcellent = calculateExpectedCount(totalRankCount, excellentRatio);
+       /* int expectedExcellent = calculateExpectedCount(totalRankCount, excellentRatio);
         int expectedQualified = calculateExpectedCount(totalRankCount, qualifiedRatio);
         int expectedBasic = calculateExpectedCount(totalRankCount, basicallyQualifiedRatio);
-        int expectedFail = calculateExpectedCount(totalRankCount, unQualifiedRatio);
-
+        int expectedFail = calculateExpectedCount(totalRankCount, unQualifiedRatio);*/
 
+        DynamicObject data = rowDataEntity.getDataEntity();
+        int topRanks = data.getInt(PerfRankMgmtConstant.NCKD_TOPRANKS);
+        int expectedExcellent = data.getInt(PerfRankMgmtConstant.NCKD_EXCELLENTS);
+        int expectedBasic = data.getInt(PerfRankMgmtConstant.NCKD_BASICS);
+        int expectedFail = data.getInt(PerfRankMgmtConstant.NCKD_FAILS);
+        int expectedQualified = topRanks - expectedExcellent - expectedBasic - expectedFail;
+
+
+
+        // 集团本部不校验
+        DynamicObject adminOrg = data.getDynamicObject(FormConstant.NCKD_ADMINORG);
+        DynamicObject secondOrg = adminOrg.getDynamicObject(FormConstant.NCKD_SECONDORG);
+        if(secondOrg == null || !secondOrg.getString(FormConstant.NUMBER_KEY).contains("0101")){
+            // 校验各等级人数是否在合理范围内(允许±1的差异)
+            /*validateCountRange(AppraisalResultEnum.EXCELLENT.getName(), excellentCount, expectedExcellent, totalRankCount,rowDataEntity);
+            validateCountRange(AppraisalResultEnum.QUALIFIED.getName(), qualifiedCount, expectedQualified, totalRankCount,rowDataEntity);
+            validateCountRange(AppraisalResultEnum.BASICALLY_QUALIFIED.getName(), basicCount, expectedBasic, totalRankCount,rowDataEntity);
+            validateCountRange(AppraisalResultEnum.UN_QUALIFIED.getName(), failCount, expectedFail, totalRankCount,rowDataEntity);*/
+        }
 
-        // 校验各等级人数是否在合理范围内(允许±1的差异)
-        validateCountRange(AppraisalResultEnum.EXCELLENT.getName(), excellentCount, expectedExcellent, totalRankCount,rowDataEntity);
-        validateCountRange(AppraisalResultEnum.QUALIFIED.getName(), qualifiedCount, expectedQualified, totalRankCount,rowDataEntity);
-        validateCountRange(AppraisalResultEnum.BASICALLY_QUALIFIED.getName(), basicCount, expectedBasic, totalRankCount,rowDataEntity);
-        validateCountRange(AppraisalResultEnum.UN_QUALIFIED.getName(), failCount, expectedFail, totalRankCount,rowDataEntity);
 
     }
 
@@ -365,26 +379,30 @@ public class PerfRankMgmtSaveValidate extends AbstractValidator {
      */
     private void checkCountConsistency(DynamicObject data, ValidationContext context,
                                        ExtendedDataEntity rowDataEntity) {
-        int topRanks = data.getInt(PerfRankMgmtConstant.NCKD_TOPRANKS);
-        int allowanceRanks = data.getInt(PerfRankMgmtConstant.NCKD_ALLOWANCERANKS);
-        int fails = data.getInt(PerfRankMgmtConstant.NCKD_FAILS);
-        int basics = data.getInt(PerfRankMgmtConstant.NCKD_BASICS);
-        int excellents = data.getInt(PerfRankMgmtConstant.NCKD_EXCELLENTS);
-
-        if (topRanks != context.totalRankCount) {
-            this.addFatalErrorMessage(rowDataEntity, "总排名人数与实际录入数据不一致;\n");
-        }
-        if (allowanceRanks != context.allowanceRankCount) {
-            this.addFatalErrorMessage(rowDataEntity, "R排名人数与实际录入数据不一致;\n");
-        }
-        if (fails != context.failCount) {
-            this.addFatalErrorMessage(rowDataEntity, "不合格人数与实际录入数据不一致;\n");
-        }
-        if (basics != context.basicCount) {
-            this.addFatalErrorMessage(rowDataEntity, "基本人数与实际录入数据不一致;\n");
-        }
-        if (excellents != context.excellentCount) {
-            this.addFatalErrorMessage(rowDataEntity, "优秀人数与实际录入数据不一致;\n");
+        DynamicObject adminOrg = data.getDynamicObject(FormConstant.NCKD_ADMINORG);
+        DynamicObject secondOrg = adminOrg.getDynamicObject(FormConstant.NCKD_SECONDORG);
+        if(secondOrg == null || !secondOrg.getString(FormConstant.NUMBER_KEY).contains("0101")) {
+            int topRanks = data.getInt(PerfRankMgmtConstant.NCKD_TOPRANKS);
+            int allowanceRanks = data.getInt(PerfRankMgmtConstant.NCKD_ALLOWANCERANKS);
+            int fails = data.getInt(PerfRankMgmtConstant.NCKD_FAILS);
+            int basics = data.getInt(PerfRankMgmtConstant.NCKD_BASICS);
+            int excellents = data.getInt(PerfRankMgmtConstant.NCKD_EXCELLENTS);
+
+            if (topRanks != context.totalRankCount) {
+                this.addFatalErrorMessage(rowDataEntity, "总排名人数与实际录入数据不一致;\n");
+            }
+            if (allowanceRanks != context.allowanceRankCount) {
+                this.addFatalErrorMessage(rowDataEntity, "R排名人数与实际录入数据不一致;\n");
+            }
+            if (fails != context.failCount) {
+                this.addFatalErrorMessage(rowDataEntity, "不合格人数与实际录入数据不一致;\n");
+            }
+            if (basics != context.basicCount) {
+                this.addFatalErrorMessage(rowDataEntity, "基本人数与实际录入数据不一致;\n");
+            }
+            if (excellents != context.excellentCount) {
+                this.addFatalErrorMessage(rowDataEntity, "优秀人数与实际录入数据不一致;\n");
+            }
         }
     }