1
0

2 Коммитууд c23fdc3396 ... 265e5f9817

Эзэн SHA1 Мессеж Огноо
  wyc 265e5f9817 Merge branch 'refs/heads/feat-hr-psms_1.0' 1 долоо хоног өмнө
  wyc 959ffe3f93 feat(hr): 完善年度调整与贡献积分计算逻辑 1 долоо хоног өмнө
13 өөрчлөгдсөн 396 нэмэгдсэн , 137 устгасан
  1. 2 0
      code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/FormConstant.java
  2. 37 11
      code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/enums/psms/ScoreItemEnum.java
  3. 27 27
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/AnnualAdjustmentData.java
  4. 64 10
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/AnnualAdjustmentService.java
  5. 1 1
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/ContributionConstant.java
  6. 166 32
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/ContributionHelper.java
  7. 24 24
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ContribBillFormPlugin.java
  8. 32 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ContribLillListPlugin.java
  9. 5 12
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ScoreItemConfFormPlugin.java
  10. 13 3
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/adjust/NewDynamicAdjustmentOperationPlugIn.java
  11. 11 11
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/contribution/ContribBillOpPlugin.java
  12. 9 2
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/initial/BaseInitialOperationPlugIn.java
  13. 5 4
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/report/adjust/UnAdjustedReportReportListDataPlugin.java

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

@@ -141,6 +141,8 @@ public class FormConstant {
     public static final String ORG_KEY = "ORG";
     /** 创建组织*/
     public static final String CREATEORG_KEY = "createorg";
+    /** 原创建组织*/
+    public static final String SRCCREATEORG_KEY = "srccreateorg";
     /** 所属单位*/
     public static final String USEORG_KEY = "useorg";
     /** 分录行号 */

+ 37 - 11
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/enums/psms/ScoreItemEnum.java

@@ -12,23 +12,24 @@ import java.util.Map;
 public enum ScoreItemEnum {
 
     /**科研与创新积分*/
-    RESEARCH_SCORE("1", "科研与创新积分"),
+    RESEARCH_SCORE("01", "科研与创新积分","nckd_contribbill_a"),
     /**专利申报积分*/
-    PATENT_SCORE("2", "专利申报积分"),
+    PATENT_SCORE("02", "专利申报积分","nckd_contribbill_b"),
     /**论文发表积分*/
-    PAPER_SCORE("3", "论文发表积分"),
+    PAPER_SCORE("03", "论文发表积分","nckd_contribbill_c"),
     /**技能竞赛积分*/
-    SKILL_CONTEST_SCORE("4", "技能竞赛积分"),
+    SKILL_CONTEST_SCORE("04", "技能竞赛积分","nckd_contribbill_d"),
     /**培训教材积分*/
-    TRAINING_MATERIAL_SCORE("5", "培训教材积分"),
+    TRAINING_MATERIAL_SCORE("05", "培训教材积分","nckd_contribbill_e"),
     /**技术标准积分*/
-    TECH_STANDARD_SCORE("6", "技术标准积分"),
+    TECH_STANDARD_SCORE("06", "技术标准积分","nckd_contribbill_f"),
     /**管理规范积分*/
-    MGMT_SPEC_SCORE("7", "管理规范积分"),
-    /**培训授课积分*/
-    TRAINING_SCORE("8", "培训授课积分"),
+    MGMT_SPEC_SCORE("07", "管理规范积分","nckd_contribbill_g"),
     /**师带徒积分*/
-    MENTOR_SCORE("9", "师带徒积分");
+    MENTOR_SCORE("08", "师带徒积分","nckd_contribbill_h"),
+    /**培训授课积分*/
+    TRAINING_SCORE("09", "培训授课积分","nckd_contribbill_i");
+
 
     private static final Map<String, ScoreItemEnum> CODE_MAP = new HashMap<>();
 
@@ -40,10 +41,12 @@ public enum ScoreItemEnum {
 
     private final String code;
     private final String name;
+    private final String pageId;
 
-    ScoreItemEnum(String code, String name) {
+    ScoreItemEnum(String code, String name,String pageId) {
         this.code = code;
         this.name = name;
+        this.pageId = pageId;
     }
 
     /**
@@ -59,6 +62,22 @@ public enum ScoreItemEnum {
         }
         return CODE_MAP.get(code);
     }
+    
+    /**
+     * 根据页面标识获取枚举
+      * @param pageId
+     * @return: nckd.jxccl.base.common.enums.psms.ScoreItemEnum
+     * @author W.Y.C
+     * @date: 2025/10/26 21:45
+     */
+    public static ScoreItemEnum getByPageId(String pageId) {
+        for (ScoreItemEnum value : ScoreItemEnum.values()) {
+            if (value.pageId.equals(pageId)) {
+                return value;
+            }
+        }
+        return null;
+    }
 
 
     public String getCode() {
@@ -68,4 +87,11 @@ public enum ScoreItemEnum {
     public String getName() {
         return name;
     }
+
+    public String getPageId() {
+		return pageId;
+	}
+
+
+
 }

+ 27 - 27
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/AnnualAdjustmentData.java

@@ -118,31 +118,31 @@ public class AnnualAdjustmentData {
     private DynamicObject lastJobLevel;
 
     /** 年度分项得分A(yearscoresuma) */
-    private Double yearscoresuma;
+    private BigDecimal yearscoresuma;
 
     /** 年度分项得分B(yearscoresumb) */
-    private Double yearscoresumb;
+    private BigDecimal yearscoresumb;
 
     /** 年度分项得分C(yearscoresumc) */
-    private Double yearscoresumc;
+    private BigDecimal yearscoresumc;
 
     /** 年度分项得分D(yearscoresumd) */
-    private Double yearscoresumd;
+    private BigDecimal yearscoresumd;
 
     /** 年度分项得分E(yearscoresume) */
-    private Double yearscoresume;
+    private BigDecimal yearscoresume;
 
     /** 年度分项得分F(yearscoresumf) */
-    private Double yearscoresumf;
+    private BigDecimal yearscoresumf;
 
     /** 年度分项得分G(yearscoresumg) */
-    private Double yearscoresumg;
+    private BigDecimal yearscoresumg;
 
     /** 年度分项得分H(yearscoresumh) */
-    private Double yearscoresumh;
+    private BigDecimal yearscoresumh;
 
     /** 年度分项得分I(yearscoresumi) */
-    private Double yearscoresumi;
+    private BigDecimal yearscoresumi;
 
     public String getPersonName() { return personName; }
     public void setPersonName(String personName) { this.personName = personName; }
@@ -214,24 +214,24 @@ public class AnnualAdjustmentData {
         this.lastJobLevel = lastJobLevel;
     }
 
-    public Double getYearscoresuma() { return yearscoresuma; }
-    public void setYearscoresuma(Double yearscoresuma) { this.yearscoresuma = yearscoresuma; }
-    public Double getYearscoresumb() { return yearscoresumb; }
-    public void setYearscoresumb(Double yearscoresumb) { this.yearscoresumb = yearscoresumb; }
-    public Double getYearscoresumc() { return yearscoresumc; }
-    public void setYearscoresumc(Double yearscoresumc) { this.yearscoresumc = yearscoresumc; }
-    public Double getYearscoresumd() { return yearscoresumd; }
-    public void setYearscoresumd(Double yearscoresumd) { this.yearscoresumd = yearscoresumd; }
-    public Double getYearscoresume() { return yearscoresume; }
-    public void setYearscoresume(Double yearscoresume) { this.yearscoresume = yearscoresume; }
-    public Double getYearscoresumf() { return yearscoresumf; }
-    public void setYearscoresumf(Double yearscoresumf) { this.yearscoresumf = yearscoresumf; }
-    public Double getYearscoresumg() { return yearscoresumg; }
-    public void setYearscoresumg(Double yearscoresumg) { this.yearscoresumg = yearscoresumg; }
-    public Double getYearscoresumh() { return yearscoresumh; }
-    public void setYearscoresumh(Double yearscoresumh) { this.yearscoresumh = yearscoresumh; }
-    public Double getYearscoresumi() { return yearscoresumi; }
-    public void setYearscoresumi(Double yearscoresumi) { this.yearscoresumi = yearscoresumi; }
+    public BigDecimal getYearscoresuma() { return yearscoresuma; }
+    public void setYearscoresuma(BigDecimal yearscoresuma) { this.yearscoresuma = yearscoresuma; }
+    public BigDecimal getYearscoresumb() { return yearscoresumb; }
+    public void setYearscoresumb(BigDecimal yearscoresumb) { this.yearscoresumb = yearscoresumb; }
+    public BigDecimal getYearscoresumc() { return yearscoresumc; }
+    public void setYearscoresumc(BigDecimal yearscoresumc) { this.yearscoresumc = yearscoresumc; }
+    public BigDecimal getYearscoresumd() { return yearscoresumd; }
+    public void setYearscoresumd(BigDecimal yearscoresumd) { this.yearscoresumd = yearscoresumd; }
+    public BigDecimal getYearscoresume() { return yearscoresume; }
+    public void setYearscoresume(BigDecimal yearscoresume) { this.yearscoresume = yearscoresume; }
+    public BigDecimal getYearscoresumf() { return yearscoresumf; }
+    public void setYearscoresumf(BigDecimal yearscoresumf) { this.yearscoresumf = yearscoresumf; }
+    public BigDecimal getYearscoresumg() { return yearscoresumg; }
+    public void setYearscoresumg(BigDecimal yearscoresumg) { this.yearscoresumg = yearscoresumg; }
+    public BigDecimal getYearscoresumh() { return yearscoresumh; }
+    public void setYearscoresumh(BigDecimal yearscoresumh) { this.yearscoresumh = yearscoresumh; }
+    public BigDecimal getYearscoresumi() { return yearscoresumi; }
+    public void setYearscoresumi(BigDecimal yearscoresumi) { this.yearscoresumi = yearscoresumi; }
 
     public DynamicObject getLastJobSeq() {
         return lastJobSeq;

+ 64 - 10
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/AnnualAdjustmentService.java

@@ -6,10 +6,12 @@ import kd.bos.entity.constant.StatusEnum;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.user.UserServiceHelper;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.enums.AppraisalResultEnum;
 import nckd.jxccl.base.common.enums.psms.AdjustTypeEnum;
 import nckd.jxccl.base.common.enums.psms.JobSeqEnum;
+import nckd.jxccl.base.common.enums.psms.ScoreItemEnum;
 import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
 import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.base.common.utils.ConvertUtil;
@@ -18,6 +20,7 @@ import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 import nckd.jxccl.hr.psms.common.bo.PositionAppointmentBO;
+import nckd.jxccl.hr.psms.helper.ContributionHelper;
 import nckd.jxccl.hr.psms.helper.PositionFileHelper;
 import org.apache.commons.lang3.StringUtils;
 
@@ -25,6 +28,7 @@ import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.StringJoiner;
@@ -223,17 +227,15 @@ public class AnnualAdjustmentService {
 
         ac.whyAdjust1.add(StrFormatter.format("选择的调整时间:【{}】", DateUtil.format(adjustDate,DateUtil.NORM_DATE_PATTERN)));
 
+        AnnualAdjustmentData data = new AnnualAdjustmentData();
 
-        //对应SHR:291行;utils.YearContributeScoreBillEntryScoreSumBypersonidAndYear
-        //TODO 1、获取年度贡献积分
-        //yearscoresuma、yearscoresumb、yearscoresumc、yearscoresumd、yearscoresume、yearscoresumf、yearscoresumg、yearscoresumh、yearscoresumi、allyearscoresum、yearscoresuma
 
-        //2、获取上年度考核结果(对应SHR:PersonpositionfileUtils:884~914行)
+        //1、获取上年度考核结果(对应SHR:PersonpositionfileUtils:884~914行)
         // DynamicObject performanceResult = PerformanceManagerHelper.getPerformanceResult(ac.personId, lastYearDateTime);
         if(performanceResult == null){
             throw new ValidationException(StrFormatter.format("人员【{}】缺少【{}】年考核结果", ac.personName,lastYear));
         }
-        AnnualAdjustmentData data = new AnnualAdjustmentData();
+
         data.setAppraisalResult(performanceResult);
         data.setAppraisalResultNumber(performanceResult.getString(FormConstant.NUMBER_KEY));
         data.setAppraisalResultName(performanceResult.getString(FormConstant.NAME_KEY));
@@ -241,12 +243,12 @@ public class AnnualAdjustmentService {
         data.setAppraisalResultScore(performanceResult.getBigDecimal(FormConstant.NCKD_SCORE));
 
 
-        //3.获取员工上年度年度R排名(对应SHR:PersonpositionfileUtils:915~945行)
+        //2.获取员工上年度年度R排名(对应SHR:PersonpositionfileUtils:915~945行)
         DynamicObject lastPersonPosFile = null;
         JobLevelCalculatorService.RankingResultInfo rankingInfo = JobLevelCalculatorService.getRankingInfo(ac.personId, ac.personName, beginDate == null ? new Date() : beginDate);
         data.setRankingResultInfo(rankingInfo);
 
-        //4.查询上一条有效年度调整记录(对应SHR:PersonpositionfileUtils:946~997行)
+        //3.查询上一条有效年度调整记录(对应SHR:PersonpositionfileUtils:946~997行)
         DynamicObject[] personPosFileByPersonAndState = PositionFileHelper.getPersonPosFileByPersonAndState(ac.personId,
                 new String[]{"3","4"},
                 null,null,
@@ -315,6 +317,49 @@ public class AnnualAdjustmentService {
         }
 
 
+        //4、获取年度贡献积分
+        //对应SHR:291行;utils.YearContributeScoreBillEntryScoreSumBypersonidAndYear
+        List<ContributionHelper.ScoreItemValidScore> scoreItemAccumulateScore = ContributionHelper.getApprovedScoreItemAccumulateScore(new Long[]{ac.personId}, DateUtil.toDate(lastYearDateTime));
+        //计算出最多可得的分数(根据积分配置项)
+        List<ContributionHelper.ScoreItemValidScore> allowedScoreList = ContributionHelper.calculateMaxAllowedScore(scoreItemAccumulateScore);
+        BigDecimal allowedScoreSum = BigDecimal.ZERO;
+        for (ContributionHelper.ScoreItemValidScore allowedScore : allowedScoreList) {
+            String scoreItemNumber = allowedScore.getScoreItemNumber();
+            ScoreItemEnum scoreItemEnum = ScoreItemEnum.getByCode(scoreItemNumber);
+            BigDecimal validScore = allowedScore.getValidScore();
+            if(ScoreItemEnum.RESEARCH_SCORE == scoreItemEnum){
+                data.setYearscoresuma(validScore);
+            } else if(ScoreItemEnum.PATENT_SCORE == scoreItemEnum){
+                data.setYearscoresumb(validScore);
+            } else if(ScoreItemEnum.PAPER_SCORE == scoreItemEnum){
+                data.setYearscoresumc(validScore);
+            } else if(ScoreItemEnum.SKILL_CONTEST_SCORE == scoreItemEnum){
+                data.setYearscoresumd(validScore);
+            } else if(ScoreItemEnum.TRAINING_MATERIAL_SCORE == scoreItemEnum) {
+                data.setYearscoresume(validScore);
+            } else if(ScoreItemEnum.TECH_STANDARD_SCORE == scoreItemEnum){
+                data.setYearscoresumf(validScore);
+            } else if(ScoreItemEnum.MGMT_SPEC_SCORE == scoreItemEnum){
+                data.setYearscoresumg(validScore);
+            } else if(ScoreItemEnum.MENTOR_SCORE == scoreItemEnum){
+                data.setYearscoresumh(validScore);
+            } else if(ScoreItemEnum.TRAINING_SCORE == scoreItemEnum){
+                data.setYearscoresumi(validScore);
+            }
+            allowedScoreSum = allowedScoreSum.add(validScore);
+
+            //未受限制的实际累计总分
+            BigDecimal sumScore = allowedScore.getSumScore();
+            //比较实际累计总分和未受限制的实际累计总分
+            if(sumScore.compareTo(validScore) != 0){
+                //实际累计积分与有效积分不符,说明被限高
+                ac.whyAdjust1.add(StrFormatter.format("上年度【{}】【{}】积分实际累计总分为【{}】但达到项目最高分限制,最终有效应用分为【{}】;", scoreItemEnum.getCode(), sumScore, validScore));
+            }
+
+        }
+        data.setAllYearScoreSum(allowedScoreSum);
+
+
         //5.获取员工任职信息(对应SHR:PersonpositionfileUtils:998~1009行)
         // PositionAppointmentBO positionAppointment = PositionStructureHelper.positionAppointmentQuery(ac.personId, beginDate == null ? new Date() : beginDate);
         DynamicObject perEduExp = positionAppointment.getPerEduExp();
@@ -740,13 +785,22 @@ public class AnnualAdjustmentService {
 
         DynamicObject empPosOrgRel = ac.positionAppointment.getEmpPosOrgRel();
         newPersonPosFile.set(PositionStructureConstant.NCKD_PERSON, ac.personInfo);
+
+        //管理组织
+        newPersonPosFile.set(PositionStructureConstant.ORG_KEY, UserServiceHelper.getUserMainOrgId(UserServiceHelper.getCurrentUserId()));
+
         DynamicObject company = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORGHR_ENTITYID);
         company.set(FormConstant.ID_KEY, empPosOrgRel.getLong(String.join(".",FormConstant.COMPANY_KEY,FormConstant.ID_KEY)));
-        newPersonPosFile.set(PositionStructureConstant.USEORG_KEY, company);
+        //创建组织
+        newPersonPosFile.set(PositionStructureConstant.CREATEORG_KEY, company);
+        //原创建组织
+        newPersonPosFile.set(PositionStructureConstant.SRCCREATEORG_KEY, company);
+
+        //使用组织
         DynamicObject dep = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORGHR_ENTITYID);
         dep.set(FormConstant.ID_KEY, empPosOrgRel.getLong(String.join(".",FormConstant.ADMINORG,FormConstant.ID_KEY)));
-        newPersonPosFile.set(PositionStructureConstant.ORG_KEY, dep);
-        newPersonPosFile.set(PositionStructureConstant.CREATEORG_KEY, dep);
+        newPersonPosFile.set(PositionStructureConstant.USEORG_KEY, dep);
+
         newPersonPosFile.set(PositionStructureConstant.NCKD_TYPESTATE, "3");
         newPersonPosFile.set(PositionStructureConstant.NCKD_EXECUTEYEAR, ac.executeYear);
         Long positionId = empPosOrgRel.getLong(String.join(".",FormConstant.POSITION_KEY,FormConstant.ID_KEY));

+ 1 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/ContributionEvaluationConstant.java → code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/ContributionConstant.java

@@ -11,7 +11,7 @@ import nckd.jxccl.base.common.constant.FormConstant;
 * @date 2025/10/22 21:53
 * @version 1.0
 */
-public class ContributionEvaluationConstant extends FormConstant {
+public class ContributionConstant extends FormConstant {
 
 
 

+ 166 - 32
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/helper/ContributionHelper.java

@@ -12,12 +12,13 @@ import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
-import nckd.jxccl.hr.psms.common.ContributionEvaluationConstant;
+import nckd.jxccl.hr.psms.common.ContributionConstant;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -35,7 +36,7 @@ public class ContributionHelper {
      * 根据人员获取积分项目有效分数
      * 依据人员某年度已获得的积分(含在途单据)+积分配置的最高分计算出可获得的分数
      *
-     * @param scoreItemValidScoreList 待计算列表
+     * @param scoreItemValidScoreList 待计算列表(人员不能重复)
      * @param year 年份
      * @param excludeBillId 排除的单据ID(计算有效分数不含当前单据),可为空
      * @return: ScoreItemValidScore
@@ -121,33 +122,43 @@ public class ContributionHelper {
         List<ScoreItemValidScore> result = getScoreItemValidScore(inputList, year, excludeBillId);
     }
 
+
     /**
      * 根据人员和年度获取积分项目已累计分数
      * @param personIds 人员
      * @param year 年度
      * @param excludeBillId 排除的单据ID(计算有效分数不含当前单据),可为空
+     * @param approvedOnly 是否只查询已审批通过的记录
      * @return: List<ScoreItemValidScore> 积分项目已累计分数
      * @author W.Y.C
      * @date: 2025/10/26 16:20
      */
-    public static List<ScoreItemValidScore> getScoreItemAccumulateScore(Long[] personIds, Date year, Long excludeBillId) {
+    public static List<ScoreItemValidScore> getScoreItemAccumulateScore(Long[] personIds, Date year, Long excludeBillId, boolean approvedOnly) {
         if (personIds == null || personIds.length == 0) {
             return new ArrayList<>();
         }
 
         LocalDateTime yearStarDateTime = DateUtil.beginOfYear(DateUtil.toLocalDateTime(year));
         QueryFieldBuilder scoreItemConfFieldBuilder = QueryFieldBuilder.create()
-                .add(ContributionEvaluationConstant.NCKD_YEAR)
-                .addIdNumberName(ContributionEvaluationConstant.NCKD_SCOREITEM)
-                .addIdNumberName(ContributionEvaluationConstant.NCKD_SCOREITEMSUB)
-                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY,ContributionEvaluationConstant.NCKD_PERSON},FormConstant.ID_KEY)
-                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionEvaluationConstant.NCKD_SCORE,ContributionEvaluationConstant.NCKD_ORISCORE);
-
-        //查询非"审批不通过"、"已废弃"年度贡献积分
-        QFilter filter = new QFilter(FormConstant.BILL_STATUS_KEY, QCP.not_in, new String[]{"E", "F"})
-                .and(ContributionEvaluationConstant.NCKD_YEAR,QCP.large_equals,DateUtil.beginOfDay(yearStarDateTime))
-                .and(ContributionEvaluationConstant.NCKD_YEAR,QCP.less_equals, DateUtil.endOfDay(yearStarDateTime))
-                .and(String.join( ".",FormConstant.NCKD_ENTRYENTITY,ContributionEvaluationConstant.NCKD_PERSON),QCP.in,personIds);
+                .add(ContributionConstant.NCKD_YEAR)
+                .addIdNumberName(ContributionConstant.NCKD_SCOREITEM)
+                .addIdNumberName(ContributionConstant.NCKD_SCOREITEMSUB)
+                .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;
+        if (approvedOnly) {
+            //只查询"已审批通过"年度贡献积分
+            filter = QFilterCommonHelper.getBillStatusFilter();
+        } else {
+            //查询非"审批不通过"、"已废弃"年度贡献积分
+            filter = new QFilter(FormConstant.BILL_STATUS_KEY, QCP.not_in, new String[]{"E", "F"});
+        }
+
+        filter.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);
 
         if(excludeBillId != null && excludeBillId > 0){
             filter.and(FormConstant.ID_KEY,QCP.not_equals,excludeBillId);
@@ -156,31 +167,59 @@ public class ContributionHelper {
         List<ScoreItemValidScore> scoreItemValidScoreList = new ArrayList<>();
         try(AlgoContext context = Algo.newContext()) {
             DataSet dateSet = QueryServiceHelper.queryDataSet(ContributionHelper.class.getName(),
-                    ContributionEvaluationConstant.CONTRIBBILL_ENTITYID,
+                    ContributionConstant.CONTRIBBILL_ENTITYID,
                     scoreItemConfFieldBuilder.buildSelect(),
                     new QFilter[]{filter}, null, 5000);
 
             DataSet sumDateSet = dateSet.copy()
                     // 按人员、积分项目、积分项目子项进行分组
-                    .groupBy(new String[]{String.join(".", ContributionEvaluationConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_PERSON, FormConstant.ID_KEY),
-                            String.join(".", ContributionEvaluationConstant.NCKD_SCOREITEM, FormConstant.ID_KEY),
-                            String.join(".", ContributionEvaluationConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY)})
-                    .sum(String.join(".", ContributionEvaluationConstant.NCKD_ENTRYENTITY, FormConstant.NCKD_SCORE),"sumScore").finish();
+                    .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),
+                            String.join(".", ContributionConstant.NCKD_SCOREITEMSUB, FormConstant.ID_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(".", ContributionEvaluationConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_PERSON, FormConstant.ID_KEY));
-                Long scoreItemId = row.getLong(String.join(".", ContributionEvaluationConstant.NCKD_SCOREITEM, FormConstant.ID_KEY));
-                Long scoreItemSubId = row.getLong(String.join(".", ContributionEvaluationConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY));
+                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));
+                Long scoreItemSubId = row.getLong(String.join(".", ContributionConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY));
                 //已获得的累计积分
                 BigDecimal sumScore = row.getBigDecimal("sumScore");
-                ScoreItemValidScore scoreItemValidScore = new ScoreItemValidScore(personId, scoreItemId, scoreItemSubId, sumScore);
+                ScoreItemValidScore scoreItemValidScore = new ScoreItemValidScore(personId, scoreItemId,scoreItemNumber, scoreItemSubId, sumScore);
                 scoreItemValidScoreList.add(scoreItemValidScore);
             }
         }
         return scoreItemValidScoreList;
     }
 
+    /**
+     * 根据人员和年度获取积分项目已累计分数(包含所有未废弃记录)
+     * @param personIds 人员
+     * @param year 年度
+     * @param excludeBillId 排除的单据ID(计算有效分数不含当前单据),可为空
+     * @return: List<ScoreItemValidScore> 积分项目已累计分数
+     * @author W.Y.C
+     * @date: 2025/10/26 16:20
+     */
+    public static List<ScoreItemValidScore> getScoreItemAccumulateScore(Long[] personIds, Date year, Long excludeBillId) {
+        return getScoreItemAccumulateScore(personIds, year, excludeBillId, false);
+    }
+
+    /**
+     * 根据人员和年度获取已审批通过的积分项目累计分数
+     * @param personIds 人员
+     * @param year 年度
+     * @return: List<ScoreItemValidScore> 积分项目已累计分数(仅包含已审批通过的记录)
+     * @author W.Y.C
+     * @date: 2025/10/26 16:20
+     */
+    public static List<ScoreItemValidScore> getApprovedScoreItemAccumulateScore(Long[] personIds, Date year) {
+        return getScoreItemAccumulateScore(personIds, year, null, true);
+    }
+
+
     /**
      * 计算可获得的有效分数
      * 基于累计总分和限制分数,计算还可以获得多少分数(不超过限制)
@@ -188,7 +227,7 @@ public class ContributionHelper {
      * @param scoreConfMap 分数配置映射表,key为配置ID,value为限分数值
      * @param scoreItemId 积分项目ID
      * @param scoreItemSubId 具体积分项目ID
-     * @param accumulatedScore 累计总分
+     * @param accumulatedScore 累计总分
      * @return 可获得的有效分数
      *         如果没有任何限制返回null
      *         如果已超过限制返回BigDecimal.ZERO
@@ -245,6 +284,92 @@ public class ContributionHelper {
         return availableScore;
     }
 
+    /**
+     * 计算最多可得的分数
+     * 根据累计积分和分数配置映射表,如果超过配置的限制分数则返回限制分最大分数,
+     * 计算每个积分大项在考虑双重限制条件下的最大可获得分数:
+     * 1. 子项限制:每个具体积分项目子项可能有分数上限
+     * 2. 大项限制:整个积分大项可能有总分上限
+     *
+     * @param scoreItemValidScoreList 某个人员所有积分项目的累计积分(personId、scoreItemId、scoreItemSubId、sumScore有值)
+     * @return 最多可得的分数列表(按大项维度聚合)
+     * @author W.Y.C
+     * @date: 2025/10/27
+     */
+    public static List<ScoreItemValidScore> calculateMaxAllowedScore(List<ScoreItemValidScore> scoreItemValidScoreList) {
+
+        //获取积分限分配置
+        Map<Long, BigDecimal> scoreConfMap = ContributionHelper.getScoreConf();
+
+        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);
+
+            // 计算大项总分(按子项分组后求和)
+            Map<Long, BigDecimal> subItemSumMap = new HashMap<>();
+            for (ScoreItemValidScore item : valueList) {
+                Long subItemId = item.getScoreItemSubId();
+                BigDecimal score = item.getSumScore() == null ? BigDecimal.ZERO : item.getSumScore();
+                subItemSumMap.merge(subItemId, score, BigDecimal::add);
+            }
+
+            // 计算未受限制的实际总分
+            BigDecimal actualTotalScore = BigDecimal.ZERO;
+            for (BigDecimal subItemScore : subItemSumMap.values()) {
+                actualTotalScore = actualTotalScore.add(subItemScore);
+            }
+
+
+            // 计算每个子项的有效分数并求和
+            BigDecimal totalAllowedScore = BigDecimal.ZERO;
+            for (Map.Entry<Long, BigDecimal> subEntry : subItemSumMap.entrySet()) {
+                Long subItemId = subEntry.getKey();
+                BigDecimal subItemSumScore = subEntry.getValue();
+
+                // 获取子项限制分数
+                BigDecimal scoreItemSubMaxScore = null;
+                if (subItemId != null && subItemId > 0) {
+                    scoreItemSubMaxScore = scoreConfMap.get(subItemId);
+                }
+
+                // 子项限制后的分数(优先考虑子项限制)
+                BigDecimal allowedSubScore = subItemSumScore;
+                if (scoreItemSubMaxScore != null && scoreItemSubMaxScore.compareTo(BigDecimal.ZERO) > 0) {
+                    allowedSubScore = subItemSumScore.min(scoreItemSubMaxScore);
+                }
+
+                totalAllowedScore = totalAllowedScore.add(allowedSubScore);
+            }
+
+            // 如果大项有限制,需要检查是否超过大项限制
+            if (scoreItemMaxScore != null && scoreItemMaxScore.compareTo(BigDecimal.ZERO) > 0) {
+                totalAllowedScore = totalAllowedScore.min(scoreItemMaxScore);
+            }
+
+            // 创建结果对象,只包含scoreItemId和validScore
+            ScoreItemValidScore resultItem = new ScoreItemValidScore(null, scoreItemId, null);
+            String scoreItemNumber = null;
+            if (!valueList.isEmpty() && valueList.get(0) != null) {
+                scoreItemNumber = valueList.get(0).getScoreItemNumber();
+            }
+            resultItem.setScoreItemNumber(scoreItemNumber);
+            resultItem.setValidScore(totalAllowedScore);
+            resultItem.setSumScore(actualTotalScore);
+            result.add(resultItem);
+        }
+
+        return result;
+    }
+
     /**
      * 决定使用哪种累计分数
      * @param scoreConfMap 分数配置映射
@@ -274,25 +399,25 @@ public class ContributionHelper {
     public static Map<Long, BigDecimal> getScoreConf() {
         //查询积分项目分数配置
         QueryFieldBuilder scoreItemConfFieldBuilder = QueryFieldBuilder.create()
-                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_SCOREITEM)
-                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_SCOREITEMSUB)
-                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionEvaluationConstant.NCKD_MAXSCORE);
+                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM)
+                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB)
+                .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, ContributionConstant.NCKD_MAXSCORE);
 
-        DynamicObjectCollection scoreItemConfQuery = QueryServiceHelper.query(ContributionEvaluationConstant.SCOREITEMCONF_ENTITYID,
+        DynamicObjectCollection scoreItemConfQuery = QueryServiceHelper.query(ContributionConstant.SCOREITEMCONF_ENTITYID,
                 scoreItemConfFieldBuilder.buildSelect(),
                 new QFilter[]{QFilterCommonHelper.getEnableFilter()});
 
         //scoreMap:key为积分项目子项ID(项目子项为空时key为项目大项),value为积分项目对应的最大分数
         Map<Long, BigDecimal> scoreMap = scoreItemConfQuery.stream().collect(Collectors.toMap(
                 item -> {
-                    long scoreItemSubId = item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY));
+                    long scoreItemSubId = item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEMSUB, FormConstant.ID_KEY));
                     if (scoreItemSubId <= 0) {
-                        return item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_SCOREITEM, FormConstant.ID_KEY));
+                        return item.getLong(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_SCOREITEM, FormConstant.ID_KEY));
                     } else {
                         return scoreItemSubId;
                     }
                 },
-                item -> item.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionEvaluationConstant.NCKD_MAXSCORE)),
+                item -> item.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_MAXSCORE)),
                 //处理重复key的情况,取最大值
                 (existing, replacement) -> existing.max(replacement)
         ));
@@ -302,6 +427,7 @@ public class ContributionHelper {
     public static class ScoreItemValidScore{
         private Long personId;
         private Long scoreItemId;
+        private String scoreItemNumber;
         private Long scoreItemSubId;
         /**本次积分*/
         private BigDecimal currentScore;
@@ -317,9 +443,10 @@ public class ContributionHelper {
             this.scoreItemSubId = scoreItemSubId;
         }
 
-        public ScoreItemValidScore(Long personId, Long scoreItemId, Long scoreItemSubId, BigDecimal sumScore) {
+        public ScoreItemValidScore(Long personId, Long scoreItemId,String scoreItemNumber, Long scoreItemSubId, BigDecimal sumScore) {
             this.personId = personId;
             this.scoreItemId = scoreItemId;
+            this.scoreItemNumber = scoreItemNumber;
             this.scoreItemSubId = scoreItemSubId;
             this.sumScore = sumScore;
         }
@@ -348,6 +475,13 @@ public class ContributionHelper {
             this.scoreItemId = scoreItemId;
         }
 
+        public String getScoreItemNumber() {
+            return scoreItemNumber;
+        }
+        public void setScoreItemNumber(String scoreItemNumber) {
+            this.scoreItemNumber = scoreItemNumber;
+        }
+
         public Long getScoreItemSubId() {
             return scoreItemSubId;
         }

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

@@ -14,7 +14,7 @@ import kd.bos.orm.query.QFilter;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.ConvertUtil;
-import nckd.jxccl.hr.psms.common.ContributionEvaluationConstant;
+import nckd.jxccl.hr.psms.common.ContributionConstant;
 import nckd.jxccl.hr.psms.helper.ContributionHelper;
 
 import java.math.BigDecimal;
@@ -37,12 +37,12 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
     public void registerListener(EventObject e) {
         super.registerListener(e);
         // 积分具体项目字段添加值变化监听
-        BasedataEdit scoreItemSubField = this.getView().getControl(ContributionEvaluationConstant.NCKD_SCOREITEMSUB);
+        BasedataEdit scoreItemSubField = this.getView().getControl(ContributionConstant.NCKD_SCOREITEMSUB);
         if (scoreItemSubField != null) {
             scoreItemSubField.addBeforeF7SelectListener(this);
         }
 
-        BasedataEdit scoreItemRankField = this.getView().getControl(ContributionEvaluationConstant.NCKD_SCOREITEMRANK);
+        BasedataEdit scoreItemRankField = this.getView().getControl(ContributionConstant.NCKD_SCOREITEMRANK);
         if (scoreItemRankField != null) {
             scoreItemRankField.addBeforeF7SelectListener(this);
         }
@@ -51,15 +51,15 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
     @Override
     public void beforeF7Select(BeforeF7SelectEvent beforeF7SelectEvent) {
         String fieldKey = beforeF7SelectEvent.getProperty().getName();
-        if (ContributionEvaluationConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(fieldKey) || ContributionEvaluationConstant.NCKD_SCOREITEMRANK.equalsIgnoreCase(fieldKey)) {
-            DynamicObject scoreItem = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionEvaluationConstant.NCKD_SCOREITEM));
+        if (ContributionConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(fieldKey) || ContributionConstant.NCKD_SCOREITEMRANK.equalsIgnoreCase(fieldKey)) {
+            DynamicObject scoreItem = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEM));
             if(scoreItem == null){
                 this.getView().showTipNotification("请先选择“积分项目”");
                 beforeF7SelectEvent.setCancel( true);
                 return;
             }
             // 构建过滤条件:假设B字段的F7列表关联实体中有一个字段与A字段值关联(例如"relatedField")
-            QFilter filter = new QFilter(ContributionEvaluationConstant.NCKD_SCOREITEM, QCP.equals, scoreItem.getLong(FormConstant.ID_KEY));
+            QFilter filter = new QFilter(ContributionConstant.NCKD_SCOREITEM, QCP.equals, scoreItem.getLong(FormConstant.ID_KEY));
             // 获取F7列表的显示参数并设置过滤条件
             ListShowParameter showParameter = (ListShowParameter) beforeF7SelectEvent.getFormShowParameter();
             showParameter.getListFilterParameter().setFilter(filter);
@@ -94,11 +94,11 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
      * @date: 2025/10/26 19:46
      */
     private boolean isScoreCalculationTriggerField(String fieldKey) {
-        return ContributionEvaluationConstant.NCKD_YEAR.equalsIgnoreCase(fieldKey)
-                || ContributionEvaluationConstant.NCKD_PERSON.equalsIgnoreCase(fieldKey)
-                || ContributionEvaluationConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(fieldKey)
-                || ContributionEvaluationConstant.NCKD_SCOREITEM.equalsIgnoreCase(fieldKey)
-                || ContributionEvaluationConstant.NCKD_ORISCORE.equalsIgnoreCase(fieldKey);
+        return ContributionConstant.NCKD_YEAR.equalsIgnoreCase(fieldKey)
+                || ContributionConstant.NCKD_PERSON.equalsIgnoreCase(fieldKey)
+                || ContributionConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(fieldKey)
+                || ContributionConstant.NCKD_SCOREITEM.equalsIgnoreCase(fieldKey)
+                || ContributionConstant.NCKD_ORISCORE.equalsIgnoreCase(fieldKey);
     }
 
     /**
@@ -111,11 +111,11 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
      */
     private void handleEntryRowChange(int rowIndex) {
         Long id = ConvertUtil.toLong(this.getModel().getValue(FormConstant.ID_KEY));
-        Date date = ConvertUtil.toDate(this.getModel().getValue(ContributionEvaluationConstant.NCKD_YEAR));
-        DynamicObject scoreItem = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionEvaluationConstant.NCKD_SCOREITEM));
-        DynamicObject scoreItemSub = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionEvaluationConstant.NCKD_SCOREITEMSUB));
-        DynamicObject person = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionEvaluationConstant.NCKD_PERSON, rowIndex));
-        BigDecimal oriScore = ConvertUtil.toBigDecimal(this.getModel().getValue(ContributionEvaluationConstant.NCKD_ORISCORE, rowIndex));
+        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 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
                 && oriScore != null && oriScore.compareTo(BigDecimal.ZERO) > 0) {
@@ -126,8 +126,8 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
                     scoreItemSub.getLong(FormConstant.ID_KEY));
             scoreItemValidScore.setCurrentScore(oriScore);
             ContributionHelper.getScoreItemValidScore(scoreItemValidScore, date, id);
-            this.getModel().setValue(ContributionEvaluationConstant.NCKD_SCORE, scoreItemValidScore.getValidScore(), rowIndex);
-            this.getView().updateView(ContributionEvaluationConstant.NCKD_SCORE, rowIndex);
+            this.getModel().setValue(ContributionConstant.NCKD_SCORE, scoreItemValidScore.getValidScore(), rowIndex);
+            this.getView().updateView(ContributionConstant.NCKD_SCORE, rowIndex);
         }
     }
 
@@ -141,9 +141,9 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
      */
     private void handleHeadFieldChange() {
         Long id = ConvertUtil.toLong(this.getModel().getValue(FormConstant.ID_KEY));
-        Date date = ConvertUtil.toDate(this.getModel().getValue(ContributionEvaluationConstant.NCKD_YEAR));
-        DynamicObject scoreItem = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionEvaluationConstant.NCKD_SCOREITEM));
-        DynamicObject scoreItemSub = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionEvaluationConstant.NCKD_SCOREITEMSUB));
+        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));
 
         if (date != null && scoreItem != null && scoreItemSub != null) {
             //重置分录所有分录的"录用积分"字段
@@ -151,8 +151,8 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
             List<ContributionHelper.ScoreItemValidScore> scoreItemValidScoreList = new ArrayList<>(entryEntity.size());
 
             for (int i = 0; i < entryEntity.size(); i++) {
-                DynamicObject person = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionEvaluationConstant.NCKD_PERSON, i));
-                BigDecimal oriScore = ConvertUtil.toBigDecimal(this.getModel().getValue(ContributionEvaluationConstant.NCKD_ORISCORE, i));
+                DynamicObject person = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_PERSON, i));
+                BigDecimal oriScore = ConvertUtil.toBigDecimal(this.getModel().getValue(ContributionConstant.NCKD_ORISCORE, i));
 
                 if(person != null && oriScore != null && oriScore.compareTo(BigDecimal.ZERO) > 0){
                     ContributionHelper.ScoreItemValidScore scoreItemValidScore = new ContributionHelper.ScoreItemValidScore(
@@ -168,7 +168,7 @@ public class ContribBillFormPlugin extends AbstractFormPlugin implements Plugin,
             if (!scoreItemValidScoreList.isEmpty()) {
                 ContributionHelper.getScoreItemValidScore(scoreItemValidScoreList, date, id);
                 for (ContributionHelper.ScoreItemValidScore scoreItemValidScore : scoreItemValidScoreList) {
-                    this.getModel().setValue(ContributionEvaluationConstant.NCKD_SCORE, scoreItemValidScore.getValidScore(), scoreItemValidScore.getRowIndex());
+                    this.getModel().setValue(ContributionConstant.NCKD_SCORE, scoreItemValidScore.getValidScore(), scoreItemValidScore.getRowIndex());
                 }
                 this.getView().updateView(FormConstant.NCKD_ENTRYENTITY);
             }

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

@@ -0,0 +1,32 @@
+package nckd.jxccl.hr.psms.plugin.form.contribution;
+
+import kd.bos.form.events.SetFilterEvent;
+import kd.bos.list.IListView;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.enums.psms.ScoreItemEnum;
+import nckd.jxccl.hr.psms.common.ContributionConstant;
+
+/**
+* 年度贡献积分单据列表插件
+* 实体标识:nckd_contribbill
+* @author W.Y.C
+* @date 2025/10/26 21:44
+* @version 1.0
+*/
+public class ContribLillListPlugin extends AbstractListPlugin implements Plugin {
+
+    @Override
+    public void setFilter(SetFilterEvent e) {
+        //获取单据标识,获取页面标识
+        String billFormId = ((IListView) this.getView()).getBillFormId();
+        ScoreItemEnum scoreItem = ScoreItemEnum.getByPageId(billFormId);
+        if(scoreItem != null) {
+            //根据不同页面过滤不同积分单据数据
+            e.addCustomQFilter(new QFilter(String.join(".",ContributionConstant.NCKD_SCOREITEM, FormConstant.NUMBER_KEY), QCP.equals, scoreItem.getCode()));
+        }
+    }
+}

+ 5 - 12
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/contribution/ScoreItemConfFormPlugin.java

@@ -1,10 +1,6 @@
 package nckd.jxccl.hr.psms.plugin.form.contribution;
 
 import kd.bos.dataentity.entity.DynamicObject;
-import kd.bos.entity.datamodel.events.ChangeData;
-import kd.bos.entity.datamodel.events.PropertyChangedArgs;
-import kd.bos.form.control.EntryGrid;
-import kd.bos.form.control.events.BaseDataColumnDependFieldSetEvent;
 import kd.bos.form.field.BasedataEdit;
 import kd.bos.form.field.events.BeforeF7SelectEvent;
 import kd.bos.form.field.events.BeforeF7SelectListener;
@@ -14,12 +10,9 @@ import kd.bos.orm.query.QFilter;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.ConvertUtil;
-import nckd.jxccl.hr.psms.common.ContributionEvaluationConstant;
-import nckd.jxccl.hr.psms.helper.ContributionHelper;
-import org.apache.commons.lang3.StringUtils;
+import nckd.jxccl.hr.psms.common.ContributionConstant;
 
 import java.util.EventObject;
-import java.util.Objects;
 
 /**
 * 积分项目分数配置插件
@@ -35,7 +28,7 @@ public class ScoreItemConfFormPlugin extends AbstractFormPlugin implements Plugi
         super.registerListener(e);
 
         // 为分录中的A字段添加值变化监听
-        BasedataEdit bFieldEdit = this.getView().getControl(ContributionEvaluationConstant.NCKD_SCOREITEMSUB);
+        BasedataEdit bFieldEdit = this.getView().getControl(ContributionConstant.NCKD_SCOREITEMSUB);
         if (bFieldEdit != null) {
             bFieldEdit.addBeforeF7SelectListener(this);
         }
@@ -48,19 +41,19 @@ public class ScoreItemConfFormPlugin extends AbstractFormPlugin implements Plugi
 
         //基础资料联动
         // 仅处理B字段的F7事件
-        if (ContributionEvaluationConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(fieldKey)) {
+        if (ContributionConstant.NCKD_SCOREITEMSUB.equalsIgnoreCase(fieldKey)) {
             // 获取当前分录行的行号
             int currentRow = e.getRow();
 
             if (currentRow >= 0) {
                 // 获取当前行A字段的值
-                DynamicObject fieldAValue = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionEvaluationConstant.NCKD_SCOREITEM, currentRow));
+                DynamicObject fieldAValue = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(ContributionConstant.NCKD_SCOREITEM, currentRow));
                 if(fieldAValue == null){
                     this.getView().showTipNotification("请先选择“积分项目”");
                     e.setCancel( true);
                     return;
                 }
-                QFilter filter = new QFilter(ContributionEvaluationConstant.NCKD_SCOREITEM, QCP.equals, fieldAValue.getLong(FormConstant.ID_KEY));
+                QFilter filter = new QFilter(ContributionConstant.NCKD_SCOREITEM, QCP.equals, fieldAValue.getLong(FormConstant.ID_KEY));
                 e.addCustomQFilter(filter);
             }
         }

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

@@ -17,6 +17,7 @@ import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.bos.servicehelper.user.UserServiceHelper;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.base.common.utils.DateUtil;
@@ -232,13 +233,22 @@ public class NewDynamicAdjustmentOperationPlugIn extends AbstractOperationServic
 
         DynamicObject empPosOrgRel = positionAppointment.getEmpPosOrgRel();
         newPersonPosFile.set(PositionStructureConstant.NCKD_PERSON, person);
+
+        //管理组织
+        newPersonPosFile.set(PositionStructureConstant.ORG_KEY, UserServiceHelper.getUserMainOrgId(UserServiceHelper.getCurrentUserId()));
         DynamicObject company = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORGHR_ENTITYID);
         company.set(FormConstant.ID_KEY, empPosOrgRel.getLong(String.join(".",FormConstant.COMPANY_KEY,FormConstant.ID_KEY)));
-        newPersonPosFile.set(PositionStructureConstant.USEORG_KEY, company);
+        //创建组织
+        newPersonPosFile.set(PositionStructureConstant.CREATEORG_KEY, company);
+        //原创建组织
+        newPersonPosFile.set(PositionStructureConstant.SRCCREATEORG_KEY, company);
+        //使用组织
         DynamicObject dep = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORGHR_ENTITYID);
         dep.set(FormConstant.ID_KEY, empPosOrgRel.getLong(String.join(".",FormConstant.ADMINORG,FormConstant.ID_KEY)));
-        newPersonPosFile.set(PositionStructureConstant.ORG_KEY, dep);
-        newPersonPosFile.set(PositionStructureConstant.CREATEORG_KEY, dep);
+        newPersonPosFile.set(PositionStructureConstant.USEORG_KEY, dep);
+
+
+
         newPersonPosFile.set(PositionStructureConstant.NCKD_TYPESTATE, "4");
         newPersonPosFile.set(PositionStructureConstant.NCKD_EXECUTEYEAR, DateUtil.getYear(adjustDate));
         Long positionId = empPosOrgRel.getLong(String.join(".",FormConstant.POSITION_KEY,FormConstant.ID_KEY));

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

@@ -17,7 +17,7 @@ import kd.bos.form.MessageBoxResult;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.StrFormatter;
-import nckd.jxccl.hr.psms.common.ContributionEvaluationConstant;
+import nckd.jxccl.hr.psms.common.ContributionConstant;
 import nckd.jxccl.hr.psms.helper.ContributionHelper;
 
 import java.math.BigDecimal;
@@ -47,7 +47,7 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
                 //校验参与人数
                 for (ExtendedDataEntity dataEntity : this.getDataEntities()) {
                     DynamicObject data = dataEntity.getDataEntity();
-                    int participants = data.getInt(ContributionEvaluationConstant.NCKD_PARTICIPANTS);
+                    int participants = data.getInt(ContributionConstant.NCKD_PARTICIPANTS);
                     if (participants < 1) {
                         this.addMessage(dataEntity, "参与人数不能小于1;");
                     }else{
@@ -57,13 +57,13 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
                         }else{
                             //校验积分是否超出限制
                             Long id = data.getLong(FormConstant.ID_KEY);
-                            Date date = data.getDate(ContributionEvaluationConstant.NCKD_YEAR);
-                            DynamicObject scoreItem = data.getDynamicObject(ContributionEvaluationConstant.NCKD_SCOREITEM);
-                            DynamicObject scoreItemSub = data.getDynamicObject(ContributionEvaluationConstant.NCKD_SCOREITEMSUB);
+                            Date date = data.getDate(ContributionConstant.NCKD_YEAR);
+                            DynamicObject scoreItem = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEM);
+                            DynamicObject scoreItemSub = data.getDynamicObject(ContributionConstant.NCKD_SCOREITEMSUB);
                             List<ContributionHelper.ScoreItemValidScore> scoreItemValidScoreList = new ArrayList<>(entryEntity.size());
                             for (DynamicObject entry : entryEntity) {
-                                DynamicObject person = entry.getDynamicObject(ContributionEvaluationConstant.NCKD_PERSON);
-                                BigDecimal oriScore = entry.getBigDecimal(ContributionEvaluationConstant.NCKD_ORISCORE);
+                                DynamicObject person = entry.getDynamicObject(ContributionConstant.NCKD_PERSON);
+                                BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
                                 ContributionHelper.ScoreItemValidScore scoreItemValidScore = new ContributionHelper.ScoreItemValidScore(
                                         person.getLong(FormConstant.ID_KEY),
                                         scoreItem.getLong(FormConstant.ID_KEY),
@@ -74,10 +74,10 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
                             if (!scoreItemValidScoreList.isEmpty()) {
                                 ContributionHelper.getScoreItemValidScore(scoreItemValidScoreList, date, id);
                                 for (DynamicObject entry : entryEntity) {
-                                    DynamicObject person = entry.getDynamicObject(ContributionEvaluationConstant.NCKD_PERSON);
+                                    DynamicObject person = entry.getDynamicObject(ContributionConstant.NCKD_PERSON);
                                     long personId = person.getLong(FormConstant.ID_KEY);
-                                    BigDecimal oriScore = entry.getBigDecimal(ContributionEvaluationConstant.NCKD_ORISCORE);
-                                    BigDecimal score = entry.getBigDecimal(ContributionEvaluationConstant.NCKD_SCORE);
+                                    BigDecimal oriScore = entry.getBigDecimal(ContributionConstant.NCKD_ORISCORE);
+                                    BigDecimal score = entry.getBigDecimal(ContributionConstant.NCKD_SCORE);
                                     for (ContributionHelper.ScoreItemValidScore scoreItemValidScore : scoreItemValidScoreList) {
                                         if(Objects.equals(scoreItemValidScore.getPersonId(),personId)){
                                             if(scoreItemValidScore.getValidScore() != null){
@@ -102,7 +102,7 @@ public class ContribBillOpPlugin extends AbstractOperationServicePlugIn implemen
     @Override
     public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
         for (DynamicObject data : e.getDataEntities()) {
-            int participants = data.getInt(ContributionEvaluationConstant.NCKD_PARTICIPANTS);
+            int participants = data.getInt(ContributionConstant.NCKD_PARTICIPANTS);
             DynamicObjectCollection dynamicObjectCollection = data.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
             if(participants != dynamicObjectCollection.size()){
                 e.cancel = !this.showInteractionMessage(participants,dynamicObjectCollection.size());

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

@@ -11,6 +11,7 @@ import kd.bos.logging.LogFactory;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.bos.servicehelper.user.UserServiceHelper;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.enums.AppraisalResultEnum;
 import nckd.jxccl.base.common.enums.psms.JobSeqEnum;
@@ -367,9 +368,15 @@ public abstract class BaseInitialOperationPlugIn extends AbstractOperationServic
         personPosFile.set(PositionStructureConstant.NCKD_APPRAISALRESULT, data.lastYearAppraisalResult);
         personPosFile.set(PositionStructureConstant.NCKD_JOBSEQHR, data.jobSeq);
         personPosFile.set(PositionStructureConstant.NCKD_POSITIONHR, data.positionHr);
-        personPosFile.set(PositionStructureConstant.USEORG_KEY, data.company);
-        personPosFile.set(PositionStructureConstant.ORG_KEY, data.dep);
+        /*personPosFile.set(PositionStructureConstant.USEORG_KEY, data.company);
         personPosFile.set(PositionStructureConstant.CREATEORG_KEY, data.dep);
+        personPosFile.set(PositionStructureConstant.ORG_KEY, data.dep);*/
+
+        personPosFile.set(PositionStructureConstant.ORG_KEY, UserServiceHelper.getUserMainOrgId(UserServiceHelper.getCurrentUserId()));
+        personPosFile.set(PositionStructureConstant.SRCCREATEORG_KEY, data.company);
+        personPosFile.set(PositionStructureConstant.CREATEORG_KEY, data.company);
+        personPosFile.set(PositionStructureConstant.USEORG_KEY, data.dep);
+
         personPosFile.set(PositionStructureConstant.NCKD_ALLSUMSCORE, allSumScore);
         personPosFile.set(PositionStructureConstant.NCKD_SUMSCORE, sumScore);
         personPosFile.set(PositionStructureConstant.NCKD_RANKNAME, data.rankName);

+ 5 - 4
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/report/adjust/UnAdjustedReportReportListDataPlugin.java

@@ -68,6 +68,7 @@ public class UnAdjustedReportReportListDataPlugin extends AbstractReportListData
                 .addGroup(new String[]{PositionStructureConstant.PERSONPOSFILE_ENTITYID},
                         FormConstant.USEORG_KEY,
                         FormConstant.ORG_KEY,
+                        FormConstant.CREATEORG_KEY,
                         PositionStructureConstant.NCKD_POSITIONHR,
                         PositionStructureConstant.NCKD_JOBSEQHR,
                         PositionStructureConstant.NCKD_PROTITLELEVEL,
@@ -180,9 +181,9 @@ public class UnAdjustedReportReportListDataPlugin extends AbstractReportListData
         joinOr.add(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, PositionStructureConstant.NCKD_DIPLOMA) + " <> " +
                 String.join(".", FormConstant.HRPI_PEREDUEXP, FormConstant.EDUCATION_KEY));
         //公司变化
-        joinOr.add(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, FormConstant.USEORG_KEY) + " <> " + FormConstant.COMPANY_KEY);
+        joinOr.add(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, FormConstant.CREATEORG_KEY) + " <> " + FormConstant.COMPANY_KEY);
         //部门变化
-        joinOr.add(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, FormConstant.ORG_KEY) + " <> " + FormConstant.ADMINORG);
+        joinOr.add(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, FormConstant.USEORG_KEY) + " <> " + FormConstant.ADMINORG);
         //序列变化
         joinOr.add(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, PositionStructureConstant.NCKD_JOBSEQHR) + " <> " +
                 String.join(".", FormConstant.HBPM_POSITIONHR, PositionStructureConstant.NCKD_JOBSEQ));
@@ -218,12 +219,12 @@ public class UnAdjustedReportReportListDataPlugin extends AbstractReportListData
                 ") THEN '技能变化' END", "c");
 
         newDataSet = newDataSet.addField("CASE WHEN " +
-                String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, FormConstant.USEORG_KEY) +
+                String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, FormConstant.CREATEORG_KEY) +
                 " <> " + FormConstant.COMPANY_KEY +
                 " THEN '跨单位变动' END", "d");
 
         newDataSet = newDataSet.addField("CASE WHEN " +
-                String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, FormConstant.ORG_KEY) +
+                String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, FormConstant.USEORG_KEY) +
                 " <> " + FormConstant.ADMINORG +
                 " THEN '单位内变动' END", "e");