| 
					
				 | 
			
			
				@@ -0,0 +1,755 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package nckd.jxccl.hr.psms.business; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import kd.bos.common.enums.EnableEnum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import kd.bos.dataentity.entity.DynamicObject; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import kd.bos.entity.constant.StatusEnum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import kd.bos.orm.query.QCP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import kd.bos.orm.query.QFilter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import kd.bos.servicehelper.BusinessDataServiceHelper; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import nckd.jxccl.base.common.constant.FormConstant; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import nckd.jxccl.base.common.enums.AppraisalResultEnum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import nckd.jxccl.base.common.exception.ValidationException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+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.pm.helper.PerformanceManagerHelper; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import nckd.jxccl.hr.psms.common.PositionStructureConstant; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import nckd.jxccl.hr.psms.common.bo.PositionAppointmentBO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import nckd.jxccl.hr.psms.helper.PositionStructureHelper; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.commons.lang3.StringUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.math.BigDecimal; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.time.LocalDateTime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.Date; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.LinkedHashMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.Map; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 年度调整服务类。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <p>重构目标:逻辑清晰、职责单一、条件判断明确、可维护可测试;保持原始业务逻辑完整性。</p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class AnnualAdjustmentService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 生成年度调整记录 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param person    员工 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param beginDate   生效日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 成功返回 null;失败返回错误信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @note 对应SHR:PersonpositionfilecreateViewListHandler#addNewYear_PersonpositionfileInfo(277~815行) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public DynamicObject addNewYearPersonPositionFileInfo(DynamicObject person, Date beginDate,String remark) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int executeYear = beginDate != null ? DateUtil.getYear(beginDate) : DateUtil.getYear(new Date()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //判断当前年是否已执行过年度调整 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject[] personPosFileByYear = PositionStructureHelper.getPersonPosFileByPersonAndState(person.getLong(FormConstant.ID_KEY), new String[]{"3"}, null, new QFilter(PositionStructureConstant.NCKD_EXECUTEYEAR, QCP.equals, executeYear)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(personPosFileByYear != null && personPosFileByYear.length > 0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new ValidationException(StrFormatter.format("人员【{}】已存在【{}】年的年度调整!", person.getString(FormConstant.NAME_KEY), executeYear)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 1、 初始化上下文并加载基础数据。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 对应SHR:291~339行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        AdjustmentContext ac = initAndLoad(executeYear, person, beginDate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.remark = remark; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //2、 判断是否为本年首次调整、考核是否已被使用,并根据规则决定是否使用R排名。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //对应SHR:341~391行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        evaluateFirstAndAppraisalUsage(ac); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 3、加载上一条记录并校验生效日期。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //对应SHR:393~421行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        loadLastRecordAndValidateBeginDate(ac); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 4、处理职位序列(如果是管理序列,则按职能序列进行调整) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //对应SHR:521~527行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject convertJobSeq = JobLevelCalculatorService.handleJobSeq(ac.jobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.convertJobSeq = convertJobSeq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject convertLastJobSeq = JobLevelCalculatorService.handleJobSeq(ac.data.getLastJobSeq()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.data.setConvertLastJobSeq(convertLastJobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 5、获取技能/职称分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //对应SHR:451~481行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        JobLevelCalculatorService.JobScoreInfo jobScoreInfo = JobLevelCalculatorService.handleJobScores(convertJobSeq, ac.positionAppointment); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.data.setJobScoreInfo(jobScoreInfo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 6、计算学历得分并生成说明 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //对应SHR:423~449行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.diplomaScore = JobLevelCalculatorService.handleDiplomaScore(ac.lastRecordInfo, ac.positionAppointment, jobScoreInfo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.whyDiplomaScore.putAll(jobScoreInfo.whyDiplomaScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 7、汇总年度积分池与综合分数。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //对应SHR:483~519行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        aggregateScores(ac); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //8.确定目标职级(含有R排名和无R排名两条路径)。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //对应SHR:540~702行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject jobLevel = decideTargetJobGrade(ac); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 9、上年度考核结果为“无”时,取最低职级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //对应SHR:703~707行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (AppraisalResultEnum.NONE.getCode().equals(ac.data.getAppraisalResultNumber())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 考核结果为无时取最低职级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.adjustType = "8"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.adjustInt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            jobLevel = JobLevelCalculatorService.getLowestJobLevel(ac.convertJobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(jobLevel == null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new ValidationException(StrFormatter.format("人员【{}】,职位序列【{}】总积分【{}】职称等级【{}】技能等级【{}】考核结果【{}】没有匹配到符合的职级", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.personName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.jobSeq.getString(FormConstant.NAME_KEY), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.allSumScore.toString(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.data.getZgjbName(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.data.getZyjndjName(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.data.getAppraisalResultName())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        JobLevelCalculatorService.JobLevelResult jobLevelResult = JobLevelCalculatorService.calculateJobLevel(person, beginDate, ac.positionAppointment); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.data.getRankingResultInfo().allowanceRankMark = jobLevelResult.rankingResultInfo.allowanceRankMark; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.data.getRankingResultInfo().allowanceRankSel = jobLevelResult.rankingResultInfo.allowanceRankSel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //10、构建职位档案 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return buildPersonPositionFile(ac, jobLevel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 初始化上下文并加载基础数据。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param executeYear 执行年份 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param person 员工 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param beginDate 生效日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: nckd.jxccl.hr.psms.business.AnnualAdjustmentService.AdjustmentContext 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/08 21:15 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private AdjustmentContext initAndLoad(Integer executeYear, DynamicObject person, Date beginDate){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        AdjustmentContext ac = new AdjustmentContext(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.executeYear = executeYear; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.nowYear = executeYear; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.personId = person.getLong(FormConstant.ID_KEY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.personName = person.getString(FormConstant.NAME_KEY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.beginDate = beginDate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.personInfo = person; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int lastYear = executeYear - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        LocalDateTime lastYearDateTime = LocalDateTime.of(lastYear, 1, 1, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //对应SHR:291行;utils.YearContributeScoreBillEntryScoreSumBypersonidAndYear 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //TODO 1、获取年度贡献积分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //yearscoresuma、yearscoresumb、yearscoresumc、yearscoresumd、yearscoresume、yearscoresumf、yearscoresumg、yearscoresumh、yearscoresumi、allyearscoresum、yearscoresuma 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //2、获取上年度考核结果(对应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.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        data.setAppraisalResultName(performanceResult.getString(FormConstant.NAME_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        data.setAppraisalResultId(performanceResult.getLong(FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        data.setAppraisalResultScore(performanceResult.getBigDecimal(FormConstant.NCKD_SCORE)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //3.获取员工上年度年度R排名(对应SHR:PersonpositionfileUtils:915~945行) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject lastPersonPosFile = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        JobLevelCalculatorService.RankingResultInfo rankingInfo = JobLevelCalculatorService.getRankingInfo(ac.personId, ac.personName, beginDate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        data.setRankingResultInfo(rankingInfo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //4.查询上一条有效年度调整记录(对应SHR:PersonpositionfileUtils:946~997行) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject[] personPosFileByPersonAndState = PositionStructureHelper.getPersonPosFileByPersonAndState(ac.personId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                new String[]{"3","4"}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                null,null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                QueryFieldBuilder.create() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        .orderDesc(PositionStructureConstant.NCKD_EXECUTEYEAR,PositionStructureConstant.MODIFY_TIME_KEY,PositionStructureConstant.NCKD_BEGINDATE).buildOrderArray()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(personPosFileByPersonAndState == null || personPosFileByPersonAndState.length < 1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //没有年度调整记录取初定记录 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lastPersonPosFile = PositionStructureHelper.getFirstRank(ac.personId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(lastPersonPosFile == null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw new ValidationException(StrFormatter.format("当前无法为【{}】进行调整,因为他/她尚未建立职位档案。请前往“职位及积分初定” -> 进行初定!", ac.personName)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setFirstId(lastPersonPosFile.getLong(FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lastPersonPosFile = personPosFileByPersonAndState[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setLastId(lastPersonPosFile.getLong(FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(lastPersonPosFile != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //(firstid、lastsumscore、lastdiplomascore、lastrankscore、lastjobstatusscore、lasthrjobfamilynumber、lastjobgradefid、lastjobgradeindex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setLastSumScore(lastPersonPosFile.getBigDecimal(PositionStructureConstant.NCKD_SUMSCORE)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //lastdiplomascore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //lastrankscore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //lastjobstatusscore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            DynamicObject jobSeq = lastPersonPosFile.getDynamicObject(PositionStructureConstant.NCKD_JOBSEQHR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setLastHrJobFamilyNumber(jobSeq.getString(FormConstant.NUMBER_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setLastJobSeq(jobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            DynamicObject jobLevel = lastPersonPosFile.getDynamicObject(PositionStructureConstant.NCKD_JOBLEVELHR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setLastJobLevel(jobLevel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setLastJobGradeIndex(jobLevel.getInt(FormConstant.JOBLEVELSEQ)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setLastJobGradeIndex(jobLevel.getInt(FormConstant.JOBLEVELSEQ)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //5.获取员工任职信息(对应SHR:PersonpositionfileUtils:998~1009行) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PositionAppointmentBO positionAppointment = PositionStructureHelper.positionAppointmentQuery(ac.personId, beginDate == null ? new Date() : beginDate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject perEduExp = positionAppointment.getPerEduExp(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(perEduExp != null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setDiplomaId(perEduExp.getLong(String.join(".", FormConstant.EDUCATION_KEY, FormConstant.ID_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setDiplomaScore(perEduExp.getBigDecimal(String.join(".", FormConstant.EDUCATION_KEY, FormConstant.NCKD_SCORE))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject empPosOrgRel = positionAppointment.getEmpPosOrgRel(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(empPosOrgRel != null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setPersonDepId(empPosOrgRel.getLong(String.join(".",FormConstant.ADMINORG,FormConstant.ID_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setHrJobFamilyId(empPosOrgRel.getLong(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.ID_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setHrJobFamilyNumber(empPosOrgRel.getString(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.NUMBER_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setPositionId(empPosOrgRel.getLong(String.join(".", FormConstant.HBPM_POSITIONHR,  FormConstant.ID_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setPositionName(empPosOrgRel.getString(String.join(".", FormConstant.HBPM_POSITIONHR,  FormConstant.NAME_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setPersonName(empPosOrgRel.getString(String.join(".", FormConstant.EMPLOYEE_KEY,  FormConstant.NAME_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // data.setHrOrgUnitId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new ValidationException(StrFormatter.format("当前无法为【{}】进行调整,因为根据时间【{}】未获取到人员任职和聘任信息!", ac.personName, DateUtil.format(beginDate == null ? new Date() : beginDate,DateUtil.NORM_DATE_PATTERN))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject perProTitle = positionAppointment.getPerProTitle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(perProTitle != null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setRankName(perProTitle.getString(String.join(".", FormConstant.PROLEVEL_KEY, FormConstant.NAME_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setZgjbId(perProTitle.getLong(String.join(".", FormConstant.PROLEVEL_KEY, FormConstant.ID_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setZgjbNumber(perProTitle.getString(String.join(".", FormConstant.PROLEVEL_KEY, FormConstant.NUMBER_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setZgjbName(perProTitle.getString(String.join(".", FormConstant.PROLEVEL_KEY, FormConstant.NAME_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setZgjbScore(perProTitle.getBigDecimal(String.join(".", FormConstant.PROLEVEL_KEY, FormConstant.NCKD_SCORE))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject perOcpQual = positionAppointment.getPerOcpQual(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(perOcpQual != null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setJobStatusName(perOcpQual.getString(String.join(".", FormConstant.QUALEVEL_KEY, FormConstant.NAME_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setZyjndjId(perOcpQual.getLong(String.join(".", FormConstant.QUALEVEL_KEY, FormConstant.ID_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setZyjndjNumber(perOcpQual.getString(String.join(".", FormConstant.QUALEVEL_KEY, FormConstant.NUMBER_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setZyjndjName(perOcpQual.getString(String.join(".", FormConstant.QUALEVEL_KEY, FormConstant.NAME_KEY))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data.setZyjndjScore(perOcpQual.getBigDecimal(String.join(".", FormConstant.QUALEVEL_KEY, FormConstant.NCKD_SCORE))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (data.getHrJobFamilyId() == null || data.getHrJobFamilyId() == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new ValidationException(StrFormatter.format("无职位序列,请检查当前人员【{}】任职的岗位【{}】是否有职位序列",ac.personName,data.getPositionName())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.positionAppointment = positionAppointment; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        long jobSeq = positionAppointment.getEmpPosOrgRel().getLong(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.jobSeq = BusinessDataServiceHelper.loadSingle(jobSeq,FormConstant.HBJM_JOBSEQHR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 对应SHR:307~322行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 判断R位次存在性 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ac.data.getRankingResultInfo() == null || ac.data.getRankingResultInfo().allowanceRankPercent == null || ac.data.getRankingResultInfo().topRank == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.keep = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ac.data.getRankingResultInfo() == null || ac.data.getRankingResultInfo().allowanceRankPercent == null || ac.data.getRankingResultInfo().allowanceRankPercent <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.haveRp = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 对应SHR:323~339行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 考核结果对应升降级逻辑 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (AppraisalResultEnum.EXCELLENT.getCode().equals(ac.data.getAppraisalResultNumber())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.minusByAppraisal = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.whyAdjust.append("【考核结果优秀】升1级"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (AppraisalResultEnum.BASICALLY_QUALIFIED.getCode().equals(ac.data.getAppraisalResultNumber())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.minusByAppraisal = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.whyAdjust.append("【考核结果基本合格】降1级"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (AppraisalResultEnum.UN_QUALIFIED.getCode().equals(ac.data.getAppraisalResultNumber())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.minusByAppraisal = -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.whyAdjust.append("【考核结果不合格】降2级"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.data = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return ac; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 判断是否为本年首次调整、考核是否已被使用,并根据规则决定是否使用R排名。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param ac 上下文对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/08 22:12 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void evaluateFirstAndAppraisalUsage(AdjustmentContext ac) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject nowYearPersonPosFile = PositionStructureHelper.getLatsPersonPosFileByPerson(ac.personId, new QFilter(PositionStructureConstant.NCKD_EXECUTEYEAR, QCP.equals, ac.nowYear)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boolean isyearfirstdo = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (nowYearPersonPosFile != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            DynamicObject nowYearAppraisalResult = nowYearPersonPosFile.getDynamicObject(PositionStructureConstant.NCKD_APPRAISALRESULT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String nowYearAppraisalResultNumber = nowYearAppraisalResult.getString(FormConstant.NUMBER_KEY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String appraisalResultNumber = ac.data.getAppraisalResultNumber(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!StringUtils.equals(nowYearAppraisalResultNumber, appraisalResultNumber)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw new ValidationException(StrFormatter.format("人员【{}】,上年考度核结果存在变更,需删除【{}】年度创建的【员工职位档案调整】记录才能继续操作 !", ac.personName,ac.nowYear)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            LocalDateTime nowYearDateTime = LocalDateTime.of(ac.nowYear, 1, 1, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.useAppraisalresult = JobLevelCalculatorService.useAppraisalResult(ac.personId, DateUtil.toDate(nowYearDateTime)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (ac.useAppraisalresult && ac.minusByAppraisal != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ac.whyAdjust.append(" 非").append(ac.nowYear) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        .append("年度首次调整,且升降【考核结果】已被使用,不需要考虑R排名,保级处理"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ac.haveRp = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ac.keep = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.whyAdjust.append(" ").append(ac.nowYear).append("年度首次调整,【考核结果】未被使用"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            isyearfirstdo = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ac.useAppraisalresult) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.whyAdjust.append(" ").append(ac.nowYear).append("年度【考核结果】已被使用,保级处理"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            isyearfirstdo = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.keep = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.whyAdjust.append(" ").append(ac.nowYear).append("年度【考核结果】未被使用"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.keep = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            isyearfirstdo = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (ac.minusByAppraisal == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ac.whyAdjust.append("【考核结果】为保级,"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Double p = ac.data.getRankingResultInfo().allowanceRankPercent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (p == null || p <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.whyAdjust.append("无R排名"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.haveRp = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.whyAdjust.append("使用R排名进行计算 "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.haveRp = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.isYearFirstDo = isyearfirstdo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 加载上一条记录并校验生效日期。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param ac 上下文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/08 23:13 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void loadLastRecordAndValidateBeginDate(AdjustmentContext ac) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.lastRecordId = ac.data.getLastId() != null && ac.data.getLastId() != 0 ? ac.data.getLastId() : ac.data.getFirstId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ac.lastRecordId == null || ac.lastRecordId == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new ValidationException(StrFormatter.format("人员【{}】,缺少职位及积分初定信息,请先完成初定,第二年再操作年度调整!", ac.personName)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.lastRecordInfo = BusinessDataServiceHelper.loadSingle(ac.lastRecordId, PositionStructureConstant.PERSONPOSFILE_ENTITYID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ac.beginDate != null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                && ac.lastRecordInfo != null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                && ac.lastRecordInfo.getDate(PositionStructureConstant.NCKD_BEGINDATE) != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Date lastBegin = ac.lastRecordInfo.getDate(PositionStructureConstant.NCKD_BEGINDATE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (ac.beginDate.before(lastBegin)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw new ValidationException(StrFormatter.format("当前无法为【{}】进行调整,因为最近调整时间为【{}】,不能早于最近一次职位调整时间。", ac.personName,DateUtil.format(lastBegin,DateUtil.NORM_DATE_PATTERN))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 汇总年度积分池与综合分数。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param ac 上下文对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/08 23:46 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void aggregateScores(AdjustmentContext ac) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal allyearscoresum = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ac.data.getAllYearScoreSum() == null ? BigDecimal.ZERO : ac.data.getAllYearScoreSum(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println("上年所有贡献单据分数之和" + allyearscoresum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal appraisalresultscore = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ac.data.getAppraisalResultScore() == null ? BigDecimal.ZERO : ac.data.getAppraisalResultScore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println("上年年度考核得分" + appraisalresultscore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.lastYearContributeScore = allyearscoresum.add(appraisalresultscore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println("上年度贡献综合评价分" + ac.lastYearContributeScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.addYearContributeScore = ac.lastYearContributeScore.multiply(new BigDecimal("0.1")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println("年度新增的贡献积分" + ac.addYearContributeScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal lastsum = ac.data.getLastSumScore() == null ? BigDecimal.ZERO : ac.data.getLastSumScore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println("上年累计积分池的分" + lastsum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.sumScore = lastsum.add(ac.addYearContributeScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println("累计积分池的分" + ac.sumScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.allSumScore = ac.sumScore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .add(ac.diplomaScore) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .add(ac.data.getJobScoreInfo().perProTitleScore) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .add(ac.data.getJobScoreInfo().quaLevelScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println("累计总积分" + ac.allSumScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 确定目标职级(含有R排名和无R排名两条路径)。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param ac 上下文对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: kd.bos.dataentity.entity.DynamicObject 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @note 对应原 PersonpositionfilecreateViewListHandler:540~707 行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/10 14:17 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private DynamicObject decideTargetJobGrade(AdjustmentContext ac) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //上一条职位档案的职位序列(如果是管理序列,则转换为职能序列) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String newJobSeqNumber = ac.convertJobSeq.getString(FormConstant.NUMBER_KEY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String newLastJobSeqNumber = ac.data.getConvertLastJobSeq().getString(FormConstant.NUMBER_KEY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!newJobSeqNumber.equalsIgnoreCase(newLastJobSeqNumber)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //序列发生变化 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new ValidationException(StrFormatter.format("人员【{}】,序列发生变化!请先到【员工职位档案调整】中进行操作", ac.personName)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ac.haveRp) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return decideWithR(ac); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return decideWithoutR(ac); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 有 R 排名时的定位路径。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param ac 上下文对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: kd.bos.dataentity.entity.DynamicObject 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/10 14:18 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private DynamicObject decideWithR(AdjustmentContext ac) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject jobLevel = JobLevelCalculatorService.getJobLevel(ac.convertJobSeq, ac.allSumScore, ac.data.getZgjbNumber(), ac.data.getZyjndjNumber(), 0, Boolean.FALSE,Boolean.FALSE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(jobLevel == null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new ValidationException(StrFormatter.format("人员【{}】,职位序列【{}】总积分【{}】职称等级【{}】技能等级【{}】考核结果【{}】没有匹配到符合的职级", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.personName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.jobSeq.getString(FormConstant.NAME_KEY), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.allSumScore.toString(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.data.getZgjbName(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.data.getZyjndjName(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ac.data.getAppraisalResultName())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int jobGradeindex = jobLevel.getInt(FormConstant.JOBLEVELSEQ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println("当前积分所得职级顺序号:::" + jobGradeindex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<Integer, DynamicObject> jobLevelByJobSeqMap = JobLevelCalculatorService.getJobLevelByJobSeqMap(ac.convertJobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int newjobgradeindex = ac.data.getLastJobGradeIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 补充根据R排名确定是否升级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ac.minusByAppraisal == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 如果考评结果不需要升降级则验证R排名 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!ac.keep) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                newjobgradeindex = JobLevelCalculatorService.getnewjobgradeindexByrank(ac.data.getLastJobGradeIndex(), newjobgradeindex, ac.data.getRankingResultInfo(), ac.convertJobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (newjobgradeindex > jobGradeindex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                newjobgradeindex = jobGradeindex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 考核结果需要升降级则直接执行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            newjobgradeindex = ac.data.getLastJobGradeIndex() + ac.minusByAppraisal; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (jobGradeindex <= newjobgradeindex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                newjobgradeindex = jobGradeindex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 确定是否超出总分最高任命职级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject maxJobLevel = JobLevelCalculatorService.getMaxJobLevel(ac.convertJobSeq, ac.allSumScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int personMaxjobgradeindex = maxJobLevel.getInt(FormConstant.JOBLEVELSEQ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 超出总分能任命最高职职级则该最高职级就是要任命的职级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (newjobgradeindex > personMaxjobgradeindex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            newjobgradeindex = personMaxjobgradeindex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 确定是否超出该职称等级或技能等级最高任命职级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject maxJobLevel1 = JobLevelCalculatorService.getMaxJobLevel(ac.convertJobSeq, ac.allSumScore, null, ac.data.getZgjbNumber(), ac.data.getZyjndjNumber()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int maxJobGradeIndex = maxJobLevel1.getInt(FormConstant.JOBLEVELSEQ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 职级超出职称等级或技能等级能任命最高职职级则该最高职级就是要任命的职级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (newjobgradeindex > maxJobGradeIndex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            newjobgradeindex = maxJobGradeIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if((ac.data.getZgjbId() == null || ac.data.getZyjndjId() == 0) && (ac.data.getZyjndjId() == null || ac.data.getZyjndjId() == 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //如果没有聘任则取最低职级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            jobLevel = JobLevelCalculatorService.getLowestJobLevel(ac.convertJobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(jobLevel != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                newjobgradeindex = jobLevel.getInt(FormConstant.JOBLEVELSEQ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }else if(jobLevelByJobSeqMap.get(newjobgradeindex) != null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            jobLevel = jobLevelByJobSeqMap.get(newjobgradeindex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //兜底;如果没有获取到合适的职级则取最低级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            jobLevel = JobLevelCalculatorService.getLowestJobLevel(ac.convertJobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(jobLevel != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                newjobgradeindex = jobLevel.getInt(FormConstant.JOBLEVELSEQ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if((ac.data.getZgjbId() == null || ac.data.getZyjndjId() == 0) && (ac.data.getZyjndjId() == null || ac.data.getZyjndjId() == 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //无聘任 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.adjustType = "7"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }else if (newjobgradeindex == ac.data.getLastJobGradeIndex()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //保级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.adjustType = "1"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }else if (newjobgradeindex > ac.data.getLastJobGradeIndex()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //升级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.adjustType = "2"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //降级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.adjustType = "0"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 升降级数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ac.adjustInt = newjobgradeindex - ac.data.getLastJobGradeIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return jobLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 无 R 排名时的定位路径。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param ac 上下文对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: kd.bos.dataentity.entity.DynamicObject 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/10 14:18 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private DynamicObject decideWithoutR(AdjustmentContext ac) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // String JobGrade = ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject jobLevel = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ac.minusByAppraisal == 0 && ac.keep) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            System.out.println("绩效分组排名,没有勾选享受职位津贴,保持原职级不变,没有则为最低档"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.whyAdjust.append("绩效分组排名,没有勾选享受职位津贴,保持原职级不变"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            jobLevel = ac.data.getLastJobLevel(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.adjustType = "0"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (jobLevel == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                jobLevel = JobLevelCalculatorService.getLowestJobLevel(ac.convertJobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            jobLevel = JobLevelCalculatorService.getJobLevel(ac.convertJobSeq, ac.allSumScore, ac.data.getZgjbNumber(), ac.data.getZyjndjNumber(), 0, Boolean.FALSE,Boolean.FALSE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(jobLevel == null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw new ValidationException(StrFormatter.format("人员【{}】,职位序列【{}】总积分【{}】职称等级【{}】技能等级【{}】考核结果【{}】没有匹配到符合的职级", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ac.personName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ac.jobSeq.getString(FormConstant.NAME_KEY), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ac.allSumScore.toString(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ac.data.getZgjbName(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ac.data.getZyjndjName(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ac.data.getAppraisalResultName())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int jobGradeindex = jobLevel.getInt(FormConstant.JOBLEVELSEQ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            System.out.println("当前积分所得职级顺序号:::" + jobGradeindex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //这里不知道为什么用上一档案的序列?这里沿用SHR的逻辑,避免业务错误 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Map<Integer, DynamicObject> jobLevelByJobSeqMap = JobLevelCalculatorService.getJobLevelByJobSeqMap(ac.data.getConvertLastJobSeq()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int newjobgradeindex = ac.data.getLastJobGradeIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (ac.isYearFirstDo) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                newjobgradeindex += ac.minusByAppraisal; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (jobGradeindex <= newjobgradeindex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                newjobgradeindex = jobGradeindex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 确定是否超出该职称等级或技能等级最高任命职级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            DynamicObject maxJobLevel1 = JobLevelCalculatorService.getMaxJobLevel(ac.convertJobSeq, ac.allSumScore, null, ac.data.getZgjbNumber(), ac.data.getZyjndjNumber()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int maxJobGradeIndex = maxJobLevel1.getInt(FormConstant.JOBLEVELSEQ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 职级超出职称等级或技能等级能任命最高职职级则该最高职级就是要任命的职级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (newjobgradeindex > maxJobGradeIndex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                newjobgradeindex = maxJobGradeIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 如果最后超出最低排名则按最低排名 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (jobLevelByJobSeqMap.get(newjobgradeindex) != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                jobLevel = jobLevelByJobSeqMap.get(newjobgradeindex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                jobLevel = JobLevelCalculatorService.getLowestJobLevel(ac.convertJobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(jobLevel != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    newjobgradeindex = jobLevel.getInt(FormConstant.JOBLEVELSEQ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 设置调整类型和调整级别数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (newjobgradeindex == ac.data.getLastJobGradeIndex()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                //保级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ac.adjustType = "1"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (newjobgradeindex > ac.data.getLastJobGradeIndex()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                //升级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ac.adjustType = "2"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                //降级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ac.adjustType = "0"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 升降级数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ac.adjustInt = newjobgradeindex - ac.data.getLastJobGradeIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return jobLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 构建职位档案 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param ac 上下文对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param jobLevel 目标职级对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return: kd.bos.dataentity.entity.DynamicObject 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @note 对应原 710~803行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @author W.Y.C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @date: 2025/10/10 15:44 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private DynamicObject buildPersonPositionFile(AdjustmentContext ac, DynamicObject jobLevel) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject newPersonPosFile = BusinessDataServiceHelper.newDynamicObject( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                PositionStructureConstant.PERSONPOSFILE_ENTITYID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject empPosOrgRel = ac.positionAppointment.getEmpPosOrgRel(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_PERSON, ac.personInfo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        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.NCKD_TYPESTATE, "3"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_EXECUTEYEAR, ac.executeYear); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Long positionId = empPosOrgRel.getLong(String.join(".",FormConstant.POSITION_KEY,FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject position = BusinessDataServiceHelper.newDynamicObject(FormConstant.HBPM_POSITIONHR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        position.set(FormConstant.ID_KEY, positionId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Long jobSeqId = empPosOrgRel.getLong(String.join(".", FormConstant.HBPM_POSITIONHR, FormConstant.NCKD_JOBSEQ, FormConstant.ID_KEY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject jobSeq = BusinessDataServiceHelper.newDynamicObject(FormConstant.HBJM_JOBSEQHR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        jobSeq.set(FormConstant.ID_KEY, jobSeqId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_JOBSEQHR, jobSeq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_POSITIONHR, position); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_RANKNAME, "无".equalsIgnoreCase(ac.data.getRankName()) ? null : ac.data.getRankName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject proTitleLevel = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_PROTITLELEVEL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        proTitleLevel.set(FormConstant.ID_KEY, ac.data.getZgjbId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_PROTITLELEVEL, proTitleLevel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_JOBSTATUSNAME, "无".equalsIgnoreCase(ac.data.getZyjndjName()) ? null : ac.data.getZyjndjName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject ocpQualLevel = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_OCPQUALLEVEL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ocpQualLevel.set(FormConstant.ID_KEY, ac.data.getZyjndjId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_OCPQUALLEVEL, ocpQualLevel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject diploma = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.HBSS_DIPLOMA); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        diploma.set(FormConstant.ID_KEY, ac.data.getDiplomaId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_DIPLOMA, diploma); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_JOBLEVELHR, jobLevel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_LASTPERSONPOSFILE, ac.lastRecordInfo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_DIPLOMASCORE, ac.diplomaScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_WHYDIPLOMASCORE, ac.whyDiplomaScore.toString()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_RANKSCORE, ac.data.getJobScoreInfo().perProTitleScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_JOBSTATUSSCORE, ac.data.getJobScoreInfo().quaLevelScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ALLSUMSCORE, ac.allSumScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_SUMSCORE,ac.sumScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_BEGINDATE, ac.beginDate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ADJUSTINT, ac.adjustInt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_FIRSTRANK, EnableEnum.NO.getCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_TOPRANK, ac.data.getRankingResultInfo().topRank); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ALLOWANCERANK, ac.data.getRankingResultInfo().allowanceRank); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_TOPRANKPERCENT, ac.data.getRankingResultInfo().topRankPercent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ALLOWANCERANKMARK, ac.data.getRankingResultInfo().allowanceRankMark); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ALLOWANCERANKSEL, ac.data.getRankingResultInfo().allowanceRankSel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ALLOWANCERANKPCT, ac.data.getRankingResultInfo().allowanceRankPercent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //上年度考核结果 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_APPRAISALRESULT, ac.data.getAppraisalResult()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_RESULTSCORE, ac.data.getAppraisalResultScore()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ADJUSTTYPE, ac.adjustType); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_DISABLE, EnableEnum.NO.getCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ISCURRENTNEWEST, EnableEnum.YES.getCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.STATUS, StatusEnum.C.toString()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.ENABLE, EnableEnum.YES.getCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_YEARSCORESUMA, ac.data.getYearscoresuma()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_YEARSCORESUMB, ac.data.getYearscoresumb()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_YEARSCORESUMC, ac.data.getYearscoresumc()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_YEARSCORESUMD, ac.data.getYearscoresumd()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_YEARSCORESUME, ac.data.getYearscoresume()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_YEARSCORESUMF, ac.data.getYearscoresumf()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_YEARSCORESUMG, ac.data.getYearscoresumg()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_YEARSCORESUMH, ac.data.getYearscoresumh()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_YEARSCORESUMI, ac.data.getYearscoresumi()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_LYRCONTRIBSCORE, ac.lastYearContributeScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ALLYEARSCORESUM, ac.data.getAllYearScoreSum()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.NCKD_ADDYCONTRIBSCORE, ac.addYearContributeScore); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 备注 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newPersonPosFile.set(PositionStructureConstant.KEY_NCKD_CAUSEREMARK, ac.remark); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return newPersonPosFile; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 内部运行时上下文。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static class AdjustmentContext { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 执行年份 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer executeYear; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 当前年份 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer nowYear; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 调整生效日期 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Date beginDate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 员工ID */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Long personId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 员工Name */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String personName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 员工信息对象 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject personInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 强类型数据对象(替代原 selMap) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        AnnualAdjustmentData data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 是否有R位次(allowancerankpercent≤0则为false) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boolean haveRp = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 是否保级(缺R位次时为true) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boolean keep = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 本年考核是否已使用 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boolean useAppraisalresult = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 是否本年首次调整 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boolean isYearFirstDo = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 考核升降级标记(+1升/-1降/-2降两级) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int minusByAppraisal = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 固定类型(默认3) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String typestate = "3"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 上一条档案记录ID */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Long lastRecordId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 上一条记录对象 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject lastRecordInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 上年度贡献综合评价分 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal lastYearContributeScore = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 年度新增贡献积分 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal addYearContributeScore = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 当前累计积分池 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal sumScore = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 总分(池+学历+职称/技能) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal allSumScore = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 学历得分 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal diplomaScore = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 学历得分说明 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<String, String> whyDiplomaScore = new LinkedHashMap<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 职称得分 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal rankScore = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 技能得分 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal jobStatusScore = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 调整说明 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        StringBuffer whyAdjust = new StringBuffer(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 升降类型:0降/1保/2升/7固定/8无考核结果 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String adjustType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /** 升降数量:正数升、负数降、0保 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer adjustInt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PositionAppointmentBO positionAppointment; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /**当前任职的序列(未转换前,这里转换指的是:如果是管理序列,则按职能序列进行调整)*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject jobSeq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /**当前任职的序列(转换后,这里转换指的是:如果是管理序列,则按职能序列进行调整)*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DynamicObject convertJobSeq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String remark; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |