Przeglądaj źródła

Merge remote-tracking branch 'origin/master'

jtd 2 tygodni temu
rodzic
commit
60c8f6dc6b
29 zmienionych plików z 1625 dodań i 118 usunięć
  1. 4 0
      code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/FormConstant.java
  2. 14 2
      code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/utils/DateUtil.java
  3. 148 0
      code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/swc/helper/AdjFileServiceHelper.java
  4. 5 4
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/AnnualAdjustmentService.java
  5. 342 49
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/JobLevelCalculatorService.java
  6. 2 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/ContributionConstant.java
  7. 16 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/PositionStructureConstant.java
  8. 131 3
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/ContributionHelper.java
  9. 136 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ContribBillFormPlugin.java
  10. 16 1
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/adjust/NewDynamicAdjustmentOperationPlugIn.java
  11. 18 1
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/annualadjust/AnnualAdjustmentOperationPlugin.java
  12. 1 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/annualadjust/AnnualLockOrUnLockedOpPlugin.java
  13. 27 2
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/ContribBillOpPlugin.java
  14. 129 10
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/file/PersonPosFileSaveOpPlugin.java
  15. 85 10
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/BaseInitialOperationPlugIn.java
  16. 21 1
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/NewHireInitialOperationPlugIn.java
  17. 20 2
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/ServingInitialOperationPlugIn.java
  18. 1 9
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/other/NewAppointMentOpPlugin.java
  19. 355 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/task/PsmsAdjustSalaryTask.java
  20. 1 1
      code/nckd-cosmic-debug/src/main/java/kd/cosmic/debug/tools/CosmicLauncher.java
  21. 3 2
      code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/salary/PushAdjustOpPlugin.java
  22. 3 5
      code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/salary/SalaryAdjOpPlugin.java
  23. 1 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/business/coordination/SinsurCoordSplitService.java
  24. 1 1
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/business/datacomparison/DataComparisonQueryService.java
  25. 21 0
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/formplugin/web/coordination/HCSIEmpCoordVerifBillListEx.java
  26. 1 1
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/utils/ReportUtils.java
  27. 23 5
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hcdm/opplugin/annualincome/SalAnnualIncomeUpdatePlugin.java
  28. 87 4
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/init/business/SynPendingSalaryAdjDataServiceImpl.java
  29. 13 5
      code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/utils/SwcUtils.java

+ 4 - 0
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/FormConstant.java

@@ -440,4 +440,8 @@ public class FormConstant {
     /** 别名 */
     /** 别名 */
     public static final String NCKD_ISPARTICIPATE = "nckd_isparticipate";
     public static final String NCKD_ISPARTICIPATE = "nckd_isparticipate";
 
 
+
+    /** 岗位工资标准(jt002)*/
+    public static final Long STANDARDITEM_ID_KEY = 2321899710350111744L;
+
 }
 }

+ 14 - 2
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/utils/DateUtil.java

@@ -399,6 +399,16 @@ public class DateUtil {
 
 
     // ==================== 时间范围处理 ====================
     // ==================== 时间范围处理 ====================
 
 
+    /**
+     * 获取日期的开始时间(00:00:00)
+     *
+     * @param date 日期时间
+     * @return 当天的开始时间
+     */
+    public static Date beginOfDay(Date date) {
+        return toDate(beginOfDay(toLocalDateTime(date)));
+    }
+
     /**
     /**
      * 获取日期的开始时间(00:00:00)
      * 获取日期的开始时间(00:00:00)
      *
      *
@@ -450,14 +460,16 @@ public class DateUtil {
         return dateTime.withDayOfYear(1).toLocalDate().atStartOfDay();
         return dateTime.withDayOfYear(1).toLocalDate().atStartOfDay();
     }
     }
 
 
+
+
     /**
     /**
      * 获取日期当天的结束时间(23:59:59.999999999)
      * 获取日期当天的结束时间(23:59:59.999999999)
      *
      *
      * @param date 日期时间
      * @param date 日期时间
      * @return 当天的结束时间
      * @return 当天的结束时间
      */
      */
-    public static LocalDateTime endOfDay(Date date) {
-        return endOfDay(toLocalDateTime(date));
+    public static Date endOfDay(Date date) {
+        return toDate(endOfDay(toLocalDateTime(date)));
     }
     }
 
 
     /**
     /**

+ 148 - 0
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/swc/helper/AdjFileServiceHelper.java

@@ -0,0 +1,148 @@
+package nckd.jxccl.base.swc.helper;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.validate.BillStatus;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.servicehelper.DispatchServiceHelper;
+import kd.sdk.swc.hcdm.business.helper.HCDMAdjFileServiceHelper;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.entity.helper.EntityHelper;
+import nckd.jxccl.base.hrpi.helper.EmpPosOrgRelHelper;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 定调薪帮助类
+ *
+ * @author W.Y.C
+ * @version 1.0
+ * @date 2025/12/21 16:02
+ */
+public class AdjFileServiceHelper {
+
+    protected final static Log logger = LogFactory.getLog(AdjFileServiceHelper.class);
+
+    /**
+     * 获取员工某个薪酬项目最新定调薪记录
+     * @param personIds 人员id
+     * @param standardItemId 定调薪项目id
+     * @return: java.util.List<nckd.jxccl.base.swc.helper.AdjFileServiceHelper.SalaryAdjustmentResult>
+     * @author W.Y.C
+     * @date: 2025/12/21 16:06
+     */
+    public static List<SalaryAdjustmentResult> getLastDecAdjRecords(List<Long> personIds,Long standardItemId) {
+        //获取员工最新任职
+        Map<Long, DynamicObject> empPosOrgRelByEmployeesMap = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployeesMap(personIds);
+        List<Long> allEmpPosOrgRelIds = empPosOrgRelByEmployeesMap.values().stream()
+                .map(result -> result.getLong(FormConstant.ID_KEY))
+                .collect(Collectors.toList());
+
+        List<SalaryAdjustmentResult> salaryAdjustmentResultList = new ArrayList<>();
+
+        DynamicObject standardItem = EntityHelper.newEntity(FormConstant.HSBS_STANDARDITEM);
+        standardItem.set(FormConstant.ID_KEY, standardItemId);
+        Map<String, Object> adjFileParams = new HashMap<>();
+        adjFileParams.put("employees", personIds);
+        List<String> status = new ArrayList<>();
+        status.add(BillStatus.C.toString());
+        adjFileParams.put("status", status);
+        //获取人员定薪档案
+        Map<String, Object> adjFileResult = DispatchServiceHelper.invokeBizService("swc", "hcdm", "IAdjFileInfoService", "queryAdjFileBoByEmp", adjFileParams);
+        if (ConvertUtil.toBoolean(adjFileResult.get("success"))) {
+            List<Map> list = ConvertUtil.toList(adjFileResult.get("data"), ArrayList::new);
+            List<Long> adjFileIds = new ArrayList<>();
+            for (Map map : list) {
+                Long id = ConvertUtil.toLong(map.get(FormConstant.ID_KEY));
+                //根据员工任职匹配
+                Long empPosOrgRelId = ConvertUtil.toLong(map.get("empposorgrel_id"));
+                if (allEmpPosOrgRelIds.contains(empPosOrgRelId)) {
+                    adjFileIds.add(id);
+                }
+            }
+            //构建定调薪记录查询条件
+            Map<String, Object> adjRecordParams = new HashMap<>();
+            List<Map<String, Object>> dataList = new ArrayList<>();
+            for (Long adjFileId : adjFileIds) {
+                Map<String, Object> dataItem = new HashMap<>();
+                // 调薪档案ID
+                dataItem.put("adjfile", adjFileId);
+                // 调薪项目ID
+                dataItem.put("standarditem", standardItemId);
+                // 查询基准日期
+                dataItem.put("startdate", new Date());
+                // 唯一标识
+                dataItem.put("_uniquecode", "unique" + adjFileId);
+                dataList.add(dataItem);
+            }
+            adjRecordParams.put("data", dataList);
+            adjRecordParams.put("selprops", "salarystdv.rankentry.rank.id,salarystdv.rankentry.rank.name,salarystdv.rankentry.rank.number,salarystdv.rankentry.rank.index,salarystdv.rankentry.frankindex,company.id,company.name,hcdmorg.id,");
+            //查询定调薪记录
+            //hcdm_decadjrecor
+            Map<String, Object> lastDecAdjRecordMap = HCDMAdjFileServiceHelper.getLastDecAdjRecords(adjRecordParams);
+            if (ConvertUtil.toBoolean(lastDecAdjRecordMap.get("success"))) {
+                List<Map> datas = ConvertUtil.toList(lastDecAdjRecordMap.get("data"), ArrayList::new);
+                for (Map data : datas) {
+                    if (ConvertUtil.toBoolean(data.get("success"))) {
+                        List<DynamicObject> adjRecordList = ConvertUtil.toList(data.get("data"), ArrayList::new);
+                        for (DynamicObject dynamicObject : adjRecordList) {
+                            // 人员
+                            DynamicObject employee = dynamicObject.getDynamicObject("adjfile").getDynamicObject("employee");
+                            SalaryAdjustmentResult salaryAdjustmentResult = new SalaryAdjustmentResult();
+                            //薪酬管理组织
+                            DynamicObject hcdmOrg = dynamicObject.getDynamicObject("hcdmorg");
+                            //薪酬标准表版本
+                            DynamicObject salaryStDv = dynamicObject.getDynamicObject("salarystdv");
+                            //薪等(01岗、02岗)
+                            DynamicObject salaryGrade = dynamicObject.getDynamicObject("salarygrade");
+                            //薪档(1档、2档)
+                            DynamicObject salaryRank = dynamicObject.getDynamicObject("salaryrank");
+                            //金额
+                            BigDecimal amount = dynamicObject.getBigDecimal("amount");
+                            salaryAdjustmentResult.employee = employee;
+                            salaryAdjustmentResult.hcdmOrg = hcdmOrg;
+                            salaryAdjustmentResult.adjFileInfo = dynamicObject.getDynamicObject("adjfile");
+                            salaryAdjustmentResult.salaryStDv = salaryStDv;
+                            salaryAdjustmentResult.standardItem = standardItem;
+                            salaryAdjustmentResult.salaryGrade = salaryGrade;
+                            salaryAdjustmentResult.salaryRank = salaryRank;
+                            salaryAdjustmentResult.amount = amount;
+                            salaryAdjustmentResultList.add(salaryAdjustmentResult);
+                        }
+                    }
+                }
+            } else {
+                logger.error("查询定调薪记录失败");
+            }
+        } else {
+            logger.error("获取人员定薪档案失败");
+        }
+        return salaryAdjustmentResultList;
+    }
+
+
+    public static class SalaryAdjustmentResult {
+        /** 人员ID*/
+        public DynamicObject employee;
+        public DynamicObject hcdmOrg;
+        /**定调薪档案*/
+        public DynamicObject adjFileInfo;
+        /**薪酬标准表*/
+        public DynamicObject salaryStDv;
+        /** 定调薪项目 */
+        public DynamicObject standardItem;
+        /** 薪等(01岗、02岗)*/
+        public DynamicObject salaryGrade;
+        /** 薪档(1档、2档)*/
+        public DynamicObject salaryRank;
+        //金额
+        public BigDecimal amount;
+    }
+}

+ 5 - 4
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/AnnualAdjustmentService.java

@@ -351,9 +351,9 @@ public class AnnualAdjustmentService {
 
 
         //4、获取年度贡献积分
         //4、获取年度贡献积分
         //对应SHR:291行;utils.YearContributeScoreBillEntryScoreSumBypersonidAndYear
         //对应SHR:291行;utils.YearContributeScoreBillEntryScoreSumBypersonidAndYear
-        List<ContributionHelper.ScoreItemValidScore> scoreItemAccumulateScore = ContributionHelper.getApprovedScoreItemAccumulateScore(new Long[]{ac.personId}, DateUtil.toDate(lastYearDateTime));
+        List<ContributionHelper.ScoreItemValidScore> scoreItemAccumulateScore = ContributionHelper.sumScoreItemAccumulateScore(new Long[]{ac.personId}, DateUtil.toDate(lastYearDateTime));
         //计算出最多可得的分数(根据积分配置项)
         //计算出最多可得的分数(根据积分配置项)
-        List<ContributionHelper.ScoreItemValidScore> allowedScoreList = ContributionHelper.calculateMaxAllowedScore(scoreItemAccumulateScore);
+        List<ContributionHelper.ScoreItemValidScore> allowedScoreList = ContributionHelper.calculateMaxAllowedScore1(scoreItemAccumulateScore);
         BigDecimal allowedScoreSum = BigDecimal.ZERO;
         BigDecimal allowedScoreSum = BigDecimal.ZERO;
         for (ContributionHelper.ScoreItemValidScore allowedScore : allowedScoreList) {
         for (ContributionHelper.ScoreItemValidScore allowedScore : allowedScoreList) {
             String scoreItemNumber = allowedScore.getScoreItemNumber();
             String scoreItemNumber = allowedScore.getScoreItemNumber();
@@ -385,7 +385,8 @@ public class AnnualAdjustmentService {
             //比较实际累计总分和未受限制的实际累计总分
             //比较实际累计总分和未受限制的实际累计总分
             if(sumScore.compareTo(validScore) != 0){
             if(sumScore.compareTo(validScore) != 0){
                 //实际累计积分与有效积分不符,说明被限高
                 //实际累计积分与有效积分不符,说明被限高
-                ac.whyAdjust1.add(StrFormatter.format("上年度【{}】【{}】积分实际累计总分为【{}】但达到项目最高分限制,最终有效应用分为【{}】;", scoreItemEnum.getCode(), sumScore, validScore));
+                ac.whyAdjust1.add(StrFormatter.format("上年度【{}】【{}】积分实际累计总分为【{}】但达到项目最高分限制,最终有效应用分为【{}】;", scoreItemEnum.getName(), sumScore, validScore));
+                logger.warn(StrFormatter.format("上年度【{}】积分实际累计总分为【{}】但达到项目最高分限制,最终有效应用分为【{}】;", scoreItemEnum.getName(), sumScore, validScore));
             }
             }
 
 
         }
         }
@@ -594,7 +595,7 @@ public class AnnualAdjustmentService {
         logger.info("上年度贡献综合评价分: " + ac.lastYearContributeScore);
         logger.info("上年度贡献综合评价分: " + ac.lastYearContributeScore);
 
 
         ac.addYearContributeScore = ac.lastYearContributeScore.multiply(new BigDecimal("0.1"));
         ac.addYearContributeScore = ac.lastYearContributeScore.multiply(new BigDecimal("0.1"));
-        logger.info("年度新增的贡献积分: " + ac.addYearContributeScore);
+        logger.info("年度新增的贡献积分(*10%): " + ac.addYearContributeScore);
 
 
         BigDecimal lastsum = ac.data.getLastSumScore() == null ? BigDecimal.ZERO : ac.data.getLastSumScore();
         BigDecimal lastsum = ac.data.getLastSumScore() == null ? BigDecimal.ZERO : ac.data.getLastSumScore();
         logger.info("上年累计积分池的分: " + lastsum);
         logger.info("上年累计积分池的分: " + lastsum);

Plik diff jest za duży
+ 342 - 49
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/JobLevelCalculatorService.java


+ 2 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/ContributionConstant.java

@@ -39,6 +39,8 @@ public class ContributionConstant extends FormConstant {
     public static final String NCKD_SCOREITEMSUB = "nckd_scoreitemsub";
     public static final String NCKD_SCOREITEMSUB = "nckd_scoreitemsub";
     /** 积分项目名次 */
     /** 积分项目名次 */
     public static final String NCKD_SCOREITEMRANK = "nckd_scoreitemrank";
     public static final String NCKD_SCOREITEMRANK = "nckd_scoreitemrank";
+    /** 分录-积分项目名次 */
+    public static final String NCKD_SCOREITEMRANKEN = "nckd_scoreitemranken";
 
 
 
 
 
 

+ 16 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/PositionStructureConstant.java

@@ -121,6 +121,22 @@ public class PositionStructureConstant extends FormConstant {
     public static final String NCKD_LEVELKEEPREASON = "nckd_levelkeepreason";
     public static final String NCKD_LEVELKEEPREASON = "nckd_levelkeepreason";
     /** 锁定时间*/
     /** 锁定时间*/
     public static final String POSITIONAPPOINTMENTQUERY = "positionappointmentquery";
     public static final String POSITIONAPPOINTMENTQUERY = "positionappointmentquery";
+
+    /** 系数 */
+    public static final String NCKD_COEFFICIENT = "nckd_coefficient";
+    /** 当前01档岗位工资 */
+    public static final String NCKD_CURRENTPOSTSALARY = "nckd_currentpostsalary";
+    /** 岗位津贴 */
+    public static final String NCKD_POSTALLOWANCE = "nckd_postallowance";
+    /** 是否已推送调薪 */
+    public static final String NCKD_ISSALADJPUSH = "nckd_issaladjpush";
+    /** 调薪推送时间 */
+    public static final String NCKD_SALADJPUSHTIME = "nckd_saladjpushtime";
+    /** 调薪id */
+    public static final String NCKD_SALADJID = "nckd_saladjid";
+    /** 调薪编码 */
+    public static final String NCKD_SALADJNUMBER = "nckd_saladjnumber";
+
     /*-------------------------------------- 员工职位档案 end --------------------------------------*/
     /*-------------------------------------- 员工职位档案 end --------------------------------------*/
 
 
 
 

+ 131 - 3
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/ContributionHelper.java

@@ -5,13 +5,17 @@ import kd.bos.algo.AlgoContext;
 import kd.bos.algo.DataSet;
 import kd.bos.algo.DataSet;
 import kd.bos.algo.Row;
 import kd.bos.algo.Row;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.QueryServiceHelper;
 import kd.bos.servicehelper.QueryServiceHelper;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.enums.psms.ScoreItemEnum;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
 import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
+import nckd.jxccl.hr.psms.business.AnnualAdjustmentService;
 import nckd.jxccl.hr.psms.common.ContributionConstant;
 import nckd.jxccl.hr.psms.common.ContributionConstant;
 
 
 import java.math.BigDecimal;
 import java.math.BigDecimal;
@@ -32,6 +36,8 @@ import java.util.stream.Collectors;
  */
  */
 public class ContributionHelper {
 public class ContributionHelper {
 
 
+    protected final static Log logger = LogFactory.getLog(AnnualAdjustmentService.class);
+
     /**
     /**
      * 根据人员获取积分项目有效分数
      * 根据人员获取积分项目有效分数
      * 依据人员某年度已获得的积分(含在途单据)+积分配置的最高分计算出可获得的分数
      * 依据人员某年度已获得的积分(含在途单据)+积分配置的最高分计算出可获得的分数
@@ -186,7 +192,8 @@ public class ContributionHelper {
                             String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY),
                             String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY),
                             String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.NUMBER_KEY),
                             String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.NUMBER_KEY),
                             String.join(".", ContributionConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY),
                             String.join(".", ContributionConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY),
-                            String.join(".", ContributionConstant.NCKD_SCOREITEMRANK, FormConstant.ID_KEY)}) // 添加名次分组
+                            String.join(".", ContributionConstant.NCKD_SCOREITEMRANK, FormConstant.ID_KEY)
+                    })
                     .sum(String.join(".", ContributionConstant.NCKD_ENTRYENTITY, FormConstant.NCKD_SCORE),"sumScore").finish();
                     .sum(String.join(".", ContributionConstant.NCKD_ENTRYENTITY, FormConstant.NCKD_SCORE),"sumScore").finish();
 
 
             while (sumDateSet.hasNext()) {
             while (sumDateSet.hasNext()) {
@@ -205,6 +212,67 @@ public class ContributionHelper {
         return scoreItemValidScoreList;
         return scoreItemValidScoreList;
     }
     }
 
 
+
+    /**
+     * 根据人员和年度获取积分项目已累计分数
+     * @param personIds 人员
+     * @param year 年度
+     * @return: List<ScoreItemValidScore> 积分项目已累计分数
+     * @author W.Y.C
+     * @date: 2025/10/26 16:20
+     */
+    public static List<ScoreItemValidScore> sumScoreItemAccumulateScore(Long[] personIds, Date year) {
+        if (personIds == null || personIds.length == 0) {
+            return new ArrayList<>();
+        }
+
+        LocalDateTime yearStarDateTime = DateUtil.beginOfYear(DateUtil.toLocalDateTime(year));
+        QueryFieldBuilder scoreItemConfFieldBuilder = QueryFieldBuilder.create()
+                .add(ContributionConstant.NCKD_YEAR)
+                .addIdNumberName(ContributionConstant.NCKD_SCOREITEM)
+                .addIdNumberName(ContributionConstant.NCKD_SCOREITEMSUB)
+                .addIdNumberName(ContributionConstant.NCKD_SCOREITEMRANK) // 添加积分项目名次字段
+                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON},FormConstant.ID_KEY)
+                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionConstant.NCKD_SCORE, ContributionConstant.NCKD_ORISCORE);
+
+        //只查询"已审批通过"年度贡献积分
+        QFilter filter = QFilterCommonHelper.getBillStatusFilter()
+                .and(ContributionConstant.NCKD_YEAR,QCP.large_equals,DateUtil.beginOfDay(yearStarDateTime))
+                .and(ContributionConstant.NCKD_YEAR,QCP.less_equals, DateUtil.endOfDay(yearStarDateTime))
+                .and(String.join( ".",FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON),QCP.in,personIds);
+
+        List<ScoreItemValidScore> scoreItemValidScoreList = new ArrayList<>();
+        try(AlgoContext context = Algo.newContext()) {
+            DataSet dateSet = QueryServiceHelper.queryDataSet(ContributionHelper.class.getName(),
+                    ContributionConstant.CONTRIBBILL_ENTITYID,
+                    scoreItemConfFieldBuilder.buildSelect(),
+                    new QFilter[]{filter}, null, 5000);
+
+            DataSet sumDateSet = dateSet.copy()
+                    // 按人员、积分项目、积分项目子项、积分项目名次进行分组
+                    .groupBy(new String[]{String.join(".", ContributionConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON, FormConstant.ID_KEY),
+                            String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY),
+                            String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.NUMBER_KEY)
+                    })
+                    .sum(String.join(".", ContributionConstant.NCKD_ENTRYENTITY, FormConstant.NCKD_SCORE),"sumScore").finish();
+
+            while (sumDateSet.hasNext()) {
+                Row row = sumDateSet.next();
+                Long personId = row.getLong(String.join(".", ContributionConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON, FormConstant.ID_KEY));
+                Long scoreItemId = row.getLong(String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY));
+                String scoreItemNumber = row.getString(String.join(".", ContributionConstant.NCKD_SCOREITEM, FormConstant.NUMBER_KEY));
+                //已获得的累计积分
+                BigDecimal sumScore = row.getBigDecimal("sumScore");
+                ScoreItemValidScore scoreItemValidScore = new ScoreItemValidScore(personId, scoreItemId,scoreItemNumber, null, null, sumScore);
+                scoreItemValidScoreList.add(scoreItemValidScore);
+            }
+        }
+        return scoreItemValidScoreList;
+    }
+
+
+
+
     /**
     /**
      * 根据人员和年度获取积分项目已累计分数(包含所有未废弃记录)
      * 根据人员和年度获取积分项目已累计分数(包含所有未废弃记录)
      * @param personIds 人员
      * @param personIds 人员
@@ -439,6 +507,65 @@ public class ContributionHelper {
         return result;
         return result;
     }
     }
 
 
+
+    /**
+     * 计算最多可得的分数
+     * 根据累计积分和分数配置映射表,如果超过配置的限制分数则返回限制分最大分数,
+     * 计算每个积分大项在考虑三重限制条件下的最大可获得分数:
+     * 1. 名次限制:每个积分项目名次可能有分数上限(最高优先级)
+     * 2. 子项限制:每个具体积分项目子项可能有分数上限
+     * 3. 大项限制:整个积分大项可能有总分上限
+     *
+     * @param scoreItemValidScoreList 某个人员所有积分项目的累计积分(personId、scoreItemId、scoreItemSubId、scoreItemRankId、sumScore有值)
+     * @return 最多可得的分数列表(按大项维度聚合)
+     * @author W.Y.C
+     * @date: 2025/10/27
+     */
+    public static List<ScoreItemValidScore> calculateMaxAllowedScore1(List<ScoreItemValidScore> scoreItemValidScoreList) {
+
+        //获取积分限分配置
+        Map<String, BigDecimal> scoreConfMap = ContributionHelper.getScoreConf();
+        /*Map<String, BigDecimal> scoreConfMap = Maps.newConcurrentMap();
+         scoreConfMap.put("11-111-1111",new BigDecimal(2));
+         scoreConfMap.put("11-121",new BigDecimal(5));
+         scoreConfMap.put("11",new BigDecimal(20));*/
+
+        List<ScoreItemValidScore> result = new ArrayList<>();
+
+        // 按大类分组
+        Map<Long, List<ScoreItemValidScore>> groupedByScoreItemId = scoreItemValidScoreList.stream()
+                .collect(Collectors.groupingBy(ScoreItemValidScore::getScoreItemId));
+
+        for (Map.Entry<Long, List<ScoreItemValidScore>> entry : groupedByScoreItemId.entrySet()) {
+            Long scoreItemId = entry.getKey();
+            List<ScoreItemValidScore> valueList = entry.getValue();
+
+            // 获取大项限制分数
+            BigDecimal scoreItemMaxScore = scoreConfMap.get(scoreItemId + "");
+
+            BigDecimal totalAllowedScore = BigDecimal.ZERO;
+            for (ScoreItemValidScore item : valueList) {
+                BigDecimal score = item.getSumScore() == null ? BigDecimal.ZERO : item.getSumScore();
+                // 应用大项限制(如果设置了大项限制)
+                if (scoreItemMaxScore != null && scoreItemMaxScore.compareTo(BigDecimal.ZERO) >= 0) {
+                    totalAllowedScore = scoreItemMaxScore.min(score);
+                }else{
+                    //没有配置限制,则直接使用录入的分数
+                    ScoreItemEnum scoreItemEnum = ScoreItemEnum.getByCode(item.getScoreItemNumber());
+                    logger.warn("积分【{}】没有配置积分项限制,使用实际录入的分数:{}",scoreItemEnum.getName() ,score);
+                    totalAllowedScore = score;
+                }
+                // 创建结果对象,只包含scoreItemId和validScore
+                ScoreItemValidScore resultItem = new ScoreItemValidScore(item.getPersonId(), scoreItemId, null, null);
+                resultItem.setScoreItemNumber(item.getScoreItemNumber());
+                resultItem.setValidScore(totalAllowedScore);
+                resultItem.setSumScore(score);
+                result.add(resultItem);
+            }
+        }
+        return result;
+    }
+
     /**
     /**
      * 决定使用哪种累计分数
      * 决定使用哪种累计分数
      * @param scoreConfMap 分数配置映射
      * @param scoreConfMap 分数配置映射
@@ -619,7 +746,7 @@ public class ContributionHelper {
         }
         }
 
 
         public BigDecimal getValidScore() {
         public BigDecimal getValidScore() {
-            //为空时说明不限制分数
+           /* //为空时说明不限制分数
             BigDecimal trulyValidScore = this.currentScore;
             BigDecimal trulyValidScore = this.currentScore;
             if(this.validScore != null && this.currentScore != null){
             if(this.validScore != null && this.currentScore != null){
                 //如果可使用分数超过录入分数则使用录入分数(oriScore),否则使用可使用分数
                 //如果可使用分数超过录入分数则使用录入分数(oriScore),否则使用可使用分数
@@ -627,7 +754,8 @@ public class ContributionHelper {
             }else{
             }else{
                 return BigDecimal.ZERO;
                 return BigDecimal.ZERO;
             }
             }
-            return trulyValidScore;
+            return trulyValidScore;*/
+            return this.validScore;
         }
         }
 
 
         public void setValidScore(BigDecimal validScore) {
         public void setValidScore(BigDecimal validScore) {

+ 136 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ContribBillFormPlugin.java

@@ -1,9 +1,11 @@
 package nckd.jxccl.hr.psms.plugin.form.contribution;
 package nckd.jxccl.hr.psms.plugin.form.contribution;
 
 
+import kd.bos.bill.OperationStatus;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.entity.datamodel.events.ChangeData;
 import kd.bos.entity.datamodel.events.ChangeData;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.form.FormShowParameter;
 import kd.bos.form.field.BasedataEdit;
 import kd.bos.form.field.BasedataEdit;
 import kd.bos.form.field.events.BeforeF7SelectEvent;
 import kd.bos.form.field.events.BeforeF7SelectEvent;
 import kd.bos.form.field.events.BeforeF7SelectListener;
 import kd.bos.form.field.events.BeforeF7SelectListener;
@@ -11,9 +13,12 @@ import kd.bos.form.plugin.AbstractFormPlugin;
 import kd.bos.list.ListShowParameter;
 import kd.bos.list.ListShowParameter;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
 import kd.sdk.plugin.Plugin;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.enums.psms.ScoreItemEnum;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.entity.helper.EntityHelper;
 import nckd.jxccl.hr.psms.common.ContributionConstant;
 import nckd.jxccl.hr.psms.common.ContributionConstant;
 import nckd.jxccl.hr.psms.helper.ContributionHelper;
 import nckd.jxccl.hr.psms.helper.ContributionHelper;
 
 
@@ -22,6 +27,7 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.Date;
 import java.util.EventObject;
 import java.util.EventObject;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Objects;
 
 
 /**
 /**
@@ -33,6 +39,38 @@ import java.util.Objects;
 */
 */
 public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin, BeforeF7SelectListener {
 public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin, BeforeF7SelectListener {
 
 
+    @Override
+    public void afterCreateNewData(EventObject e) {
+        FormShowParameter formShowParameter = this.getView().getFormShowParameter();
+        if (formShowParameter.getStatus() == OperationStatus.ADDNEW) {
+            Object value = this.getModel().getValue(ContributionConstant.NCKD_SCOREITEM);
+            if (value != null) {
+                DynamicObject scoreItem = ConvertUtil.toDynamicObjectOrNull(value);
+                if (scoreItem != null) {
+                    String scoreItemNumber = scoreItem.getString(FormConstant.NUMBER_KEY);
+                    if (ScoreItemEnum.SKILL_CONTEST_SCORE.getCode().equalsIgnoreCase(scoreItemNumber)) {
+                        //技能竞赛积分默认三行分录
+                        DynamicObjectCollection dynamicObjectCollection = this.getModel().getDataEntity(true).getDynamicObjectCollection(ContributionConstant.NCKD_ENTRYENTITY);
+                        DynamicObjectCollection scoreItemRankColl = QueryServiceHelper.query(ContributionConstant.NCKD_SCOREITEMRANK,
+                                FormConstant.ID_KEY+","+FormConstant.NAME_KEY+","+FormConstant.NUMBER_KEY,
+                                new QFilter[]{new QFilter(ContributionConstant.NCKD_SCOREITEM, QCP.equals, scoreItem.getLong(FormConstant.ID_KEY))},
+                                ContributionConstant.INDEX_KEY
+                        );
+                        for (DynamicObject scoreItemRank : scoreItemRankColl) {
+                            DynamicObject dynamicObject = dynamicObjectCollection.addNew();
+                            DynamicObject newScoreItemRank = EntityHelper.newEntity(ContributionConstant.NCKD_SCOREITEMRANK, scoreItemRank.getLong(FormConstant.ID_KEY));
+                            newScoreItemRank.set(ContributionConstant.NAME_KEY, scoreItemRank.getString(FormConstant.NAME_KEY));
+                            newScoreItemRank.set(ContributionConstant.NUMBER_KEY, scoreItemRank.getString(FormConstant.NUMBER_KEY));
+
+                            dynamicObject.set(ContributionConstant.NCKD_SCOREITEMRANKEN,newScoreItemRank);
+                        }
+                        this.getView().updateView(ContributionConstant.NCKD_ENTRYENTITY);
+                    }
+                }
+            }
+        }
+    }
+
     @Override
     @Override
     public void registerListener(EventObject e) {
     public void registerListener(EventObject e) {
         super.registerListener(e);
         super.registerListener(e);
@@ -118,6 +156,49 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
         DynamicObject scoreItemRank = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMRANK));
         DynamicObject scoreItemRank = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMRANK));
         DynamicObject person = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_PERSON, rowIndex));
         DynamicObject person = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_PERSON, rowIndex));
         BigDecimal oriScore = ConvertUtil.toBigDecimal(this.getModel().getValue(ContributionConstant.NCKD_ORISCORE, rowIndex));
         BigDecimal oriScore = ConvertUtil.toBigDecimal(this.getModel().getValue(ContributionConstant.NCKD_ORISCORE, rowIndex));
+        if (date != null && scoreItem != null && scoreItemSub != null) {
+            String scoreItemNumber = scoreItem.getString(FormConstant.NUMBER_KEY);
+            if (ScoreItemEnum.RESEARCH_SCORE.getCode().equalsIgnoreCase(scoreItemNumber)) {
+                if (person != null  && oriScore != null && oriScore.compareTo(BigDecimal.ZERO) > 0) {
+                    //科研与创新需要需要匹配积分规则
+                    QFilter filter = new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM), QCP.equals, scoreItem.getLong(FormConstant.ID_KEY))
+                            .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB), QCP.equals, scoreItemSub.getLong(FormConstant.ID_KEY)))
+                            .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMRANK), QCP.equals, scoreItemRank.getLong(FormConstant.ID_KEY)));
+                    Map<String, BigDecimal> scoreConf = ContributionHelper.getScoreConf(filter);
+                    String key = scoreItem.getLong(FormConstant.ID_KEY) + "-" + scoreItemSub.getLong(FormConstant.ID_KEY) + "-" + scoreItemRank.getLong(FormConstant.ID_KEY);
+                    BigDecimal validScore = oriScore;
+                    if (!scoreConf.isEmpty() && scoreConf.containsKey(key)) {
+                        BigDecimal maxScore = scoreConf.get(key);
+                        if (maxScore != null) {
+                            validScore = oriScore.compareTo(maxScore) > 0 ? maxScore : oriScore;
+                        }
+                    }
+                    this.getModel().setValue(ContributionConstant.NCKD_SCORE, validScore, rowIndex);
+                    this.getView().updateView(ContributionConstant.NCKD_SCORE, rowIndex);
+                }
+            } else {
+                this.getModel().setValue(ContributionConstant.NCKD_SCORE, oriScore, rowIndex);
+                this.getView().updateView(ContributionConstant.NCKD_SCORE, rowIndex);
+            }
+        }
+    }
+
+    /**
+     * 处理分录行变更
+     * 分录变更则针对当前分录计算积分
+     * @param rowIndex 行索引
+     * @return: void
+     * @author W.Y.C
+     * @date: 2025/10/26 19:47
+     */
+    private void handleEntryRowChange1(int rowIndex) {
+        Long id = ConvertUtil.toLong(this.getModel().getValue(FormConstant.ID_KEY));
+        Date date = ConvertUtil.toDate(this.getModel().getValue(ContributionConstant.NCKD_YEAR));
+        DynamicObject scoreItem = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEM));
+        DynamicObject scoreItemSub = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMSUB));
+        DynamicObject scoreItemRank = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMRANK));
+        DynamicObject person = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_PERSON, rowIndex));
+        BigDecimal oriScore = ConvertUtil.toBigDecimal(this.getModel().getValue(ContributionConstant.NCKD_ORISCORE, rowIndex));
 
 
         if (date != null && scoreItem != null && scoreItemSub != null && person != null
         if (date != null && scoreItem != null && scoreItemSub != null && person != null
                 && oriScore != null && oriScore.compareTo(BigDecimal.ZERO) > 0) {
                 && oriScore != null && oriScore.compareTo(BigDecimal.ZERO) > 0) {
@@ -149,6 +230,61 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
         DynamicObject scoreItemSub = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMSUB));
         DynamicObject scoreItemSub = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMSUB));
         DynamicObject scoreItemRank = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMRANK));
         DynamicObject scoreItemRank = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMRANK));
 
 
+
+        if (date != null && scoreItem != null && scoreItemSub != null) {
+
+            DynamicObjectCollection entryEntity = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
+            String scoreItemNumber = scoreItem.getString(FormConstant.NUMBER_KEY);
+            if(ScoreItemEnum.RESEARCH_SCORE.getCode().equalsIgnoreCase(scoreItemNumber)){
+                if(scoreItemRank != null) {
+                    //科研与创新需要需要匹配积分规则
+                    QFilter filter = new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM), QCP.equals, scoreItem.getLong(FormConstant.ID_KEY))
+                            .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB), QCP.equals, scoreItemSub.getLong(FormConstant.ID_KEY)))
+                            .and(new QFilter(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMRANK), QCP.equals, scoreItemRank.getLong(FormConstant.ID_KEY)));
+                    Map<String, BigDecimal> scoreConf = ContributionHelper.getScoreConf(filter);
+                    String key = scoreItem.getLong(FormConstant.ID_KEY)+"-"+scoreItemSub.getLong(FormConstant.ID_KEY)+"-"+scoreItemRank.getLong(FormConstant.ID_KEY);
+                    for (int i = 0; i < entryEntity.size(); i++) {
+                        DynamicObject entry = entryEntity.get(i);
+                        BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
+                        BigDecimal validScore = oriScore;
+                        if(!scoreConf.isEmpty() && scoreConf.containsKey(key)){
+                            BigDecimal maxScore = scoreConf.get(key);
+                            if (maxScore != null && oriScore != null) {
+                                validScore = oriScore.compareTo(maxScore) > 0 ? maxScore : oriScore;
+                            } else {
+                                // 根据业务需求处理 null 值情况
+                                validScore = oriScore != null ? oriScore : BigDecimal.ZERO;
+                            }
+                        }
+                        this.getModel().setValue(ContributionConstant.NCKD_SCORE, validScore, i);
+                    }
+                }
+            }else{
+                for (int i = 0; i < entryEntity.size(); i++) {
+                    DynamicObject entry = entryEntity.get(i);
+                    BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
+                    this.getModel().setValue(ContributionConstant.NCKD_SCORE, oriScore, i);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 处理表头字段变更
+     * 表头变更则重新计算所有分录(已维护人员和原积分的数据)的积分
+     * @param
+     * @return: void
+     * @author W.Y.C
+     * @date: 2025/10/26 19:47
+     */
+    private void handleHeadFieldChange1() {
+        Long id = ConvertUtil.toLong(this.getModel().getValue(FormConstant.ID_KEY));
+        Date date = ConvertUtil.toDate(this.getModel().getValue(ContributionConstant.NCKD_YEAR));
+        DynamicObject scoreItem = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEM));
+        DynamicObject scoreItemSub = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMSUB));
+        DynamicObject scoreItemRank = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEMRANK));
+
         if (date != null && scoreItem != null && scoreItemSub != null) {
         if (date != null && scoreItem != null && scoreItemSub != null) {
             //重置分录所有分录的"录用积分"字段
             //重置分录所有分录的"录用积分"字段
             DynamicObjectCollection entryEntity = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
             DynamicObjectCollection entryEntity = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);

+ 16 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/adjust/NewDynamicAdjustmentOperationPlugIn.java

@@ -2,11 +2,15 @@ package nckd.jxccl.hr.psms.plugin.operate.adjust;
 
 
 import kd.bos.common.enums.EnableEnum;
 import kd.bos.common.enums.EnableEnum;
 import kd.bos.context.RequestContext;
 import kd.bos.context.RequestContext;
+import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.CloneUtils;
 import kd.bos.dataentity.entity.CloneUtils;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.utils.ObjectUtils;
 import kd.bos.entity.ExtendedDataEntity;
 import kd.bos.entity.ExtendedDataEntity;
 import kd.bos.entity.constant.StatusEnum;
 import kd.bos.entity.constant.StatusEnum;
+import kd.bos.entity.operate.result.IOperateInfo;
+import kd.bos.entity.operate.result.OperationResult;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.AddValidatorsEventArgs;
 import kd.bos.entity.plugin.AddValidatorsEventArgs;
 import kd.bos.entity.plugin.args.BeforeOperationArgs;
 import kd.bos.entity.plugin.args.BeforeOperationArgs;
@@ -175,7 +179,18 @@ public class NewDynamicAdjustmentOperationPlugIn extends AbstractOperationServic
 
 
         }
         }
 
 
-        SaveServiceHelper.save(newPersonPosFiles.toArray(new DynamicObject[0]));
+//        SaveServiceHelper.save(newPersonPosFiles.toArray(new DynamicObject[0]));
+        OperationResult operationResult = SaveServiceHelper.saveOperate(PositionStructureConstant.PERSONPOSFILE_ENTITYID, newPersonPosFiles.toArray(new DynamicObject[0]), OperateOption.create());
+        if (!operationResult.isSuccess()) {
+            StringJoiner errorMsg = new StringJoiner("\n");
+            for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
+                errorMsg.add(error.getMessage());
+            }
+            if (!ObjectUtils.isEmpty(operationResult.getMessage())) {
+                errorMsg.add(operationResult.getMessage());
+            }
+            throw new ValidationException("保存职位档案失败,原因:" + errorMsg.toString());
+        }
         PositionFileHelper.markAsNotCurrentNewest(personIds.toArray(new Long[0]));
         PositionFileHelper.markAsNotCurrentNewest(personIds.toArray(new Long[0]));
         PositionFileHelper.markAsCurrentNewest(null,personIds.toArray(new Long[0]));
         PositionFileHelper.markAsCurrentNewest(null,personIds.toArray(new Long[0]));
 
 

+ 18 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/annualadjust/AnnualAdjustmentOperationPlugin.java

@@ -1,9 +1,13 @@
 package nckd.jxccl.hr.psms.plugin.operate.annualadjust;
 package nckd.jxccl.hr.psms.plugin.operate.annualadjust;
 
 
 import kd.bos.common.enums.EnableEnum;
 import kd.bos.common.enums.EnableEnum;
+import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.utils.ObjectUtils;
 import kd.bos.entity.ExtendedDataEntity;
 import kd.bos.entity.ExtendedDataEntity;
+import kd.bos.entity.operate.result.IOperateInfo;
+import kd.bos.entity.operate.result.OperationResult;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.AddValidatorsEventArgs;
 import kd.bos.entity.plugin.AddValidatorsEventArgs;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
@@ -16,6 +20,7 @@ import kd.bos.servicehelper.operation.SaveServiceHelper;
 import kd.sdk.plugin.Plugin;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.enums.psms.AdjustTypeEnum;
 import nckd.jxccl.base.common.enums.psms.AdjustTypeEnum;
+import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.base.pm.helper.PerformanceManagerHelper;
 import nckd.jxccl.base.pm.helper.PerformanceManagerHelper;
@@ -33,6 +38,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
+import java.util.StringJoiner;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.Stream;
 
 
@@ -176,7 +182,18 @@ public class AnnualAdjustmentOperationPlugin extends AbstractOperationServicePlu
             }
             }
         }
         }
 
 
-        SaveServiceHelper.save(newPersonPosFiles.toArray(new DynamicObject[0]));
+//        SaveServiceHelper.save(newPersonPosFiles.toArray(new DynamicObject[0]));
+        OperationResult operationResult = SaveServiceHelper.saveOperate(PositionStructureConstant.PERSONPOSFILE_ENTITYID, newPersonPosFiles.toArray(new DynamicObject[0]), OperateOption.create());
+        if (!operationResult.isSuccess()) {
+            StringJoiner errorMsg = new StringJoiner("\n");
+            for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
+                errorMsg.add(error.getMessage());
+            }
+            if (!ObjectUtils.isEmpty(operationResult.getMessage())) {
+                errorMsg.add(operationResult.getMessage());
+            }
+            throw new ValidationException("保存职位档案失败,原因:" + errorMsg.toString());
+        }
         PositionFileHelper.markAsNotCurrentNewest(personIds.toArray(new Long[0]));
         PositionFileHelper.markAsNotCurrentNewest(personIds.toArray(new Long[0]));
         PositionFileHelper.markAsCurrentNewest(null,personIds.toArray(new Long[0]));
         PositionFileHelper.markAsCurrentNewest(null,personIds.toArray(new Long[0]));
         for (DynamicObject newPersonPosFile : newPersonPosFiles) {
         for (DynamicObject newPersonPosFile : newPersonPosFiles) {

+ 1 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/annualadjust/AnnualLockOrUnLockedOpPlugin.java

@@ -149,6 +149,7 @@ public class AnnualLockOrUnLockedOpPlugin extends AbstractOperationServicePlugIn
                 for (DynamicObject dynamicObject : load) {
                 for (DynamicObject dynamicObject : load) {
                     DynamicObject entryObj = new DynamicObject(entryType);
                     DynamicObject entryObj = new DynamicObject(entryType);
                     entryObj.set(PositionStructureConstant.NCKD_PERSONPOSFILE, dynamicObject);
                     entryObj.set(PositionStructureConstant.NCKD_PERSONPOSFILE, dynamicObject);
+                    entryObj.set(PositionStructureConstant.NCKD_ORG, dynamicObject.getDynamicObject(FormConstant.NCKD_DEP).getDynamicObject(FormConstant.BELONGCOMPANY_KEY));
                     entryColl.add(entryObj);
                     entryColl.add(entryObj);
                 }
                 }
                 //提交单据
                 //提交单据

+ 27 - 2
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/ContribBillOpPlugin.java

@@ -16,6 +16,7 @@ import kd.bos.entity.validate.ErrorLevel;
 import kd.bos.form.MessageBoxResult;
 import kd.bos.form.MessageBoxResult;
 import kd.sdk.plugin.Plugin;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.enums.psms.ScoreItemEnum;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.hr.psms.common.ContributionConstant;
 import nckd.jxccl.hr.psms.common.ContributionConstant;
@@ -26,6 +27,7 @@ import java.math.RoundingMode;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.Date;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Objects;
 
 
 /**
 /**
@@ -46,6 +48,7 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
             @Override
             @Override
             public void validate() {
             public void validate() {
                 //校验参与人数
                 //校验参与人数
+                Map<String, BigDecimal> scoreConf = ContributionHelper.getScoreConf();
                 for (ExtendedDataEntity dataEntity : this.getDataEntities()) {
                 for (ExtendedDataEntity dataEntity : this.getDataEntities()) {
                     DynamicObject data = dataEntity.getDataEntity();
                     DynamicObject data = dataEntity.getDataEntity();
                     int participants = data.getInt(ContributionConstant.NCKD_PARTICIPANTS);
                     int participants = data.getInt(ContributionConstant.NCKD_PARTICIPANTS);
@@ -62,7 +65,29 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
                             DynamicObject scoreItem = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEM);
                             DynamicObject scoreItem = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEM);
                             DynamicObject scoreItemSub = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEMSUB);
                             DynamicObject scoreItemSub = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEMSUB);
                             DynamicObject scoreItemRank = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEMRANK);
                             DynamicObject scoreItemRank = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEMRANK);
-                            List<ContributionHelper.ScoreItemValidScore> scoreItemValidScoreList = new ArrayList<>(entryEntity.size());
+                            String scoreItemNumber = scoreItem.getString(FormConstant.NUMBER_KEY);
+                            if(ScoreItemEnum.RESEARCH_SCORE.getCode().equalsIgnoreCase(scoreItemNumber)){
+                                String key = scoreItem.getLong(FormConstant.ID_KEY)+"-"+scoreItemSub.getLong(FormConstant.ID_KEY)+"-"+scoreItemRank.getLong(FormConstant.ID_KEY);
+                                if(!scoreConf.isEmpty() && scoreConf.containsKey(key)){
+                                    BigDecimal maxScore = scoreConf.get(key);
+                                    for (DynamicObject entry : entryEntity) {
+                                        DynamicObject person = entry.getDynamicObject(ContributionConstant.NCKD_PERSON);
+                                        long personId = person.getLong(FormConstant.ID_KEY);
+                                        BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
+                                        BigDecimal score = entry.getBigDecimal(ContributionConstant.NCKD_SCORE);
+                                        if(oriScore.compareTo(maxScore) > 0) {
+                                            this.addFatalErrorMessage(dataEntity, StrFormatter.format("参与人【{}】的原始分数【{}】超出限制积分【{}】。请重新填写“原始积分”,系统将会自动重算“录入积分”;",
+                                                    person.getString(FormConstant.NAME_KEY),
+                                                    oriScore.setScale(2, RoundingMode.HALF_UP),
+                                                    maxScore.setScale(2, RoundingMode.HALF_UP)));
+                                        }
+                                    }
+
+                                }
+                            }
+
+
+                           /* List<ContributionHelper.ScoreItemValidScore> scoreItemValidScoreList = new ArrayList<>(entryEntity.size());
                             for (DynamicObject entry : entryEntity) {
                             for (DynamicObject entry : entryEntity) {
                                 DynamicObject person = entry.getDynamicObject(ContributionConstant.NCKD_PERSON);
                                 DynamicObject person = entry.getDynamicObject(ContributionConstant.NCKD_PERSON);
                                 BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
                                 BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
@@ -94,7 +119,7 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
                                         }
                                         }
                                     }
                                     }
                                 }
                                 }
-                            }
+                            }*/
                         }
                         }
                     }
                     }
                 }
                 }

+ 129 - 10
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/file/PersonPosFileSaveOpPlugin.java

@@ -3,34 +3,36 @@ package nckd.jxccl.hr.psms.plugin.operate.file;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.entity.EntityMetadataCache;
 import kd.bos.entity.EntityMetadataCache;
-import kd.bos.entity.ExtendedDataEntity;
 import kd.bos.entity.MainEntityType;
 import kd.bos.entity.MainEntityType;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
-import kd.bos.entity.plugin.AddValidatorsEventArgs;
-import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
-import kd.bos.entity.validate.AbstractValidator;
+import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.QueryServiceHelper;
 import kd.bos.servicehelper.QueryServiceHelper;
 import kd.sdk.plugin.Plugin;
 import kd.sdk.plugin.Plugin;
+import kd.sdk.swc.hcdm.business.helper.HCDMSalaryStdServiceHelper;
+import kd.sdk.swc.hcdm.common.dto.stdtab.match.StdTableDataMatchParam;
+import kd.sdk.swc.hcdm.common.dto.stdtab.match.StdTableDataMatchResult;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
 import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
-import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
-import nckd.jxccl.base.common.utils.StrFormatter;
-import nckd.jxccl.base.org.helper.OrgHelper;
+import nckd.jxccl.base.swc.helper.AdjFileServiceHelper;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 
 
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.Date;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
-import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 
 /**
 /**
-* 员工职位档案
+* 员工职位档案-保存
 * 实体标识:nckd_personposfile
 * 实体标识:nckd_personposfile
 * @author W.Y.C
 * @author W.Y.C
 * @date 2025/12/4 19:36
 * @date 2025/12/4 19:36
@@ -38,4 +40,121 @@ import java.util.stream.Collectors;
 */
 */
 public class PersonPosFileSaveOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
 public class PersonPosFileSaveOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
 
 
+    protected final static Log logger = LogFactory.getLog(PersonPosFileSaveOpPlugin.class);
+
+
+
+    @Override
+    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+
+        //职位津贴=职位系数 X 所在岗级岗位工资一档金额
+        List<Long> allPersonIds = new ArrayList<>(e.getDataEntities().length);
+        List<Long> jobLevelIds = new ArrayList<>(e.getDataEntities().length);
+        for (DynamicObject dataEntity : e.getDataEntities()) {
+            String typeState = dataEntity.getString(PositionStructureConstant.NCKD_TYPESTATE);
+            if(Arrays.asList(TypeStateEnum.NEW_ENTRY.getCode(), TypeStateEnum.IN_SERVICE_LEVEL.getCode(), TypeStateEnum.ANNUAL_ADJUSTMENT.getCode(), TypeStateEnum.POSITION_TRANSFER.getCode()).contains(typeState)){
+                //只有新入职、在职人员初定、年度调整、动态调整才要获取薪酬
+                BigDecimal coefficient = dataEntity.getBigDecimal(PositionStructureConstant.NCKD_COEFFICIENT);
+                BigDecimal currentPostSalary = dataEntity.getBigDecimal(PositionStructureConstant.NCKD_CURRENTPOSTSALARY);
+                BigDecimal postAllowance = dataEntity.getBigDecimal(PositionStructureConstant.NCKD_POSTALLOWANCE);
+                //当职位系数、岗位工资一档金额、岗位津贴为0时才处理,不为空则跳过
+                if((coefficient == null || coefficient.compareTo(BigDecimal.ZERO) <= 0) && (currentPostSalary == null || currentPostSalary.compareTo(BigDecimal.ZERO) <= 0) && (postAllowance == null || postAllowance.compareTo(BigDecimal.ZERO) <= 0)){
+                    long personId = dataEntity.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
+                    if(personId > 0){
+                        allPersonIds.add(personId);
+                    }
+                    long jobLevelId = dataEntity.getLong(String.join(".", PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.ID_KEY));
+                    jobLevelIds.add(jobLevelId);
+                }
+            }
+        }
+
+        //====================================== 获取当前人员所在定调的岗位标准工资一档金额 begin ======================================
+        Map<Long, BigDecimal> amountMap = new HashMap<>(e.getDataEntities().length);
+        if(!allPersonIds.isEmpty() && !jobLevelIds.isEmpty()) {
+            //获取人员最新岗位工资标准定薪记录
+            List<AdjFileServiceHelper.SalaryAdjustmentResult> salaryAdjustmentResultList = AdjFileServiceHelper.getLastDecAdjRecords(allPersonIds, FormConstant.STANDARDITEM_ID_KEY);
+            if (!salaryAdjustmentResultList.isEmpty()) {
+                //薪酬标准ID
+                List<Long> salaryStIds = salaryAdjustmentResultList.stream().map(result -> result.salaryStDv.getLong(FormConstant.ID_KEY)).collect(Collectors.toList());
+                QFilter filter = new QFilter(FormConstant.ID_KEY, QCP.in, salaryStIds)
+                        .and(String.join(".", "rankentry", "rank", FormConstant.NUMBER_KEY), QCP.equals, "01");
+                //获取标准表中01档的薪档
+                QueryFieldBuilder salaryStandFieldBuilder = QueryFieldBuilder.create()
+                        .add(FormConstant.ID_KEY)
+                        .addIdNumberNameWithExtras(new String[]{"rankentry", "rank"},FormConstant.INDEX_KEY);
+                DynamicObjectCollection salaryStandardColl = QueryServiceHelper.query("hcdm_salarystandard", salaryStandFieldBuilder.buildSelect(), new QFilter[]{filter});
+                Map<Long, DynamicObject> salaryStandardMap = salaryStandardColl.stream()
+                        .collect(Collectors.toMap(
+                                obj -> obj.getLong(FormConstant.ID_KEY),
+                                obj -> obj
+                        ));
+
+                if (!salaryStandardMap.isEmpty()) {
+                    List<StdTableDataMatchParam> matchParams = new ArrayList<>();
+                    for (AdjFileServiceHelper.SalaryAdjustmentResult result : salaryAdjustmentResultList) {
+                        StdTableDataMatchParam stdTableDataMatchParam = new StdTableDataMatchParam();
+                        stdTableDataMatchParam.setStdTableId(result.salaryStDv.getLong(FormConstant.ID_KEY));
+                        stdTableDataMatchParam.setStdItemId(FormConstant.STANDARDITEM_ID_KEY);
+                        stdTableDataMatchParam.setGradeId(result.salaryGrade.getLong(FormConstant.ID_KEY));
+                        DynamicObject dynamicObject = salaryStandardMap.get(result.salaryStDv.getLong(FormConstant.ID_KEY));
+                        if(dynamicObject != null) {
+                            long rankId = dynamicObject.getLong(String.join(".", "rankentry", "rank", FormConstant.ID_KEY));
+                            stdTableDataMatchParam.setRankId(rankId);
+                            matchParams.add(stdTableDataMatchParam);
+                        }
+                    }
+                    if(!matchParams.isEmpty()) {
+                        //获取薪酬项目、薪等、薪档对应金额(入参params的数组下标和出参的数组下标一一对应)
+                        List<StdTableDataMatchResult> stdTableDataMatchResults = HCDMSalaryStdServiceHelper.matchStdTableData(matchParams);
+                        for (int i = 0; i < salaryAdjustmentResultList.size(); i++) {
+                            AdjFileServiceHelper.SalaryAdjustmentResult result = salaryAdjustmentResultList.get(i);
+                            if (i < stdTableDataMatchResults.size() && stdTableDataMatchResults.get(i) != null) {
+                                //当前薪等01档的金额
+                                amountMap.put(result.employee.getLong(FormConstant.ID_KEY), stdTableDataMatchResults.get(i).getAmount());
+                            }
+                        }
+                    }
+                } else {
+                    logger.warn("未获取薪酬标准表中01档的薪档数据,薪酬标准ID:{}",salaryStIds);
+                }
+            } else {
+                logger.warn("未获取到人员岗位工资标准定薪记录,人员ID:{}",allPersonIds);
+            }
+        }
+        //====================================== 获取当前人员所在定调的岗位标准工资一档金额 end ======================================
+        Map<Long, DynamicObject> jobLevelMap = new HashMap<>(e.getDataEntities().length);
+        if(!jobLevelIds.isEmpty()) {
+            MainEntityType jobLevelEntityType = EntityMetadataCache.getDataEntityType(FormConstant.HBJM_JOBLEVELHR);
+            //重新加载职级信息,避免获取不到系数
+            DynamicObject[] load = BusinessDataServiceHelper.load(jobLevelIds.toArray(new Long[0]), jobLevelEntityType);
+            jobLevelMap = Arrays.stream(load)
+                    .collect(Collectors.toMap(
+                            obj -> obj.getLong(FormConstant.ID_KEY),
+                            obj -> obj
+                    ));
+        }
+
+        for (DynamicObject dataEntity : e.getDataEntities()) {
+            long jobLevelId = dataEntity.getLong(String.join(".", PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.ID_KEY));
+            DynamicObject jobLevel = jobLevelMap.get(jobLevelId);
+            if(jobLevel != null){
+                DynamicObject person = dataEntity.getDynamicObject(FormConstant.NCKD_PERSON);
+                long personId = person.getLong(FormConstant.ID_KEY);
+                //当前岗位工资01档金额
+                BigDecimal amount = amountMap.get(personId);
+                if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0) {
+                    BigDecimal coefficient = jobLevel.getBigDecimal(PositionStructureConstant.NCKD_COEFFICIENT);
+                    if(coefficient.compareTo(BigDecimal.ZERO) > 0) {
+                        dataEntity.set(PositionStructureConstant.NCKD_COEFFICIENT, coefficient);
+                        dataEntity.set(PositionStructureConstant.NCKD_CURRENTPOSTSALARY, amount);
+                        dataEntity.set(PositionStructureConstant.NCKD_POSTALLOWANCE, coefficient.multiply(amount));
+                    }
+                } else {
+                    logger.warn("未获取到员工【{}】最新岗位工资标准定薪记录01档的薪等金额,人员ID:", person.getString(FormConstant.NAME_KEY));
+                }
+            }
+        }
+    }
+
 }
 }

+ 85 - 10
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/BaseInitialOperationPlugIn.java

@@ -3,9 +3,13 @@ package nckd.jxccl.hr.psms.plugin.operate.initial;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
 import kd.bos.common.enums.EnableEnum;
 import kd.bos.common.enums.EnableEnum;
 import kd.bos.context.RequestContext;
 import kd.bos.context.RequestContext;
+import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.utils.ObjectUtils;
 import kd.bos.entity.constant.StatusEnum;
 import kd.bos.entity.constant.StatusEnum;
+import kd.bos.entity.operate.result.IOperateInfo;
+import kd.bos.entity.operate.result.OperationResult;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.logging.Log;
 import kd.bos.logging.Log;
 import kd.bos.logging.LogFactory;
 import kd.bos.logging.LogFactory;
@@ -15,6 +19,7 @@ import kd.bos.servicehelper.operation.SaveServiceHelper;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.enums.AppraisalResultEnum;
 import nckd.jxccl.base.common.enums.AppraisalResultEnum;
 import nckd.jxccl.base.common.enums.psms.JobSeqEnum;
 import nckd.jxccl.base.common.enums.psms.JobSeqEnum;
+import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.base.common.utils.StrFormatter;
@@ -32,6 +37,7 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.StringJoiner;
 
 
 /**
 /**
  * 人员初定操作插件基类
  * 人员初定操作插件基类
@@ -118,75 +124,101 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
      * @date: 2025/10/12 14:20
      * @date: 2025/10/12 14:20
      */
      */
     protected List<BaseInitialData> extractBasicInfo(DynamicObject initialData) {
     protected List<BaseInitialData> extractBasicInfo(DynamicObject initialData) {
+        logger.info("【职位体系】-开始提取基本信息");
         List<BaseInitialData> dataList = new ArrayList<>();
         List<BaseInitialData> dataList = new ArrayList<>();
         if(initialData.containsProperty(FormConstant.NCKD_ENTRYENTITY)){
         if(initialData.containsProperty(FormConstant.NCKD_ENTRYENTITY)){
             DynamicObjectCollection dynamicObjectCollection = initialData.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
             DynamicObjectCollection dynamicObjectCollection = initialData.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
-            for (DynamicObject dynamicObject : dynamicObjectCollection) {
+            logger.info("【职位体系】-检测到批量初定数据,条数: {}", dynamicObjectCollection.size());
+            for (int i = 0; i < dynamicObjectCollection.size(); i++) {
+                DynamicObject dynamicObject = dynamicObjectCollection.get(i);
+                logger.info("【职位体系】-处理第 {} 条数据", i+1);
                 //批量初定
                 //批量初定
                 BaseInitialData data = getBaseInitialData(dynamicObject);
                 BaseInitialData data = getBaseInitialData(dynamicObject);
                 dataList.add(data);
                 dataList.add(data);
                 baseInitialData.add(data);
                 baseInitialData.add(data);
             }
             }
         }else{
         }else{
+            logger.info("【职位体系】-处理单条初定数据");
             BaseInitialData data = getBaseInitialData(initialData);
             BaseInitialData data = getBaseInitialData(initialData);
             dataList.add(data);
             dataList.add(data);
             baseInitialData.add(data);
             baseInitialData.add(data);
         }
         }
+        logger.info("【职位体系】-基本信息提取完成,共提取 {} 条数据", dataList.size());
         return dataList;
         return dataList;
     }
     }
 
 
     @NotNull
     @NotNull
     private BaseInitialData getBaseInitialData(DynamicObject initialData) {
     private BaseInitialData getBaseInitialData(DynamicObject initialData) {
         BaseInitialData data = new BaseInitialData();
         BaseInitialData data = new BaseInitialData();
+        logger.info("【职位体系】-开始获取基础数据");
 
 
         data.beginDate = initialData.getDate(PositionStructureConstant.NCKD_BEGINDATE);
         data.beginDate = initialData.getDate(PositionStructureConstant.NCKD_BEGINDATE);
         data.causeRemark = initialData.getString(PositionStructureConstant.KEY_NCKD_CAUSEREMARK);
         data.causeRemark = initialData.getString(PositionStructureConstant.KEY_NCKD_CAUSEREMARK);
         data.person = initialData.getDynamicObject(PositionStructureConstant.NCKD_PERSON);
         data.person = initialData.getDynamicObject(PositionStructureConstant.NCKD_PERSON);
 
 
         PositionAppointmentBO positionAppointment = PositionFileHelper.positionAppointmentQuery(data.person.getLong(FormConstant.ID_KEY), data.beginDate);
         PositionAppointmentBO positionAppointment = PositionFileHelper.positionAppointmentQuery(data.person.getLong(FormConstant.ID_KEY), data.beginDate);
+        logger.info("【职位体系】-获取人员任职信息完成,personId={}", data.person.getLong(FormConstant.ID_KEY));
+        
         // 学历
         // 学历
         DynamicObject perEduExp = positionAppointment.getPerEduExp();
         DynamicObject perEduExp = positionAppointment.getPerEduExp();
         if (perEduExp != null) {
         if (perEduExp != null) {
             // 学历
             // 学历
             long diplomaId = perEduExp.getLong(String.join(".", FormConstant.EDUCATION_KEY, FormConstant.ID_KEY));
             long diplomaId = perEduExp.getLong(String.join(".", FormConstant.EDUCATION_KEY, FormConstant.ID_KEY));
+            logger.info("【职位体系】-获取学历信息,diplomaId={}", diplomaId);
             if(diplomaId > 0) {
             if(diplomaId > 0) {
                 DynamicObject diploma = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_DIPLOMA);
                 DynamicObject diploma = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_DIPLOMA);
                 diploma.set(FormConstant.ID_KEY, diplomaId);
                 diploma.set(FormConstant.ID_KEY, diplomaId);
                 data.diploma = diploma;
                 data.diploma = diploma;
             }
             }
+        } else {
+            logger.info("【职位体系】-无学历信息");
         }
         }
+        
         // 职称信息
         // 职称信息
         DynamicObject perProTitle = positionAppointment.getPerProTitle();
         DynamicObject perProTitle = positionAppointment.getPerProTitle();
         if (perProTitle != null) {
         if (perProTitle != null) {
             data.rankName = perProTitle.getString(String.join(".", FormConstant.PROFESSIONAL_KEY, FormConstant.NAME_KEY));
             data.rankName = perProTitle.getString(String.join(".", FormConstant.PROFESSIONAL_KEY, FormConstant.NAME_KEY));
+            logger.info("【职位体系】-获取职称信息,rankName={}", data.rankName);
+            
             // 职称等级
             // 职称等级
             long perProTitleId = perProTitle.getLong(String.join(".", FormConstant.PROLEVEL_KEY, FormConstant.ID_KEY));
             long perProTitleId = perProTitle.getLong(String.join(".", FormConstant.PROLEVEL_KEY, FormConstant.ID_KEY));
+            logger.info("【职位体系】-获取职称等级,perProTitleId={}", perProTitleId);
             if(perProTitleId > 0) {
             if(perProTitleId > 0) {
                 DynamicObject proTitleLevel = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_PROTITLELEVEL);
                 DynamicObject proTitleLevel = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_PROTITLELEVEL);
                 proTitleLevel.set(FormConstant.ID_KEY, perProTitleId);
                 proTitleLevel.set(FormConstant.ID_KEY, perProTitleId);
                 data.proTitleLevel = proTitleLevel;
                 data.proTitleLevel = proTitleLevel;
             }
             }
+        } else {
+            logger.info("【职位体系】-无职称信息");
         }
         }
 
 
         // 技能信息
         // 技能信息
         DynamicObject perOcpQual = positionAppointment.getPerOcpQual();
         DynamicObject perOcpQual = positionAppointment.getPerOcpQual();
         if (perOcpQual != null) {
         if (perOcpQual != null) {
             data.jobStatusName = perOcpQual.getString(String.join(".", FormConstant.QUALIFICATION_KEY, FormConstant.NAME_KEY));
             data.jobStatusName = perOcpQual.getString(String.join(".", FormConstant.QUALIFICATION_KEY, FormConstant.NAME_KEY));
+            logger.info("【职位体系】-获取技能信息,jobStatusName={}", data.jobStatusName);
+            
             // 技能等级
             // 技能等级
             long quaLevelId = perOcpQual.getLong(String.join(".", FormConstant.QUALEVEL_KEY, FormConstant.ID_KEY));
             long quaLevelId = perOcpQual.getLong(String.join(".", FormConstant.QUALEVEL_KEY, FormConstant.ID_KEY));
+            logger.info("【职位体系】-获取技能等级,quaLevelId={}", quaLevelId);
             if(quaLevelId > 0) {
             if(quaLevelId > 0) {
                 DynamicObject ocpQualLevel = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_OCPQUALLEVEL);
                 DynamicObject ocpQualLevel = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_OCPQUALLEVEL);
                 ocpQualLevel.set(FormConstant.ID_KEY, quaLevelId);
                 ocpQualLevel.set(FormConstant.ID_KEY, quaLevelId);
                 data.ocpQualLevel = ocpQualLevel;
                 data.ocpQualLevel = ocpQualLevel;
             }
             }
-
+        } else {
+            logger.info("【职位体系】-无技能信息");
         }
         }
+        
         // 任职信息
         // 任职信息
         DynamicObject empPosOrgRel = positionAppointment.getEmpPosOrgRel();
         DynamicObject empPosOrgRel = positionAppointment.getEmpPosOrgRel();
         if (empPosOrgRel != null) {
         if (empPosOrgRel != null) {
             data.empPosOrgRel = empPosOrgRel;
             data.empPosOrgRel = empPosOrgRel;
+            logger.info("【职位体系】-获取任职信息完成");
+            
             //岗位
             //岗位
             long positionId = empPosOrgRel.getLong(String.join(".", FormConstant.POSITION_KEY, FormConstant.ID_KEY));
             long positionId = empPosOrgRel.getLong(String.join(".", FormConstant.POSITION_KEY, FormConstant.ID_KEY));
+            logger.info("【职位体系】-获取岗位信息,positionId={}", positionId);
             if(positionId > 0) {
             if(positionId > 0) {
                 DynamicObject position = BusinessDataServiceHelper.newDynamicObject(FormConstant.HBPM_POSITIONHR);
                 DynamicObject position = BusinessDataServiceHelper.newDynamicObject(FormConstant.HBPM_POSITIONHR);
                 position.set(FormConstant.ID_KEY, positionId);
                 position.set(FormConstant.ID_KEY, positionId);
@@ -195,12 +227,15 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
             }
             }
 
 
             long companyId = empPosOrgRel.getLong(String.join(".", FormConstant.COMPANY_KEY, FormConstant.ID_KEY));
             long companyId = empPosOrgRel.getLong(String.join(".", FormConstant.COMPANY_KEY, FormConstant.ID_KEY));
+            logger.info("【职位体系】-获取公司信息,companyId={}", companyId);
             if(companyId > 0) {
             if(companyId > 0) {
                 DynamicObject company = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORG_ENTITYID);
                 DynamicObject company = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORG_ENTITYID);
                 company.set(FormConstant.ID_KEY, companyId);
                 company.set(FormConstant.ID_KEY, companyId);
                 data.company = company;
                 data.company = company;
             }
             }
+            
             long adminOrgId = empPosOrgRel.getLong(String.join(".", FormConstant.ADMINORG, FormConstant.ID_KEY));
             long adminOrgId = empPosOrgRel.getLong(String.join(".", FormConstant.ADMINORG, FormConstant.ID_KEY));
+            logger.info("【职位体系】-获取部门信息,adminOrgId={}", adminOrgId);
             if(adminOrgId > 0) {
             if(adminOrgId > 0) {
                 DynamicObject dep = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORG_ENTITYID);
                 DynamicObject dep = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORG_ENTITYID);
                 dep.set(FormConstant.ID_KEY, adminOrgId);
                 dep.set(FormConstant.ID_KEY, adminOrgId);
@@ -209,6 +244,7 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
 
 
             // 职位序列
             // 职位序列
             Long jobSeqId = empPosOrgRel.getLong(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.ID_KEY));
             Long jobSeqId = empPosOrgRel.getLong(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.ID_KEY));
+            logger.info("【职位体系】-获取职位序列信息,jobSeqId={}", jobSeqId);
             if(jobSeqId > 0) {
             if(jobSeqId > 0) {
                 String jobSeqNumber = empPosOrgRel.getString(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.NUMBER_KEY));
                 String jobSeqNumber = empPosOrgRel.getString(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.NUMBER_KEY));
                 String jobSeqName = empPosOrgRel.getString(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.NAME_KEY));
                 String jobSeqName = empPosOrgRel.getString(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.NAME_KEY));
@@ -220,20 +256,25 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
                 data.jobSeqNumber = jobSeqNumber;
                 data.jobSeqNumber = jobSeqNumber;
                 data.jobSeqName = jobSeqName;
                 data.jobSeqName = jobSeqName;
                 data.jobSeqEnum = JobSeqEnum.getByCode(data.jobSeqNumber);
                 data.jobSeqEnum = JobSeqEnum.getByCode(data.jobSeqNumber);
+                logger.info("【职位体系】-职位序列编号={},名称={}", jobSeqNumber, jobSeqName);
             }
             }
 
 
-
-
             //本次加入集团时间
             //本次加入集团时间
             data.joinComDate = empPosOrgRel.getDate(String.join(".", FormConstant.HRPI_PERSERLEN, FormConstant.JOINCOMDATE_KEY));
             data.joinComDate = empPosOrgRel.getDate(String.join(".", FormConstant.HRPI_PERSERLEN, FormConstant.JOINCOMDATE_KEY));
+            logger.info("【职位体系】-本次加入集团时间={}", data.joinComDate);
+        } else {
+            logger.info("【职位体系】-无任职信息");
         }
         }
 
 
         data.isExcellent = Boolean.FALSE;
         data.isExcellent = Boolean.FALSE;
         if(positionAppointment.getExcellent() != null && positionAppointment.getExcellent()){
         if(positionAppointment.getExcellent() != null && positionAppointment.getExcellent()){
             data.isExcellent = Boolean.TRUE;
             data.isExcellent = Boolean.TRUE;
+            logger.info("【职位体系】-该员工为优秀生");
         }
         }
+        
         // 特定字段由子类处理
         // 特定字段由子类处理
         extractSpecificFields(data, initialData);
         extractSpecificFields(data, initialData);
+        logger.info("【职位体系】-基础数据获取完成");
         return data;
         return data;
     }
     }
 
 
@@ -275,6 +316,7 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
      * 获取积分数据
      * 获取积分数据
      */
      */
     protected ScoreData getScoreData(BaseInitialData data, String logPrefix) {
     protected ScoreData getScoreData(BaseInitialData data, String logPrefix) {
+        logger.info("{}-开始获取积分数据", logPrefix);
         ScoreData scoreData = new ScoreData();
         ScoreData scoreData = new ScoreData();
 
 
         QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create().addIdNumberNameWithExtras(FormConstant.NCKD_SCORE);
         QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create().addIdNumberNameWithExtras(FormConstant.NCKD_SCORE);
@@ -282,6 +324,7 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
         // 学历积分
         // 学历积分
         scoreData.educationScore = BigDecimal.ZERO;
         scoreData.educationScore = BigDecimal.ZERO;
         if (data.diploma != null) {
         if (data.diploma != null) {
+            logger.info("{}-开始获取学历积分,diplomaId={}", logPrefix, data.diploma.getLong(FormConstant.ID_KEY));
             DynamicObject education = BusinessDataServiceHelper.loadSingle(FormConstant.HBSS_DIPLOMA,
             DynamicObject education = BusinessDataServiceHelper.loadSingle(FormConstant.HBSS_DIPLOMA,
                     queryFieldBuilder.buildSelect(),
                     queryFieldBuilder.buildSelect(),
                     new QFilter[]{QFilterCommonHelper.getIdEqFilter(data.diploma.getLong(FormConstant.ID_KEY))});
                     new QFilter[]{QFilterCommonHelper.getIdEqFilter(data.diploma.getLong(FormConstant.ID_KEY))});
@@ -302,30 +345,41 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
         scoreData.dbProTitleLevel = null;
         scoreData.dbProTitleLevel = null;
         scoreData.dbOcpQualLevel = null;
         scoreData.dbOcpQualLevel = null;
 
 
-
+        logger.info("{}-职位序列类型={}, proTitleLevel={}, ocpQualLevel={}", 
+                   logPrefix, data.jobSeqEnum, data.proTitleLevel, data.ocpQualLevel);
 
 
         if (data.jobSeqEnum != JobSeqEnum.SKILL && data.proTitleLevel != null) {
         if (data.jobSeqEnum != JobSeqEnum.SKILL && data.proTitleLevel != null) {
             // 非技能序列获取职称积分
             // 非技能序列获取职称积分
+            logger.info("{}-开始获取职称积分", logPrefix);
             scoreData.dbProTitleLevel = BusinessDataServiceHelper.loadSingle(FormConstant.HBSS_PROTITLELEVEL,
             scoreData.dbProTitleLevel = BusinessDataServiceHelper.loadSingle(FormConstant.HBSS_PROTITLELEVEL,
                     queryFieldBuilder.buildSelect(),
                     queryFieldBuilder.buildSelect(),
                     new QFilter[]{QFilterCommonHelper.getIdEqFilter(data.proTitleLevel.getLong(FormConstant.ID_KEY))});
                     new QFilter[]{QFilterCommonHelper.getIdEqFilter(data.proTitleLevel.getLong(FormConstant.ID_KEY))});
             if (scoreData.dbProTitleLevel != null) {
             if (scoreData.dbProTitleLevel != null) {
                 scoreData.proTitleScore = scoreData.dbProTitleLevel.getBigDecimal(FormConstant.NCKD_SCORE);
                 scoreData.proTitleScore = scoreData.dbProTitleLevel.getBigDecimal(FormConstant.NCKD_SCORE);
                 data.jobStatusName = null;
                 data.jobStatusName = null;
+                logger.info("{}-职称积分获取完成,积分为{}", logPrefix, scoreData.proTitleScore);
+            } else {
+                logger.warn("{}-未找到职称等级信息", logPrefix);
             }
             }
         } else if (data.jobSeqEnum == JobSeqEnum.SKILL && data.ocpQualLevel != null) {
         } else if (data.jobSeqEnum == JobSeqEnum.SKILL && data.ocpQualLevel != null) {
             // 技能序列获取技能积分
             // 技能序列获取技能积分
+            logger.info("{}-开始获取技能积分", logPrefix);
             scoreData.dbOcpQualLevel = BusinessDataServiceHelper.loadSingle(FormConstant.HBSS_OCPQUALLEVEL,
             scoreData.dbOcpQualLevel = BusinessDataServiceHelper.loadSingle(FormConstant.HBSS_OCPQUALLEVEL,
                     queryFieldBuilder.buildSelect(),
                     queryFieldBuilder.buildSelect(),
                     new QFilter[]{QFilterCommonHelper.getIdEqFilter(data.ocpQualLevel.getLong(FormConstant.ID_KEY))});
                     new QFilter[]{QFilterCommonHelper.getIdEqFilter(data.ocpQualLevel.getLong(FormConstant.ID_KEY))});
             if (scoreData.dbOcpQualLevel != null) {
             if (scoreData.dbOcpQualLevel != null) {
                 scoreData.perOcpQualScore = scoreData.dbOcpQualLevel.getBigDecimal(FormConstant.NCKD_SCORE);
                 scoreData.perOcpQualScore = scoreData.dbOcpQualLevel.getBigDecimal(FormConstant.NCKD_SCORE);
                 data.rankName = null;
                 data.rankName = null;
+                logger.info("{}-技能积分获取完成,积分为{}", logPrefix, scoreData.perOcpQualScore);
+            } else {
+                logger.warn("{}-未找到技能等级信息", logPrefix);
             }
             }
+        } else {
+            logger.info("{}-无需获取职称或技能积分", logPrefix);
         }
         }
 
 
-        logger.info("{}-初定职位序列【{}】-职称积分【{}】-技能积分【{}】",
-                logPrefix, data.jobSeqName, scoreData.proTitleScore, scoreData.perOcpQualScore);
+        logger.info("{}-初定职位序列【{}】-学历积分【{}】-职称积分【{}】-技能积分【{}】",
+                logPrefix, data.jobSeqName, scoreData.educationScore, scoreData.proTitleScore, scoreData.perOcpQualScore);
 
 
         return scoreData;
         return scoreData;
     }
     }
@@ -355,12 +409,15 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
     protected DynamicObject createAndSavePersonPosFile(BaseInitialData data, ScoreData scoreData,
     protected DynamicObject createAndSavePersonPosFile(BaseInitialData data, ScoreData scoreData,
                                              BigDecimal allSumScore, BigDecimal sumScore, 
                                              BigDecimal allSumScore, BigDecimal sumScore, 
                                              DynamicObject jobLeve, String logPrefix, String typeState) {
                                              DynamicObject jobLeve, String logPrefix, String typeState) {
+        logger.info("{}-开始创建并保存职位档案", logPrefix);
         // 优秀生得2分
         // 优秀生得2分
         BigDecimal excellentScore = data.isExcellent ? new BigDecimal(2) : BigDecimal.ZERO;
         BigDecimal excellentScore = data.isExcellent ? new BigDecimal(2) : BigDecimal.ZERO;
+        logger.info("{}-优秀生分数: {}", logPrefix, excellentScore);
 
 
         // 构建职位档案并存入数据库
         // 构建职位档案并存入数据库
         DynamicObject personPosFile = BusinessDataServiceHelper.newDynamicObject(
         DynamicObject personPosFile = BusinessDataServiceHelper.newDynamicObject(
                 PositionStructureConstant.PERSONPOSFILE_ENTITYID);
                 PositionStructureConstant.PERSONPOSFILE_ENTITYID);
+        logger.info("{}-创建职位档案对象完成", logPrefix);
 
 
         personPosFile.set(PositionStructureConstant.NCKD_PERSON, data.person);
         personPosFile.set(PositionStructureConstant.NCKD_PERSON, data.person);
         personPosFile.set(PositionStructureConstant.NCKD_FIRSTRANK, EnableEnum.YES.getCode());
         personPosFile.set(PositionStructureConstant.NCKD_FIRSTRANK, EnableEnum.YES.getCode());
@@ -380,18 +437,24 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
         personPosFile.set(PositionStructureConstant.NCKD_DEP, data.dep);
         personPosFile.set(PositionStructureConstant.NCKD_DEP, data.dep);
         personPosFile.set(PositionStructureConstant.NCKD_ALLSUMSCORE, allSumScore);
         personPosFile.set(PositionStructureConstant.NCKD_ALLSUMSCORE, allSumScore);
         personPosFile.set(PositionStructureConstant.NCKD_SUMSCORE, sumScore);
         personPosFile.set(PositionStructureConstant.NCKD_SUMSCORE, sumScore);
+        logger.info("{}-设置基本字段完成,总积分={}, 累计积分={}", logPrefix, allSumScore, sumScore);
 
 
         DynamicObject convertJobSeq = data.convertJobSeq;
         DynamicObject convertJobSeq = data.convertJobSeq;
         JobSeqEnum jobSeqEnum = JobSeqEnum.getByCode(convertJobSeq.getString(FormConstant.NUMBER_KEY));
         JobSeqEnum jobSeqEnum = JobSeqEnum.getByCode(convertJobSeq.getString(FormConstant.NUMBER_KEY));
+        logger.info("{}-转换后的职位序列类型={}", logPrefix, jobSeqEnum);
+        
         if(JobSeqEnum.SKILL == jobSeqEnum){
         if(JobSeqEnum.SKILL == jobSeqEnum){
             personPosFile.set(PositionStructureConstant.NCKD_JOBSTATUSNAME, data.jobStatusName);
             personPosFile.set(PositionStructureConstant.NCKD_JOBSTATUSNAME, data.jobStatusName);
             personPosFile.set(PositionStructureConstant.NCKD_OCPQUALLEVEL, scoreData.dbOcpQualLevel);
             personPosFile.set(PositionStructureConstant.NCKD_OCPQUALLEVEL, scoreData.dbOcpQualLevel);
             personPosFile.set(PositionStructureConstant.NCKD_JOBSTATUSSCORE, scoreData.perOcpQualScore);
             personPosFile.set(PositionStructureConstant.NCKD_JOBSTATUSSCORE, scoreData.perOcpQualScore);
+            logger.info("{}-设置技能序列相关信息完成", logPrefix);
         }else{
         }else{
             personPosFile.set(PositionStructureConstant.NCKD_RANKNAME, data.rankName);
             personPosFile.set(PositionStructureConstant.NCKD_RANKNAME, data.rankName);
             personPosFile.set(PositionStructureConstant.NCKD_PROTITLELEVEL, scoreData.dbProTitleLevel);
             personPosFile.set(PositionStructureConstant.NCKD_PROTITLELEVEL, scoreData.dbProTitleLevel);
             personPosFile.set(PositionStructureConstant.NCKD_RANKSCORE, scoreData.proTitleScore);
             personPosFile.set(PositionStructureConstant.NCKD_RANKSCORE, scoreData.proTitleScore);
+            logger.info("{}-设置非技能序列相关信息完成", logPrefix);
         }
         }
+        
         personPosFile.set(PositionStructureConstant.NCKD_JOBLEVELHR, jobLeve);
         personPosFile.set(PositionStructureConstant.NCKD_JOBLEVELHR, jobLeve);
         personPosFile.set(PositionStructureConstant.NCKD_DIPLOMA, data.diploma);
         personPosFile.set(PositionStructureConstant.NCKD_DIPLOMA, data.diploma);
         personPosFile.set(PositionStructureConstant.NCKD_TYPESTATE, typeState);
         personPosFile.set(PositionStructureConstant.NCKD_TYPESTATE, typeState);
@@ -405,9 +468,21 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
         personPosFile.set(PositionStructureConstant.STATUS, StatusEnum.C.toString());
         personPosFile.set(PositionStructureConstant.STATUS, StatusEnum.C.toString());
         personPosFile.set(PositionStructureConstant.ENABLE, EnableEnum.YES.getCode());
         personPosFile.set(PositionStructureConstant.ENABLE, EnableEnum.YES.getCode());
         personPosFile.set(PositionStructureConstant.CREATOR_KEY, RequestContext.get().getCurrUserId());
         personPosFile.set(PositionStructureConstant.CREATOR_KEY, RequestContext.get().getCurrUserId());
-
-
-        SaveServiceHelper.save(new DynamicObject[]{personPosFile});
+        logger.info("{}-设置所有字段完成", logPrefix);
+
+//        SaveServiceHelper.save(new DynamicObject[]{personPosFile});
+        OperationResult operationResult = SaveServiceHelper.saveOperate(PositionStructureConstant.PERSONPOSFILE_ENTITYID, new DynamicObject[]{personPosFile}, OperateOption.create());
+        if (!operationResult.isSuccess()) {
+            StringJoiner errorMsg = new StringJoiner("\n");
+            for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
+                errorMsg.add(error.getMessage());
+            }
+            if (!ObjectUtils.isEmpty(operationResult.getMessage())) {
+                errorMsg.add(operationResult.getMessage());
+            }
+            throw new ValidationException("保存职位档案失败,原因:" + errorMsg.toString());
+        }
+        logger.info("{}-职位档案保存完成,ID={}", logPrefix, personPosFile.getLong(FormConstant.ID_KEY));
         return personPosFile;
         return personPosFile;
     }
     }
 
 

+ 21 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/NewHireInitialOperationPlugIn.java

@@ -139,9 +139,12 @@ public class NewHireInitialOperationPlugIn extends BaseInitialOperationPlugIn {
      * 处理单个在职人员初定
      * 处理单个在职人员初定
      */
      */
     private void processNewHireInitialData() {
     private void processNewHireInitialData() {
+        logger.info("【职位体系】-开始处理新入职人员初定");
 
 
         List<DynamicObject> savePersonPosFileList = Lists.newArrayList();
         List<DynamicObject> savePersonPosFileList = Lists.newArrayList();
-        for (BaseInitialData data : baseInitialData) {
+        for (int i = 0; i < baseInitialData.size(); i++) {
+            BaseInitialData data = baseInitialData.get(i);
+            logger.info("【职位体系】-处理第{}个新入职人员初定", i+1);
 
 
             String logPrefix = StrFormatter.format("【职位体系】-新入职人员初定-人员【{}({})】",
             String logPrefix = StrFormatter.format("【职位体系】-新入职人员初定-人员【{}({})】",
                     data.person.getString(FormConstant.NAME_KEY),
                     data.person.getString(FormConstant.NAME_KEY),
@@ -153,9 +156,11 @@ public class NewHireInitialOperationPlugIn extends BaseInitialOperationPlugIn {
                     data.positionHr.getString(FormConstant.NAME_KEY));
                     data.positionHr.getString(FormConstant.NAME_KEY));
 
 
             // 获取上年度绩效结果
             // 获取上年度绩效结果
+            logger.info("{}-开始获取上年度绩效结果", logPrefix);
             getPreviousYearPerformance(data, logPrefix);
             getPreviousYearPerformance(data, logPrefix);
 
 
             // 获取学历、职称、技能对应的积分
             // 获取学历、职称、技能对应的积分
+            logger.info("{}-开始获取积分数据", logPrefix);
             ScoreData scoreData = getScoreData(data, logPrefix);
             ScoreData scoreData = getScoreData(data, logPrefix);
 
 
             // 优秀生得2分
             // 优秀生得2分
@@ -165,34 +170,49 @@ public class NewHireInitialOperationPlugIn extends BaseInitialOperationPlugIn {
             BigDecimal allSumScore = scoreData.educationScore.add(scoreData.proTitleScore).add(scoreData.perOcpQualScore).add(excellentScore);
             BigDecimal allSumScore = scoreData.educationScore.add(scoreData.proTitleScore).add(scoreData.perOcpQualScore).add(excellentScore);
             logger.info("{}-学历分 + 职称/技能分 + 优秀生分 = {}", logPrefix, allSumScore);
             logger.info("{}-学历分 + 职称/技能分 + 优秀生分 = {}", logPrefix, allSumScore);
             // 计算累计积分池(生涯积分)
             // 计算累计积分池(生涯积分)
+            logger.info("{}-开始计算累计积分池", logPrefix);
             BigDecimal sumScore = calculateSumScore(allSumScore, scoreData, logPrefix);
             BigDecimal sumScore = calculateSumScore(allSumScore, scoreData, logPrefix);
 
 
             // 计算职级
             // 计算职级
             //当考核结果为无时,职级定为最低级
             //当考核结果为无时,职级定为最低级
             boolean useMinLevel = data.lastYearAppraisalResultEnum == nckd.jxccl.base.common.enums.AppraisalResultEnum.NONE;
             boolean useMinLevel = data.lastYearAppraisalResultEnum == nckd.jxccl.base.common.enums.AppraisalResultEnum.NONE;
             // 如果是管理序列,则按职能序列进行初定
             // 如果是管理序列,则按职能序列进行初定
+            logger.info("{}-开始处理职位序列转换", logPrefix);
             data.convertJobSeq = JobLevelCalculatorService.handleJobSeq(data.jobSeq);
             data.convertJobSeq = JobLevelCalculatorService.handleJobSeq(data.jobSeq);
+            logger.info("{}-职位序列转换完成,convertJobSeq={}", logPrefix, data.convertJobSeq);
+            
             //【三期需求】-不满足三要素(聘任职称/技能、考核结果、积分)按"无职级"初定
             //【三期需求】-不满足三要素(聘任职称/技能、考核结果、积分)按"无职级"初定
             String perProTitleNumber = scoreData.dbProTitleLevel != null ? scoreData.dbProTitleLevel.getString(FormConstant.NUMBER_KEY) : null;
             String perProTitleNumber = scoreData.dbProTitleLevel != null ? scoreData.dbProTitleLevel.getString(FormConstant.NUMBER_KEY) : null;
             String quaLevelNumber = scoreData.dbOcpQualLevel != null ? scoreData.dbOcpQualLevel.getString(FormConstant.NUMBER_KEY) : null;
             String quaLevelNumber = scoreData.dbOcpQualLevel != null ? scoreData.dbOcpQualLevel.getString(FormConstant.NUMBER_KEY) : null;
             boolean threeElementMeet = JobLevelCalculatorService.checkThreeElementsRequirement(data.convertJobSeq, allSumScore, scoreData.dbProTitleLevel,
             boolean threeElementMeet = JobLevelCalculatorService.checkThreeElementsRequirement(data.convertJobSeq, allSumScore, scoreData.dbProTitleLevel,
                     scoreData.dbOcpQualLevel, data.lastYearAppraisalResultEnum);
                     scoreData.dbOcpQualLevel, data.lastYearAppraisalResultEnum);
+                    
+            logger.info("{}-计算职级参数: convertJobSeq={}, allSumScore={}, perProTitleNumber={}, quaLevelNumber={}, downgradeNum={}, useMinLevel={}, !threeElementMeet={}",
+                       logPrefix, data.convertJobSeq, allSumScore, perProTitleNumber, quaLevelNumber, data.downgradeNum, useMinLevel, !threeElementMeet);
 
 
             DynamicObject jobLeve = JobLevelCalculatorService.getJobLevel(
             DynamicObject jobLeve = JobLevelCalculatorService.getJobLevel(
                     data.convertJobSeq, allSumScore, perProTitleNumber,
                     data.convertJobSeq, allSumScore, perProTitleNumber,
                     quaLevelNumber,data.downgradeNum,useMinLevel,!threeElementMeet);
                     quaLevelNumber,data.downgradeNum,useMinLevel,!threeElementMeet);
+            logger.info("{}-职级计算完成,jobLeve={}", logPrefix, jobLeve);
+            
             if(jobLeve != null) {
             if(jobLeve != null) {
                 // 构建职位档案并存入数据库
                 // 构建职位档案并存入数据库
+                logger.info("{}-开始创建并保存职位档案", logPrefix);
                 DynamicObject savePersonPosFile = createAndSavePersonPosFile(data, scoreData, allSumScore, sumScore, jobLeve, logPrefix, "1");
                 DynamicObject savePersonPosFile = createAndSavePersonPosFile(data, scoreData, allSumScore, sumScore, jobLeve, logPrefix, "1");
                 savePersonPosFileList.add(savePersonPosFile);
                 savePersonPosFileList.add(savePersonPosFile);
                 //返回定级后的职级
                 //返回定级后的职级
                 setJobLevelResult(data.person, jobLeve);
                 setJobLevelResult(data.person, jobLeve);
+                logger.info("{}-职位档案创建并保存完成", logPrefix);
 
 
                 //TODO 【待修改】-职位体系-这里可能有协同,初定完成后需要将待办任务置为已完成
                 //TODO 【待修改】-职位体系-这里可能有协同,初定完成后需要将待办任务置为已完成
+            } else {
+                logger.warn("{}-未能计算出有效职级,跳过创建职位档案", logPrefix);
             }
             }
         }
         }
         //职位津贴
         //职位津贴
+        logger.info("【职位体系】-开始生成职位津贴,处理数量: {}", savePersonPosFileList.size());
         ManagerAllowanceService.generateMgrPostAllow(savePersonPosFileList);
         ManagerAllowanceService.generateMgrPostAllow(savePersonPosFileList);
+        logger.info("【职位体系】-新入职人员初定处理完成");
 
 
     }
     }
 
 

+ 20 - 2
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/ServingInitialOperationPlugIn.java

@@ -147,9 +147,13 @@ public class ServingInitialOperationPlugIn extends BaseInitialOperationPlugIn {
      * 处理单个在职人员初定
      * 处理单个在职人员初定
      */
      */
     private void processServingInitial() {
     private void processServingInitial() {
+        logger.info("【职位体系】-开始处理在职人员初定");
         List<DynamicObject> savePersonPosFileList = Lists.newArrayList();
         List<DynamicObject> savePersonPosFileList = Lists.newArrayList();
         // 提取基本信息
         // 提取基本信息
-        for (BaseInitialData data : baseInitialData) {
+        for (int i = 0; i < baseInitialData.size(); i++) {
+            BaseInitialData data = baseInitialData.get(i);
+            logger.info("【职位体系】-处理第{}个在职人员初定", i+1);
+            
             String logPrefix = StrFormatter.format("【职位体系】-在职人员初定-人员【{}({})】",
             String logPrefix = StrFormatter.format("【职位体系】-在职人员初定-人员【{}({})】",
                     data.person.getString(FormConstant.NAME_KEY),
                     data.person.getString(FormConstant.NAME_KEY),
                     data.person.getString(FormConstant.EMP_NUMBER_KEY));
                     data.person.getString(FormConstant.EMP_NUMBER_KEY));
@@ -161,17 +165,21 @@ public class ServingInitialOperationPlugIn extends BaseInitialOperationPlugIn {
                     data.allSumScore.toString());
                     data.allSumScore.toString());
 
 
             // 获取上年度绩效结果
             // 获取上年度绩效结果
+            logger.info("{}-开始获取上年度绩效结果", logPrefix);
             getPreviousYearPerformance(data, logPrefix);
             getPreviousYearPerformance(data, logPrefix);
 
 
             // 获取学历、职称、技能对应的积分
             // 获取学历、职称、技能对应的积分
+            logger.info("{}-开始获取积分数据", logPrefix);
             ScoreData scoreData = getScoreData(data, logPrefix);
             ScoreData scoreData = getScoreData(data, logPrefix);
 
 
             // 计算累计积分池(生涯积分)
             // 计算累计积分池(生涯积分)
+            logger.info("{}-开始计算累计积分池", logPrefix);
             BigDecimal sumScore = calculateSumScore(data.allSumScore, scoreData, logPrefix);
             BigDecimal sumScore = calculateSumScore(data.allSumScore, scoreData, logPrefix);
 
 
             // 如果是管理序列,则按职能序列进行初定
             // 如果是管理序列,则按职能序列进行初定
+            logger.info("{}-开始处理职位序列转换", logPrefix);
             data.convertJobSeq = JobLevelCalculatorService.handleJobSeq(data.jobSeq);
             data.convertJobSeq = JobLevelCalculatorService.handleJobSeq(data.jobSeq);
-
+            logger.info("{}-职位序列转换完成,convertJobSeq={}", logPrefix, data.convertJobSeq);
 
 
             // 计算职级
             // 计算职级
             //当考核结果为无时,职级定为最低级
             //当考核结果为无时,职级定为最低级
@@ -180,20 +188,30 @@ public class ServingInitialOperationPlugIn extends BaseInitialOperationPlugIn {
             String quaLevelNumber = scoreData.dbOcpQualLevel != null ? scoreData.dbOcpQualLevel.getString(FormConstant.NUMBER_KEY) : null;
             String quaLevelNumber = scoreData.dbOcpQualLevel != null ? scoreData.dbOcpQualLevel.getString(FormConstant.NUMBER_KEY) : null;
             boolean threeElementMeet = JobLevelCalculatorService.checkThreeElementsRequirement(data.convertJobSeq, data.allSumScore, scoreData.dbProTitleLevel,
             boolean threeElementMeet = JobLevelCalculatorService.checkThreeElementsRequirement(data.convertJobSeq, data.allSumScore, scoreData.dbProTitleLevel,
                     scoreData.dbOcpQualLevel, data.lastYearAppraisalResultEnum);
                     scoreData.dbOcpQualLevel, data.lastYearAppraisalResultEnum);
+            logger.info("{}-计算职级参数: convertJobSeq={}, allSumScore={}, perProTitleNumber={}, quaLevelNumber={}, downgradeNum={}, useMinLevel={}, !threeElementMeet={}",
+                       logPrefix, data.convertJobSeq, data.allSumScore, perProTitleNumber, quaLevelNumber, data.downgradeNum, useMinLevel, !threeElementMeet);
+                       
             DynamicObject jobLeve = JobLevelCalculatorService.getJobLevel(
             DynamicObject jobLeve = JobLevelCalculatorService.getJobLevel(
                     data.convertJobSeq, data.allSumScore, perProTitleNumber,
                     data.convertJobSeq, data.allSumScore, perProTitleNumber,
                     quaLevelNumber,  data.downgradeNum,useMinLevel,!threeElementMeet);
                     quaLevelNumber,  data.downgradeNum,useMinLevel,!threeElementMeet);
+            logger.info("{}-职级计算完成,jobLeve={}", logPrefix, jobLeve);
 
 
             if(jobLeve != null) {
             if(jobLeve != null) {
                 // 构建职位档案并存入数据库
                 // 构建职位档案并存入数据库
+                logger.info("{}-开始创建并保存职位档案", logPrefix);
                 DynamicObject savePersonPosFile = createAndSavePersonPosFile(data, scoreData, data.allSumScore, sumScore, jobLeve, logPrefix, "2");
                 DynamicObject savePersonPosFile = createAndSavePersonPosFile(data, scoreData, data.allSumScore, sumScore, jobLeve, logPrefix, "2");
                 savePersonPosFileList.add(savePersonPosFile);
                 savePersonPosFileList.add(savePersonPosFile);
                 //返回定级后的职级。张三:职位级为"初级(1)"
                 //返回定级后的职级。张三:职位级为"初级(1)"
                 setJobLevelResult(data.person, jobLeve);
                 setJobLevelResult(data.person, jobLeve);
+                logger.info("{}-职位档案创建并保存完成", logPrefix);
+            } else {
+                logger.warn("{}-未能计算出有效职级,跳过创建职位档案", logPrefix);
             }
             }
         }
         }
         //职位津贴
         //职位津贴
+        logger.info("【职位体系】-开始生成职位津贴,处理数量: {}", savePersonPosFileList.size());
         ManagerAllowanceService.generateMgrPostAllow(savePersonPosFileList);
         ManagerAllowanceService.generateMgrPostAllow(savePersonPosFileList);
+        logger.info("【职位体系】-在职人员初定处理完成");
     }
     }
 
 
     @Override
     @Override

+ 1 - 9
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/other/NewAppointMentOpPlugin.java

@@ -161,11 +161,7 @@ public class NewAppointMentOpPlugin extends AbstractOperationServicePlugIn imple
                 ));
                 ));
         List<DynamicObject> newEntityList = new ArrayList<>();
         List<DynamicObject> newEntityList = new ArrayList<>();
 
 
-        DynamicObject org = OrgHelper.getCreateOrg(PositionStructureConstant.PERSONPOSFILE_ENTITYID);
-        String bdCtrlStrgy = null;
-        if(org != null) {
-            bdCtrlStrgy = OrgHelper.getBdCtrlStrgy(PositionStructureConstant.PERSONPOSFILE_ENTITYID, org.getLong(FormConstant.ID_KEY));
-        }
+
         for (DynamicObject entry : e.getDataEntities()) {
         for (DynamicObject entry : e.getDataEntities()) {
             DynamicObject newEntity = EntityHelper.newEntity(PositionStructureConstant.NCKD_PERSONPOSFILE);
             DynamicObject newEntity = EntityHelper.newEntity(PositionStructureConstant.NCKD_PERSONPOSFILE);
             DynamicObject person = entry.getDynamicObject(PositionStructureConstant.NCKD_PERSON);
             DynamicObject person = entry.getDynamicObject(PositionStructureConstant.NCKD_PERSON);
@@ -182,10 +178,6 @@ public class NewAppointMentOpPlugin extends AbstractOperationServicePlugIn imple
             newEntity.set(PositionStructureConstant.NCKD_POSITIONHR, empPosOrgRel.get(PositionStructureConstant.POSITION_KEY));
             newEntity.set(PositionStructureConstant.NCKD_POSITIONHR, empPosOrgRel.get(PositionStructureConstant.POSITION_KEY));
             newEntity.set(PositionStructureConstant.NCKD_EXECUTEYEAR, beginDateDateTime.getYear());
             newEntity.set(PositionStructureConstant.NCKD_EXECUTEYEAR, beginDateDateTime.getYear());
             newEntity.set(PositionStructureConstant.NCKD_APPOINTSTATUS, "1");
             newEntity.set(PositionStructureConstant.NCKD_APPOINTSTATUS, "1");
-            newEntity.set(FormConstant.CREATEORG_KEY, org);
-            newEntity.set(FormConstant.ORG_KEY, org);
-            newEntity.set(FormConstant.USEORG_KEY, org);
-            newEntity.set(FormConstant.CTRLSTRATEGY_KEY, bdCtrlStrgy);
             newEntity.set(FormConstant.CREATOR_KEY, UserServiceHelper.getCurrentUserId());
             newEntity.set(FormConstant.CREATOR_KEY, UserServiceHelper.getCurrentUserId());
             newEntity.set(FormConstant.DESCRIPTION_KEY, entry.get(FormConstant.DESCRIPTION_KEY));
             newEntity.set(FormConstant.DESCRIPTION_KEY, entry.get(FormConstant.DESCRIPTION_KEY));
             newEntityList.add(newEntity);
             newEntityList.add(newEntity);

+ 355 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/task/PsmsAdjustSalaryTask.java

@@ -0,0 +1,355 @@
+package nckd.jxccl.hr.psms.task;
+
+import com.alibaba.fastjson.JSON;
+import kd.bos.common.enums.EnableEnum;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.utils.ObjectUtils;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.operate.result.IOperateInfo;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.exception.KDException;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.sdk.plugin.Plugin;
+import kd.sdk.swc.hcdm.business.helper.HCDMApplyBillServiceHelper;
+import kd.sdk.swc.hcdm.business.helper.HCDMSalaryStdServiceHelper;
+import kd.sdk.swc.hcdm.common.dto.stdtab.match.StdTableDataMatchParam;
+import kd.sdk.swc.hcdm.common.dto.stdtab.match.StdTableDataMatchResult;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.enums.psms.AdjustTypeEnum;
+import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
+import nckd.jxccl.base.common.exception.ValidationException;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.base.entity.helper.EntityHelper;
+import nckd.jxccl.base.swc.helper.AdjFileServiceHelper;
+import nckd.jxccl.hr.psms.common.PositionStructureConstant;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.StringJoiner;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * 职位体系推送薪酬
+ *
+ * @author W.Y.C
+ * @version 1.0
+ * @date 2025/12/21 15:01
+ */
+public class PsmsAdjustSalaryTask extends AbstractTask implements Plugin {
+
+    private static final Log logger = LogFactory.getLog(PsmsAdjustSalaryTask.class);
+
+
+    @Override
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        //1:为本月数据,2:为上月数据
+        Integer type = ConvertUtil.toInt(map.get("type"));
+        Date beginDateParam = ConvertUtil.toDate(map.get("beginDateParam"));
+        Date endDateParam = ConvertUtil.toDate(map.get("endDateParam"));
+        // 校验日期:要么都为空,要么都不为空
+        if ((beginDateParam == null && endDateParam != null) || (beginDateParam != null && endDateParam == null)) {
+            throw new ValidationException("日期参数错误-开始日期和结束日期必须同时为空或同时不为空");
+        }
+
+        QFilter filter = new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode())
+                .and(PositionStructureConstant.NCKD_TYPESTATE, QCP.in, new String[]{TypeStateEnum.NEW_ENTRY.getCode(),TypeStateEnum.IN_SERVICE_LEVEL.getCode(),TypeStateEnum.ANNUAL_ADJUSTMENT.getCode(),TypeStateEnum.POSITION_TRANSFER.getCode()});
+        Date beginDate = null;
+        Date endDate = null;
+        if(beginDateParam != null && endDateParam != null){
+            beginDate = DateUtil.beginOfDay(beginDateParam);
+            endDate = DateUtil.endOfDay(endDateParam);
+        }else{
+            LocalDateTime now = DateUtil.now();
+            if(type == 2){
+                now = DateUtil.minusMonths(now, 1);
+            }else if(type == 1){
+                //本月
+            }else{
+                throw new ValidationException("参数错误-type,只能为1或2");
+            }
+            beginDate = DateUtil.toDate(DateUtil.beginOfMonth(now));
+            endDate = DateUtil.toDate(DateUtil.endOfMonth(now));
+        }
+        filter.and(FormConstant.CREATE_TIME_KEY,QCP.large_equals,beginDate);
+        filter.and(FormConstant.CREATE_TIME_KEY,QCP.less_equals,new Date());
+
+        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                .add(FormConstant.ID_KEY)
+                .addIdNumberName(FormConstant.NCKD_PERSON)
+                .add(PositionStructureConstant.NCKD_ISSALADJPUSH)
+                .add(PositionStructureConstant.NCKD_BEGINDATE)
+                .add(PositionStructureConstant.CREATE_TIME_KEY)
+                .addIdNumberNameWithExtras(new String[]{PositionStructureConstant.NCKD_JOBLEVELHR},PositionStructureConstant.JOBLEVELSEQ,PositionStructureConstant.NCKD_COEFFICIENT)
+                .addIdNumberName(PositionStructureConstant.NCKD_LASTPERSONPOSFILE,PositionStructureConstant.NCKD_JOBLEVELHR)
+                .orderDesc(FormConstant.CREATE_TIME_KEY);
+        DynamicObjectCollection personPosFileColl = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
+        // 按人员分组,Map<Long,List<DynamicObject>>
+        Map<Long, List<DynamicObject>> personPosFileMap = personPosFileColl.stream()
+                .collect(Collectors.groupingBy(
+                        obj -> obj.getLong(String.join(".", PositionStructureConstant.NCKD_PERSON, FormConstant.ID_KEY))
+                ));
+        //需要推送调薪的员工档案id
+        List<Long> needAdjustSalaryId = new ArrayList<>();
+        List<Long> needPersonId = new ArrayList<>();
+        List<Long> jobLevelIds = new ArrayList<>();
+        // 处理每个员工的记录
+        for (Map.Entry<Long, List<DynamicObject>> entry : personPosFileMap.entrySet()) {
+            List<DynamicObject> records = entry.getValue();
+            // 在当前员工的所有记录中,找出beginDate~endDate范围内CREATE_TIME_KEY最新的那条记录
+            Date finalBeginDate = beginDate;
+            Date finalEndDate = endDate;
+            Optional<DynamicObject> latestRecordOpt = records.stream()
+                    .filter(record -> {
+                        Date createTime = record.getDate(PositionStructureConstant.CREATE_TIME_KEY);
+                        return createTime != null &&
+                                !createTime.before(finalBeginDate) &&
+                                !createTime.after(finalEndDate);
+                    })
+                    .max(Comparator.comparing(record -> record.getDate(PositionStructureConstant.CREATE_TIME_KEY)));
+
+            // 如果找到了时间范围内的最新记录
+            if (latestRecordOpt.isPresent()) {
+                DynamicObject latestRecord = latestRecordOpt.get();
+                Date latestCreateTime = latestRecord.getDate(PositionStructureConstant.CREATE_TIME_KEY);
+
+                // 检查在latestCreateTime到当前时间范围内,该员工是否有NCKD_ISSALADJPUSH=true的记录(有的话说明当前数据之后已经有推送薪酬了,这条不用推送)
+                boolean hasPushedRecord = records.stream()
+                        .filter(record -> {
+                            Date createTime = record.getDate(PositionStructureConstant.CREATE_TIME_KEY);
+                            return createTime != null &&
+                                    !createTime.before(latestCreateTime);
+                        })
+                        .anyMatch(record -> record.getBoolean(PositionStructureConstant.NCKD_ISSALADJPUSH));
+                // 如果在最新记录时间之后没有推送调薪的记录,则添加到需要推送调薪的列表中
+                if (!hasPushedRecord) {
+                    needAdjustSalaryId.add(latestRecord.getLong(FormConstant.ID_KEY));
+                    needPersonId.add(latestRecord.getLong(String.join(".", PositionStructureConstant.NCKD_PERSON, FormConstant.ID_KEY)));
+                    jobLevelIds.add(latestRecord.getLong(String.join(".", PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.ID_KEY)));
+                    //上一档案职级
+                    long lastJobLevel = latestRecord.getLong(String.join(".", PositionStructureConstant.NCKD_LASTPERSONPOSFILE, PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.ID_KEY));
+                    jobLevelIds.add(lastJobLevel);
+                }
+            }
+        }
+
+        if(!needAdjustSalaryId.isEmpty()){
+            //获取人员最新岗位工资标准定薪记录
+            List<AdjFileServiceHelper.SalaryAdjustmentResult> salaryAdjustmentResultList = AdjFileServiceHelper.getLastDecAdjRecords(needPersonId, FormConstant.STANDARDITEM_ID_KEY);
+            Map<Long,AdjFileServiceHelper.SalaryAdjustmentResult> salaryAdjustmentResultMap = new HashMap<>(salaryAdjustmentResultList.size());
+            if (!salaryAdjustmentResultList.isEmpty()) {
+                //薪酬标准ID
+                List<Long> salaryStIds = salaryAdjustmentResultList.stream().map(result -> result.salaryStDv.getLong(FormConstant.ID_KEY)).collect(Collectors.toList());
+                QFilter salaryStandardFilter = new QFilter(FormConstant.ID_KEY, QCP.in, salaryStIds)
+                        .and(String.join(".", "rankentry", "rank", FormConstant.NUMBER_KEY), QCP.equals, "01");
+                //获取标准表中01档的薪档
+                QueryFieldBuilder salaryStandFieldBuilder = QueryFieldBuilder.create()
+                        .add(FormConstant.ID_KEY)
+                        .addIdNumberNameWithExtras(new String[]{"rankentry", "rank"},FormConstant.INDEX_KEY);
+                DynamicObjectCollection salaryStandardColl = QueryServiceHelper.query("hcdm_salarystandard", salaryStandFieldBuilder.buildSelect(), new QFilter[]{salaryStandardFilter});
+                Map<Long, DynamicObject> salaryStandardMap = salaryStandardColl.stream()
+                        .collect(Collectors.toMap(
+                                obj -> obj.getLong(FormConstant.ID_KEY),
+                                obj -> obj
+                        ));
+
+                if (!salaryStandardMap.isEmpty()) {
+                    List<StdTableDataMatchParam> matchParams = new ArrayList<>();
+                    for (AdjFileServiceHelper.SalaryAdjustmentResult result : salaryAdjustmentResultList) {
+                        StdTableDataMatchParam stdTableDataMatchParam = new StdTableDataMatchParam();
+                        stdTableDataMatchParam.setStdTableId(result.salaryStDv.getLong(FormConstant.ID_KEY));
+                        stdTableDataMatchParam.setStdItemId(FormConstant.STANDARDITEM_ID_KEY);
+                        stdTableDataMatchParam.setGradeId(result.salaryGrade.getLong(FormConstant.ID_KEY));
+                        DynamicObject dynamicObject = salaryStandardMap.get(result.salaryStDv.getLong(FormConstant.ID_KEY));
+                        if(dynamicObject != null) {
+                            long rankId = dynamicObject.getLong(String.join(".", "rankentry", "rank", FormConstant.ID_KEY));
+                            stdTableDataMatchParam.setRankId(rankId);
+                            result.salaryRank = EntityHelper.newEntity(FormConstant.HSBS_SALARYRANK, rankId);
+                            matchParams.add(stdTableDataMatchParam);
+                        }
+                    }
+                    if(!matchParams.isEmpty()) {
+                        //获取薪酬项目、薪等、薪档对应金额(入参params的数组下标和出参的数组下标一一对应)
+                        List<StdTableDataMatchResult> stdTableDataMatchResults = HCDMSalaryStdServiceHelper.matchStdTableData(matchParams);
+                        for (int i = 0; i < salaryAdjustmentResultList.size(); i++) {
+                            AdjFileServiceHelper.SalaryAdjustmentResult result = salaryAdjustmentResultList.get(i);
+                            if (i < stdTableDataMatchResults.size() && stdTableDataMatchResults.get(i) != null) {
+                                //当前薪等01档的金额
+                                result.amount = stdTableDataMatchResults.get(i).getAmount();
+                                salaryAdjustmentResultMap.put(result.employee.getLong(FormConstant.ID_KEY), result);
+                            }
+                        }
+                    }
+                } else {
+                    logger.warn("未获取薪酬标准表中01档的薪档数据,薪酬标准ID:{}",salaryStIds);
+                }
+            } else {
+                logger.warn("未获取到人员岗位工资标准定薪记录,人员ID:{}",needPersonId);
+            }
+
+            if(!salaryAdjustmentResultMap.isEmpty()){
+                Map<Long, DynamicObject> jobLevelMap = new HashMap<>(jobLevelIds.size());
+                if(!jobLevelIds.isEmpty()) {
+                    MainEntityType jobLevelEntityType = EntityMetadataCache.getDataEntityType(FormConstant.HBJM_JOBLEVELHR);
+                    //重新加载职级信息,避免获取不到系数
+                    DynamicObject[] load = BusinessDataServiceHelper.load(jobLevelIds.toArray(new Long[0]), jobLevelEntityType);
+                    jobLevelMap = Arrays.stream(load)
+                            .collect(Collectors.toMap(
+                                    obj -> obj.getLong(FormConstant.ID_KEY),
+                                    obj -> obj
+                            ));
+                }
+
+                List<DynamicObject> updatePersonPosFile = new ArrayList<>();
+                MainEntityType personPosFileEntityType = EntityMetadataCache.getDataEntityType(PositionStructureConstant.PERSONPOSFILE_ENTITYID);
+                DynamicObject[] personPosFileArray = BusinessDataServiceHelper.load(needAdjustSalaryId.toArray(), personPosFileEntityType);
+                for (DynamicObject personPosFile : personPosFileArray) {
+                    long jobLevelId = personPosFile.getLong(String.join(".", PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.ID_KEY));
+                    long lastJobLevelId = personPosFile.getLong(String.join(".",PositionStructureConstant.NCKD_LASTPERSONPOSFILE, PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.ID_KEY));
+                    DynamicObject jobLevel = jobLevelMap.get(jobLevelId);
+                    DynamicObject lastJobLevel = jobLevelMap.get(lastJobLevelId);
+
+                    if(jobLevel != null) {
+                        DynamicObject person = personPosFile.getDynamicObject(FormConstant.NCKD_PERSON);
+                        Date date = personPosFile.getDate(PositionStructureConstant.NCKD_BEGINDATE);
+                        AdjFileServiceHelper.SalaryAdjustmentResult salaryAdjustmentResult = salaryAdjustmentResultMap.get(person.getLong(FormConstant.ID_KEY));
+                        if (salaryAdjustmentResult != null && salaryAdjustmentResult.amount.compareTo(BigDecimal.ZERO) > 0) {
+                            BigDecimal coefficient = jobLevel.getBigDecimal(PositionStructureConstant.NCKD_COEFFICIENT);
+                            BigDecimal finalAmount = BigDecimal.ZERO;
+                            if(coefficient.compareTo(BigDecimal.ZERO) > 0) {
+                                //职位津贴=职位系数 X 所在岗级岗位工资一档金额
+                                finalAmount = coefficient.multiply(salaryAdjustmentResult.amount);
+                            }
+
+
+                            //触发定调薪
+                            Map<String, Object> applyBill = new HashMap<>();
+                            applyBill.put("billname", StrFormatter.format("【{}】的职位体系调整(职位津贴)",person.getString(FormConstant.NAME_KEY)));
+                            Long orgId = RequestContext.get().getOrgId();
+
+                            String uniquecode = UUID.randomUUID().toString().replace("-", "");
+                            applyBill.put("_uniquecode", uniquecode);
+                            if(salaryAdjustmentResult.hcdmOrg != null){
+                                applyBill.put("org", salaryAdjustmentResult.hcdmOrg.getLong(FormConstant.ID_KEY));
+                            }else{
+                                applyBill.put("org", orgId);
+                            }
+
+                            //定调薪明细字段显示方案   调薪明细字段
+                            applyBill.put("billtype", 2215975998602655744L);
+                            //国家
+                            applyBill.put("billcountry", 1000001L);
+                            //定调薪类型
+                            applyBill.put("salaryadjrsn", 2352338490244480000L);
+                            //默认币种
+                            applyBill.put("billcurrency", 1L);
+                            //定调薪方案
+                            applyBill.put("salaryadjscm", 2322515162646457344L);
+                            //汇率日期
+                            applyBill.put("exchangeratedate", new Date());
+                            //汇率表
+                            applyBill.put("exctable", 2321965096026258432L);
+                            //默认生效日期
+                            applyBill.put("effectivedate", date);
+                            //草稿状态
+                            applyBill.put("isdraft", "1");
+                            //审核状态
+                            applyBill.put("auditstatus", "A");
+                            //申请单数据来源   //1:手工新增  2:接口写入
+                            applyBill.put("datasource", "2");
+
+                            String typeStateStr = personPosFile.getString(PositionStructureConstant.NCKD_TYPESTATE);
+                            TypeStateEnum typeState = TypeStateEnum.getByCode(typeStateStr);
+                            String adjustTypeStr = personPosFile.getString(PositionStructureConstant.NCKD_ADJUSTTYPE);
+                            AdjustTypeEnum adjustType = AdjustTypeEnum.getByCode(adjustTypeStr);
+                            String description = StrFormatter.format("【{}】执行【{}】,调整生效时间【{}】,调整类别【{}】,由【{}({})】 -> 【{}({}级)】。系数【{}】",
+                                    DateUtil.format(personPosFile.getDate(FormConstant.CREATE_TIME_KEY),DateUtil.NORM_DATETIME_PATTERN),
+                                    typeState.getName(),
+                                    DateUtil.format(personPosFile.getDate(PositionStructureConstant.NCKD_BEGINDATE),DateUtil.NORM_DATE_PATTERN),
+                                    adjustType != null ? adjustType.getName() : "初定",
+                                    lastJobLevel == null ? "无" : lastJobLevel.getString(FormConstant.NAME_KEY),
+                                    lastJobLevel == null ? "无" : lastJobLevel.getString(FormConstant.JOBLEVELSEQ)+"级",
+                                    jobLevel.getString(FormConstant.NAME_KEY),
+                                    jobLevel.getString(FormConstant.JOBLEVELSEQ),
+                                     coefficient
+                            );
+                            applyBill.put("description", description);
+                            List<Map<String, Object>> applyBillEntryData = new ArrayList<>();
+                            Map<String, Object> applyBillEntry = new HashMap<>();
+                            Long employeeId = person.getLong(FormConstant.ID_KEY);
+                            Long positionId = personPosFile.getLong(String.join(".",PositionStructureConstant.NCKD_POSITIONHR, FormConstant.ID_KEY));
+                            applyBillEntry.put("adjfile", salaryAdjustmentResult.adjFileInfo.getLong(FormConstant.ID_KEY));
+                            applyBillEntry.put("employee", employeeId);
+                            applyBillEntry.put("standarditem", 2321901533681170432L);    //定调薪项目   职位系数
+                            applyBillEntry.put("frequency", 1095454108284088320L);       //频度  月
+                            applyBillEntry.put("amount", finalAmount);
+                            applyBillEntry.put("position", positionId);
+                            applyBillEntry.put("joblevel", jobLevel.getLong(FormConstant.ID_KEY));
+                            applyBillEntry.put("salarygrade", salaryAdjustmentResult.salaryGrade.getLong(FormConstant.ID_KEY));
+                            applyBillEntry.put("salaryrank", salaryAdjustmentResult.salaryRank.getLong(FormConstant.ID_KEY));
+                            applyBillEntry.put("reason", description);
+                            applyBillEntryData.add(applyBillEntry);
+                            applyBill.put("applybillent", applyBillEntryData);
+                            List<Map<String, Object>> applyBillData = new ArrayList<>();
+                            applyBillData.add(applyBill);
+                            Map<String, Object> papams = new HashMap<>();
+                            papams.put("data", applyBillData);
+                            papams.put("isUseMatchAmount", Boolean.TRUE);
+                            Map<String, Object> result = HCDMApplyBillServiceHelper.saveDraftApplyBill(papams);
+                            if (!ConvertUtil.toBoolean(result.get("success")) || result.get("data") == null || ConvertUtil.toList(result.get("data")).isEmpty()) {
+                                throw new ValidationException("【"+person.getString(FormConstant.NAME_KEY)+"】推送定调薪失败,原因:" + JSON.toJSONString(result));
+                            }else{
+                                personPosFile.set(PositionStructureConstant.NCKD_ISSALADJPUSH, Boolean.TRUE);
+                                personPosFile.set(PositionStructureConstant.NCKD_SALADJPUSHTIME, new Date());
+                                personPosFile.set(PositionStructureConstant.NCKD_SALADJID, ConvertUtil.toMap(ConvertUtil.toList(result.get("data")).get(0)).get("id"));
+                                personPosFile.set(PositionStructureConstant.NCKD_SALADJNUMBER, null);
+
+                                updatePersonPosFile.add(personPosFile);
+                            }
+                        } else {
+                            logger.warn("未获取到员工【{}】最新岗位工资标准定薪记录01档的薪等金额,人员ID:", person.getString(FormConstant.NAME_KEY));
+                        }
+                    }
+                }
+
+                if(!updatePersonPosFile.isEmpty()){
+                    OperationResult operationResult = SaveServiceHelper.saveOperate(PositionStructureConstant.PERSONPOSFILE_ENTITYID, updatePersonPosFile.toArray(new DynamicObject[0]), OperateOption.create());
+                    if (!operationResult.isSuccess()) {
+                        StringJoiner errorMsg = new StringJoiner("\n");
+                        for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
+                            errorMsg.add(error.getMessage());
+                        }
+                        if (!ObjectUtils.isEmpty(operationResult.getMessage())) {
+                            errorMsg.add(operationResult.getMessage());
+                        }
+                        throw new ValidationException("保存职位档案失败,原因:" + errorMsg.toString());
+                    }
+                }
+            }
+        }else{
+            logger.warn("没有需要推送的调薪数据");
+        }
+    }
+}

+ 1 - 1
code/nckd-cosmic-debug/src/main/java/kd/cosmic/debug/tools/CosmicLauncher.java

@@ -43,7 +43,7 @@ public final class CosmicLauncher {
      */
      */
     private static final String DEFAULT_COSMIT_HOME_PATH = System.getProperty("user.home").replaceAll("\\\\", "/") + "/cosmic/home";
     private static final String DEFAULT_COSMIT_HOME_PATH = System.getProperty("user.home").replaceAll("\\\\", "/") + "/cosmic/home";
 	
 	
-	private static final String PROJECT_HOME = "E:/2.work/xuding/jxccl";
+	private static final String PROJECT_HOME = "D:/jxcc/workspace/jtcosmic";
 	
 	
 	private static final String LOCAL_IP = "127.0.0.1";
 	private static final String LOCAL_IP = "127.0.0.1";
 	
 	

+ 3 - 2
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/salary/PushAdjustOpPlugin.java

@@ -1,5 +1,6 @@
 package nckd.jxccl.opmc.pm.plugin.operate.salary;
 package nckd.jxccl.opmc.pm.plugin.operate.salary;
 
 
+import com.alibaba.fastjson.JSON;
 import kd.bos.context.RequestContext;
 import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.db.tx.TX;
 import kd.bos.db.tx.TX;
@@ -155,8 +156,8 @@ public class PushAdjustOpPlugin extends AbstractOperationServicePlugIn implement
             papams.put("data", applyBillData);
             papams.put("data", applyBillData);
             papams.put("isUseMatchAmount", Boolean.TRUE);
             papams.put("isUseMatchAmount", Boolean.TRUE);
             Map<String, Object> result = HCDMApplyBillServiceHelper.saveDraftApplyBill(papams);
             Map<String, Object> result = HCDMApplyBillServiceHelper.saveDraftApplyBill(papams);
-            if (!ConvertUtil.toBoolean(result.get("success"))) {
-                throw new ValidationException("推送定调薪失败,原因:" + result.get("message").toString());
+            if (!ConvertUtil.toBoolean(result.get("success")) || result.get("data") == null || ConvertUtil.toList(result.get("data")).isEmpty()) {
+                throw new ValidationException("推送定调薪失败,原因:" + JSON.toJSONString(result));
             }
             }
         }
         }
     }
     }

+ 3 - 5
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/salary/SalaryAdjOpPlugin.java

@@ -86,8 +86,6 @@ public class SalaryAdjOpPlugin extends AbstractOperationServicePlugIn implements
     private static final int TYPE_PROMOTE_FOR_TWO_EXCELLENT_AND_THREE_PASS = 3;
     private static final int TYPE_PROMOTE_FOR_TWO_EXCELLENT_AND_THREE_PASS = 3;
     /**连续两年考核结果为优秀且另一年考核结果为合格及以上*/
     /**连续两年考核结果为优秀且另一年考核结果为合格及以上*/
     private static final int TYPE_PROMOTE_FOR_TWO_EXCELLENT_AND_THREE_PASS_FOR_TWO_YEARS = 4;
     private static final int TYPE_PROMOTE_FOR_TWO_EXCELLENT_AND_THREE_PASS_FOR_TWO_YEARS = 4;
-    /** 岗位工资标准(jt002)*/
-    private static final Long standardItemId = 2321899710350111744L;
 
 
 
 
     int passYear = 2018;
     int passYear = 2018;
@@ -220,7 +218,7 @@ public class SalaryAdjOpPlugin extends AbstractOperationServicePlugIn implements
                         .collect(Collectors.toList());
                         .collect(Collectors.toList());
 
 
                 DynamicObject standardItem = EntityHelper.newEntity(FormConstant.HSBS_STANDARDITEM);
                 DynamicObject standardItem = EntityHelper.newEntity(FormConstant.HSBS_STANDARDITEM);
-                standardItem.set(FormConstant.ID_KEY, standardItemId);
+                standardItem.set(FormConstant.ID_KEY, FormConstant.STANDARDITEM_ID_KEY);
                 Map<String, Object> adjFileParams = new HashMap<>();
                 Map<String, Object> adjFileParams = new HashMap<>();
                 adjFileParams.put("employees", allPersonIds);
                 adjFileParams.put("employees", allPersonIds);
                 List<String> status = new ArrayList<>();
                 List<String> status = new ArrayList<>();
@@ -247,7 +245,7 @@ public class SalaryAdjOpPlugin extends AbstractOperationServicePlugIn implements
                         // 调薪档案ID
                         // 调薪档案ID
                         dataItem.put("adjfile", adjFileId);
                         dataItem.put("adjfile", adjFileId);
                         // 调薪项目ID
                         // 调薪项目ID
-                        dataItem.put("standarditem", standardItemId);
+                        dataItem.put("standarditem", FormConstant.STANDARDITEM_ID_KEY);
                         // 查询基准日期
                         // 查询基准日期
                         dataItem.put("startdate", new Date());
                         dataItem.put("startdate", new Date());
                         // 唯一标识
                         // 唯一标识
@@ -373,7 +371,7 @@ public class SalaryAdjOpPlugin extends AbstractOperationServicePlugIn implements
                             List<StdTableDataMatchParam> matchParams = new ArrayList<>();
                             List<StdTableDataMatchParam> matchParams = new ArrayList<>();
                             StdTableDataMatchParam stdTableDataMatchParam = new StdTableDataMatchParam();
                             StdTableDataMatchParam stdTableDataMatchParam = new StdTableDataMatchParam();
                             stdTableDataMatchParam.setStdTableId(result.salaryStDv.getLong(FormConstant.ID_KEY));
                             stdTableDataMatchParam.setStdTableId(result.salaryStDv.getLong(FormConstant.ID_KEY));
-                            stdTableDataMatchParam.setStdItemId(standardItemId);
+                            stdTableDataMatchParam.setStdItemId(FormConstant.STANDARDITEM_ID_KEY);
                             stdTableDataMatchParam.setGradeId(result.oldSalaryGrade.getLong(FormConstant.ID_KEY));
                             stdTableDataMatchParam.setGradeId(result.oldSalaryGrade.getLong(FormConstant.ID_KEY));
                             stdTableDataMatchParam.setRankId(newSalaryRank.getLong(FormConstant.ID_KEY));
                             stdTableDataMatchParam.setRankId(newSalaryRank.getLong(FormConstant.ID_KEY));
                             matchParams.add(stdTableDataMatchParam);
                             matchParams.add(stdTableDataMatchParam);

+ 1 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/business/coordination/SinsurCoordSplitService.java

@@ -144,6 +144,7 @@ public class SinsurCoordSplitService {
      */
      */
     public void writeBackSourceBill (DynamicObject bill) {
     public void writeBackSourceBill (DynamicObject bill) {
         bill.set("dealresult", "9");
         bill.set("dealresult", "9");
+        SitConstant.COORDVERIFYBILL_HELPER.update(new DynamicObject[]{bill});
     }
     }
 
 
     /**
     /**

+ 1 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/business/datacomparison/DataComparisonQueryService.java

@@ -91,7 +91,7 @@ public class DataComparisonQueryService {
     public DataSet queryAllCalPersonAndWelfareTypeByTaskId(List<Long> taskIds) {
     public DataSet queryAllCalPersonAndWelfareTypeByTaskId(List<Long> taskIds) {
         // 获取核算任务下的所有人
         // 获取核算任务下的所有人
         QFilter filter = new QFilter("sinsurtask.id", QCP.in, taskIds);
         QFilter filter = new QFilter("sinsurtask.id", QCP.in, taskIds);
-        String selectFields = "welfarepayer.id as welfarepayer, empnumberdb as empnumber,namedb as empname,percre.number as empidcard,employee.id as employee, '1' as flag ";
+        String selectFields = "welfarepayer.id as welfarepayer, empnumberdb as empnumber,namedb as empname,percrenum as empidcard,employee.id as employee, '1' as flag ";
         DataSet dataSet1 = SitConstant.CALPERSON_HELPER.queryDataSet("queryAllCalPerson", selectFields, filter.toArray());
         DataSet dataSet1 = SitConstant.CALPERSON_HELPER.queryDataSet("queryAllCalPerson", selectFields, filter.toArray());
 
 
         // 获取所有险种
         // 获取所有险种

+ 21 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/formplugin/web/coordination/HCSIEmpCoordVerifBillListEx.java

@@ -0,0 +1,21 @@
+package nckd.jxccl.sit.hcsi.formplugin.web.coordination;
+
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.list.plugin.AbstractListPlugin;
+
+public class HCSIEmpCoordVerifBillListEx extends AbstractListPlugin {
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
+        super.afterDoOperation(afterDoOperationEventArgs);
+        String key = afterDoOperationEventArgs.getOperateKey();
+        switch(key) {
+            case "donothing_split":
+                afterDoSplit(afterDoOperationEventArgs);
+        }
+    }
+
+    private void afterDoSplit(AfterDoOperationEventArgs afterDoOperationEventArgs) {
+        this.getView().invokeOperation("refresh");
+    }
+}

+ 1 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/utils/ReportUtils.java

@@ -24,7 +24,7 @@ public class ReportUtils {
     //参保单位,险种,工号,姓名,证件号,单位缴费金额 = 单位固定+单位缴费+单位补缴,个人缴费金额=个人固定+个人缴费+个人补缴
     //参保单位,险种,工号,姓名,证件号,单位缴费金额 = 单位固定+单位缴费+单位补缴,个人缴费金额=个人固定+个人缴费+个人补缴
     //2025-11-17调整 单位缴费金额 = 单位固定+单位缴费,单位补缴金额 = 单位补缴,个人缴费金额=个人固定+个人缴费;个人补缴 = 个人补缴;
     //2025-11-17调整 单位缴费金额 = 单位固定+单位缴费,单位补缴金额 = 单位补缴,个人缴费金额=个人固定+个人缴费;个人补缴 = 个人补缴;
     private static String CALPERSON_FIELDS = "welfarepayer.id as welfarepayer,entryentity.insuranceitem.group.id as welfaretypeid,"
     private static String CALPERSON_FIELDS = "welfarepayer.id as welfarepayer,entryentity.insuranceitem.group.id as welfaretypeid,"
-            +"empnumberdb as empnumber,namedb as empname,percre.number as empidcard,employee.id as employee,"
+            +"empnumberdb as empnumber,namedb as empname,percrenum as empidcard,employee.id as employee,"
             +"case when entryentity.insuranceitem.insurancetypeattr.number in ('1006_S','1005_S','1009_S','1010_S') then entryentity.amountvalue else 0 end as value,"
             +"case when entryentity.insuranceitem.insurancetypeattr.number in ('1006_S','1005_S','1009_S','1010_S') then entryentity.amountvalue else 0 end as value,"
             +"case when entryentity.insuranceitem.insurancetypeattr.number in ('1011_S','1012_S') then entryentity.amountvalue else 0 end as value1,"
             +"case when entryentity.insuranceitem.insurancetypeattr.number in ('1011_S','1012_S') then entryentity.amountvalue else 0 end as value1,"
             +"case when entryentity.insuranceitem.insurancetypeattr.number in ('1005_S','1009_S','1011_S') then '1'"
             +"case when entryentity.insuranceitem.insurancetypeattr.number in ('1005_S','1009_S','1011_S') then '1'"

+ 23 - 5
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hcdm/opplugin/annualincome/SalAnnualIncomeUpdatePlugin.java

@@ -54,8 +54,23 @@ public class SalAnnualIncomeUpdatePlugin extends AbstractOperationServicePlugIn
                         obj -> obj.getLong("groupId") + "_" + obj.getLong("employeeId"), // 构造唯一键
                         obj -> obj.getLong("groupId") + "_" + obj.getLong("employeeId"), // 构造唯一键
                         obj -> obj  // 保留原始对象
                         obj -> obj  // 保留原始对象
                 ));
                 ));
-        Set<String> keySet = resultMap.keySet();
+        Set<String> allKeySet = resultMap.keySet();
         DynamicObjectCollection entryCols = bill.getDynamicObjectCollection("nckd_entryentity");
         DynamicObjectCollection entryCols = bill.getDynamicObjectCollection("nckd_entryentity");
+        Map<String, DynamicObject> currentMap = entryCols.stream()
+                .collect(Collectors.toMap(
+                        obj -> obj.getLong("nckd_payrollgrp.id") + "_" + obj.getLong("nckd_employee.id"), // 构造唯一键
+                        obj -> obj  // 保留原始对象
+                ));
+        Set<String> currentKeySet = currentMap.keySet();
+
+
+        Set<String> updateKeySet = allKeySet.stream()
+                .filter(currentKeySet::contains)
+                .collect(Collectors.toSet());
+        Set<String> addnewSet = allKeySet.stream()
+                .filter(key -> !currentKeySet.contains(key))
+                .collect(Collectors.toSet());
+
         for (DynamicObject entry : entryCols) {
         for (DynamicObject entry : entryCols) {
             // 如果当前分录推送状态不为【社保未拉取】则继续
             // 如果当前分录推送状态不为【社保未拉取】则继续
             if(!entry.getString("nckd_pushstatus").equals("0")) {
             if(!entry.getString("nckd_pushstatus").equals("0")) {
@@ -67,13 +82,16 @@ public class SalAnnualIncomeUpdatePlugin extends AbstractOperationServicePlugIn
             String key = groupId + "_" + employeeId;
             String key = groupId + "_" + employeeId;
 
 
             // 根据唯一键获取,如果不存在则新增一行记录
             // 根据唯一键获取,如果不存在则新增一行记录
-            if(keySet.contains(key)) {
+            if(updateKeySet.contains(key)) {
                 doUpdateEntry(entry,resultMap.get(key));
                 doUpdateEntry(entry,resultMap.get(key));
             }
             }
-            else {
-                doAddnewEntry(entryCols.addNew(), resultMap.get(key));
-            }
         }
         }
+
+        //处理新增分录
+        for (String key : addnewSet) {
+            doAddnewEntry(entryCols.addNew(),resultMap.get(key));
+        }
+
     }
     }
 
 
     /**
     /**

+ 87 - 4
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/init/business/SynPendingSalaryAdjDataServiceImpl.java

@@ -121,8 +121,8 @@ public class SynPendingSalaryAdjDataServiceImpl implements SynPendingSalaryAdjDa
 
 
         QFilter qFilter22 = new QFilter("nckd_billid", QCP.in, onhasonbrdIDs);
         QFilter qFilter22 = new QFilter("nckd_billid", QCP.in, onhasonbrdIDs);
         List<Object> listIDs = QueryServiceHelper.queryPrimaryKeys(FormConstant.NCKD_PENDINGSALARYADJ,new QFilter[]{qFilter22}, null, Integer.MAX_VALUE);
         List<Object> listIDs = QueryServiceHelper.queryPrimaryKeys(FormConstant.NCKD_PENDINGSALARYADJ,new QFilter[]{qFilter22}, null, Integer.MAX_VALUE);
-        DynamicObject billDyn =  BusinessDataServiceHelper.newDynamicObject(FormConstant.NCKD_PENDINGSALARYADJ);
-        DynamicObject[] billDyns = BusinessDataServiceHelper.load(listIDs.toArray(),billDyn.getDynamicObjectType());
+        DynamicObject billDynType =  BusinessDataServiceHelper.newDynamicObject(FormConstant.NCKD_PENDINGSALARYADJ);
+        DynamicObject[] billDyns = BusinessDataServiceHelper.load(listIDs.toArray(),billDynType.getDynamicObjectType());
 
 
         int onhasonbrdCount = 0;
         int onhasonbrdCount = 0;
         Map<Long, DynamicObject> billMap =
         Map<Long, DynamicObject> billMap =
@@ -180,7 +180,6 @@ public class SynPendingSalaryAdjDataServiceImpl implements SynPendingSalaryAdjDa
 
 
         QFilter qFilter15 = new QFilter("nckd_billid", QCP.in, transferIDs);
         QFilter qFilter15 = new QFilter("nckd_billid", QCP.in, transferIDs);
         List<Object> transferlistIDs = QueryServiceHelper.queryPrimaryKeys(FormConstant.NCKD_PENDINGSALARYADJ,new QFilter[]{qFilter15}, null, Integer.MAX_VALUE);
         List<Object> transferlistIDs = QueryServiceHelper.queryPrimaryKeys(FormConstant.NCKD_PENDINGSALARYADJ,new QFilter[]{qFilter15}, null, Integer.MAX_VALUE);
-        DynamicObject billDynType =  BusinessDataServiceHelper.newDynamicObject(FormConstant.NCKD_PENDINGSALARYADJ);
         DynamicObject[] billDyns1 = BusinessDataServiceHelper.load(transferlistIDs.toArray(),billDynType.getDynamicObjectType());
         DynamicObject[] billDyns1 = BusinessDataServiceHelper.load(transferlistIDs.toArray(),billDynType.getDynamicObjectType());
 
 
         int transferCount = 0;
         int transferCount = 0;
@@ -238,12 +237,96 @@ public class SynPendingSalaryAdjDataServiceImpl implements SynPendingSalaryAdjDa
             billDynList.add(dyn);
             billDynList.add(dyn);
         }
         }
 
 
+
+        /**
+         * 批量调动
+         */
+        String selectField3 = "id,billno,entryentity.b_effectivedate,createtime,entryentity.bb_em_tid as bb_em_tid,entryentity.ba_em_empnumber,entryentity.bb_po_position.boid,entryentity.aposition.boid,entryentity.bb_po_adminorg.boid,entryentity.aorg.boid,entryentity.aorg.belongcompany.id";
+        QFilter qFilter31 = new QFilter("billstatus", QCP.equals, "C");
+        QFilter qFilter32 = new QFilter("entryentity.transfereffectstatus", QCP.equals, "2");  //同步结果 =  同步成功
+        QFilter qFilter33 = new QFilter("entryentity.b_effectivedate", QCP.large_equals, daysAgo);
+        QFilter qFilter34 = new QFilter("entryentity.b_effectivedate", QCP.less_equals, currentDate);
+        QFilter qFilter35 = new QFilter("entryentity.aposition.nckd_paystdplan.name", QCP.equals, "江铜集团岗位绩效工资制");
+        DynamicObjectCollection transferBatchDyns = QueryServiceHelper.query(FormConstant.HDM_TRANSFERBATCH, selectField3,new QFilter[]{qFilter31,qFilter32,qFilter33,qFilter34,qFilter35});
+
+        Map<Long, DynamicObject> transferBatchMap = (Map)transferBatchDyns.stream().collect(Collectors.toMap((obj) -> {
+            return obj.getLong("id");
+        }, (obj) -> {
+            return obj;
+        }, (k1, k2) -> {
+            return k1;
+        }));
+        List<Long> transferBatchIDs = transferBatchMap.keySet().stream().collect(Collectors.toList());
+
+        QFilter qFilter38 = new QFilter("nckd_billid", QCP.in, transferBatchIDs);
+        List<Object> transferBatchlistIDs = QueryServiceHelper.queryPrimaryKeys(FormConstant.NCKD_PENDINGSALARYADJ,new QFilter[]{qFilter38}, null, Integer.MAX_VALUE);
+        DynamicObject[] billDyns3 = BusinessDataServiceHelper.load(transferBatchlistIDs.toArray(),billDynType.getDynamicObjectType());
+
+        int transferBatchCount = 0;
+        Map<Long, DynamicObject> billMap3 =
+                Arrays.stream(billDyns3)
+                        .collect(Collectors.toMap(
+                                detail -> detail.getLong("nckd_billid"),
+                                detail -> detail, // 整个 DynamicObject 作为 value
+                                (existing, replacement) -> existing // 保留前面的值
+                        ));
+
+        Map<Long, DynamicObject> adjRecordMap3 = getAdjRecordInfo(transferBatchDyns);
+
+        for(DynamicObject transferDyn: transferBatchDyns) {
+            DynamicObject billDyn3 = billMap3.get(transferDyn.getLong("id"));
+
+            if(billDyn3 != null) {
+                continue;
+            }
+            DynamicObject dyn = new DynamicObject(entityType);
+            Long employeeID = transferDyn.getLong("bb_em_tid");
+            dyn.set("billno", transferDyn.getString("billno"));
+            dyn.set("nckd_billid", transferDyn.getLong("id"));
+            dyn.set("nckd_billtype", "调动单");
+            dyn.set("billstatus", "A");  ///待处理
+            dyn.set("nckd_employeefield", employeeID);
+            dyn.set("nckd_hrorg", transferDyn.getLong("entryentity.aorg.belongcompany.id"));  //薪酬管理组织 来源  调后部门中的公司
+            dyn.set("nckd_changedate", transferDyn.getDate("entryentity.b_effectivedate"));
+            dyn.set("nckd_dodatetime", transferDyn.getDate("createtime"));
+            dyn.set("nckd_salaryadjus", salaryTypeDyns.get(1).getLong("id"));  //定调薪类型
+            /**
+             * 调动前
+             */
+            dyn.set("nckd_oldhradminorg", transferDyn.getLong("entryentity.bb_po_adminorg.boid"));  //部门
+            dyn.set("nckd_oldposition", transferDyn.getLong("entryentity.bb_po_position.boid"));  //岗位
+            DynamicObject adjRecordDyn  = adjRecordMap3.get(employeeID);
+            if(adjRecordDyn != null) {
+                dyn.set("nckd_oldsalaryrank", adjRecordDyn.getLong("salaryrank.id"));  //薪档
+            }
+            /**
+             * 调动后
+             */
+            dyn.set("nckd_newhradminorg", transferDyn.getLong("entryentity.aorg.boid"));  //部门
+            dyn.set("nckd_newposition", transferDyn.getLong("entryentity.aposition.boid"));  //岗位
+            //判断薪档是否改变
+            boolean isChange = calaSararyRank(transferDyn.getLong("entryentity.bb_po_position.boid"), transferDyn.getLong("entryentity.aposition.boid"));
+            if(isChange) {
+                dyn.set("nckd_newsalaryrank", salaryRankDyn.getLong("id"));   //薪档
+            }else{
+                if(adjRecordDyn != null) {
+                    dyn.set("nckd_newsalaryrank", adjRecordDyn.getLong("salaryrank.id"));
+                }
+            }
+
+            transferBatchCount++;
+            billDynList.add(dyn);
+
+        }
+
+
+
         int length = 0;
         int length = 0;
         if(billDynList.size() != 0) {
         if(billDynList.size() != 0) {
             //保存
             //保存
             Object[] update = SaveServiceHelper.save(billDynList.toArray(new DynamicObject[0]));
             Object[] update = SaveServiceHelper.save(billDynList.toArray(new DynamicObject[0]));
             length = update.length;
             length = update.length;
-            errorInfo.append("成功导入,"+length+"条数据,其中入职单"+onhasonbrdCount+"条,调动单"+transferCount+"条"); // 成功类型
+            errorInfo.append("成功导入,"+length+"条数据,其中入职单"+onhasonbrdCount+"条,调动单"+transferCount+transferBatchCount+"条"); // 成功类型
         }else{
         }else{
             errorInfo.append("没有导入数据");
             errorInfo.append("没有导入数据");
         }
         }

+ 13 - 5
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/utils/SwcUtils.java

@@ -9,6 +9,7 @@ import kd.bos.orm.query.QFilter;
 import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
 import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
 import nckd.jxccl.swc.constants.SwcConstant;
 import nckd.jxccl.swc.constants.SwcConstant;
 
 
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.time.ZoneId;
@@ -66,8 +67,8 @@ public class SwcUtils {
 
 
     public static StringBuilder getSalaryDetailSql(List<Long> groupIds, Date startDate, Date endDate) {
     public static StringBuilder getSalaryDetailSql(List<Long> groupIds, Date startDate, Date endDate) {
         String ids = String.join(",",groupIds.stream().map(String::valueOf).toArray(String[]::new));
         String ids = String.join(",",groupIds.stream().map(String::valueOf).toArray(String[]::new));
-        String startDateStr = dateToStr(startDate);
-        String endDateStr = dateToStr(endDate);
+        String startDateStr = dateToStr(startDate, 1);
+        String endDateStr = dateToStr(endDate, 2);
 
 
         StringBuilder sb = new StringBuilder();
         StringBuilder sb = new StringBuilder();
         sb.append("/*dialect*/ SELECT a.fid groupId,\n" +
         sb.append("/*dialect*/ SELECT a.fid groupId,\n" +
@@ -109,9 +110,16 @@ public class SwcUtils {
         return excludeGroupIds;
         return excludeGroupIds;
     }
     }
 
 
-    public static String dateToStr(Date date) {
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-        return sdf.format(date);
+    public static String dateToStr(Date date, int type) {
+        if(type == 1) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            return sdf.format(date);
+        }
+        else {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            String dateStr = sdf.format(date);
+            return dateStr + " 23:59:59";
+        }
     }
     }
 
 
 }
 }

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików