|
|
@@ -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;
|
|
|
+ }
|
|
|
+}
|