소스 검색

feat(hr): 新增员工初定与年度调整功能优化- 新增员工雇佣信息实体标识常量
- 新增职级序列、入职日期及当前数据标识常量
-优化年度调整服务,增加保级原因计算逻辑- 新增未年度调整人员查询过滤条件
- 完善新入职人员初定日期校验逻辑
- 增加删除员工职位档案时的类型状态判断-优化列表插件中过滤条件与数据包装逻辑
- 新增确认操作参数支持并完善相关提示信息

wyc 2 주 전
부모
커밋
dbd3432b84

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

@@ -41,6 +41,8 @@ public class FormConstant {
     public static final String HBPM_POSITIONHR = "hbpm_positionhr";
     /** 服务年限-实体标识*/
     public static final String HRPI_PERSERLEN = "hrpi_perserlen";
+    /** 雇佣信息-实体标识*/
+    public static final String HRPI_EMPENTREL = "hrpi_empentrel";
 
 
     //====================================== 标品op ======================================
@@ -189,6 +191,10 @@ public class FormConstant {
     public static final String EMPLOYEE_KEY = "employee";
     /**职级序列*/
     public static final String JOBLEVELSEQ = "joblevelseq";
+    /**职级序列*/
+    public static final String ENTRYDATE = "entrydate";
+    /**当前数据*/
+    public static final String ISCURRENTDATA = "iscurrentdata";
 
     /** 工具栏标识(二开)*/
     public static final String NCKD_TOOLBARAP = "nckd_toolbarap";

+ 0 - 2
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/org/helper/AdminOrgHelper.java

@@ -6,9 +6,7 @@ import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.QueryServiceHelper;
 import kd.hr.hbp.business.dao.factory.HRBaseDaoFactory;
-import kd.tdc.oatr.bussiness.queryservice.AdminOrgQueryService;
 import nckd.jxccl.base.common.constant.FormConstant;
-import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
 
 import java.util.HashSet;

+ 78 - 3
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/business/AnnualAdjustmentService.java

@@ -8,6 +8,8 @@ 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.enums.psms.AdjustTypeEnum;
+import nckd.jxccl.base.common.enums.psms.JobSeqEnum;
 import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
 import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.base.common.utils.ConvertUtil;
@@ -137,8 +139,61 @@ public class AnnualAdjustmentService {
             ac.data.getRankingResultInfo().allowanceRankSel = jobLevelResult.rankingResultInfo.allowanceRankSel;
         }
 
+        //【三期需求】:计算保级原因
+        judgeLevelKeepReason(ac, jobLevel);
+
         //10、构建职位档案
         return buildPersonPositionFile(ac, jobLevel);
+
+
+
+    }
+
+    private static void judgeLevelKeepReason(AdjustmentContext ac, DynamicObject jobLevel) {
+        if(AdjustTypeEnum.KEEP_LEVEL.getCode().equals(ac.adjustType)){
+            if(ac.useAppraisalresult){
+                ac.levelKeepReason = 1;
+            }else{
+                BigDecimal allSumScore = ac.allSumScore;
+                int currentSeq = jobLevel.getInt(PositionStructureConstant.JOBLEVELSEQ);
+                //下一级所需的积分
+                DynamicObject nextJobLevel = ac.jobLevelByJobSeqMap.get(currentSeq + 1);
+                if(nextJobLevel != null) {
+                    BigDecimal nextScore = nextJobLevel.getBigDecimal(FormConstant.NCKD_SCORE);
+                    //如果未达到下一级积分则认定:总积分没有达到下一级最低分数要求
+                    if (allSumScore.compareTo(nextScore) < 0) {
+                        //allSumScore小于nextScore
+                        if (ac.rankNoUpGrad) {
+                            //总积分及排名均未达到
+                            ac.levelKeepReason = 6;
+                        } else {
+                            //总积分没有达到下一级最低分数要求
+                            ac.levelKeepReason = 2;
+                        }
+                    } else {
+                        if(ac.rankNoUpGrad) {
+                            //R排名与全员绩效考核等级均未达到升级标准
+                            ac.levelKeepReason = 5;
+                        }else{
+                            //判断职称等级或技能等级是否达到
+                            //1、获取当前职称或技能等级序号
+                            //2、获取>当前职级的所有职级的资格条件的序号,取最小序号
+                            //3、判断当前职称或技能等级序号是否大于最小序号
+                            //4、如果当前职级序号小于最小序号则认为未达到
+                            //这里先不判断,因为其他所有保级情况都已涵盖。剩下的就只有职称或技能达不到了
+                            if (JobSeqEnum.SKILL.getCode().equals(ac.jobSeq.getString(FormConstant.NUMBER_KEY))) {
+                                ac.levelKeepReason = 4;
+                            }else{
+                                ac.levelKeepReason = 3;
+                            }
+                        }
+                    }
+                }else {
+                    //达到职级上限
+                    ac.levelKeepReason = 7;
+                }
+            }
+        }
     }
 
 
@@ -500,6 +555,7 @@ public class AnnualAdjustmentService {
         System.out.println("当前积分所得职级顺序号:::" + jobGradeindex);
 
         Map<Integer, DynamicObject> jobLevelByJobSeqMap = JobLevelCalculatorService.getJobLevelByJobSeqMap(ac.convertJobSeq);
+        ac.jobLevelByJobSeqMap = jobLevelByJobSeqMap;
         int newjobgradeindex = ac.data.getLastJobGradeIndex();
 
         // 补充根据R排名确定是否升级
@@ -507,6 +563,9 @@ public class AnnualAdjustmentService {
             // 如果考评结果不需要升降级则验证R排名
             if (!ac.keep) {
                 newjobgradeindex = JobLevelCalculatorService.getnewjobgradeindexByrank(ac.data.getLastJobGradeIndex(), newjobgradeindex, ac.data.getRankingResultInfo(), ac.convertJobSeq);
+                if(ac.data.getLastJobGradeIndex() == newjobgradeindex){
+                    ac.rankNoUpGrad = true;
+                }
             }
 
             if (newjobgradeindex > jobGradeindex) {
@@ -591,11 +650,16 @@ public class AnnualAdjustmentService {
             System.out.println("绩效分组排名,没有勾选享受职位津贴,保持原职级不变,没有则为最低档");
             ac.whyAdjust.append("绩效分组排名,没有勾选享受职位津贴,保持原职级不变");
             jobLevel = ac.data.getLastJobLevel();
-            ac.adjustType = "0";
+            ac.adjustType = "1";
+            if(ac.useAppraisalresult){
+                ac.levelKeepReason = 1;
+            }
 
             if (jobLevel == null) {
                 jobLevel = JobLevelCalculatorService.getLowestJobLevel(ac.convertJobSeq);
+                ac.adjustType = "0";
             }
+
         } else {
             jobLevel = JobLevelCalculatorService.getJobLevel(ac.convertJobSeq, ac.allSumScore, ac.data.getZgjbNumber(), ac.data.getZyjndjNumber(), 0, Boolean.FALSE,Boolean.FALSE);
             if(jobLevel == null){
@@ -611,9 +675,8 @@ public class AnnualAdjustmentService {
             int jobGradeindex = jobLevel.getInt(FormConstant.JOBLEVELSEQ);
             System.out.println("当前积分所得职级顺序号:::" + jobGradeindex);
 
-            //这里不知道为什么用上一档案的序列?这里沿用SHR的逻辑,避免业务错误
             Map<Integer, DynamicObject> jobLevelByJobSeqMap = JobLevelCalculatorService.getJobLevelByJobSeqMap(ac.data.getConvertLastJobSeq());
-
+            ac.jobLevelByJobSeqMap = jobLevelByJobSeqMap;
             int newjobgradeindex = ac.data.getLastJobGradeIndex();
 
             if (ac.isYearFirstDo) {
@@ -754,6 +817,10 @@ public class AnnualAdjustmentService {
         newPersonPosFile.set(PositionStructureConstant.NCKD_ADDYCONTRIBSCORE, ac.addYearContributeScore);
         // 备注
         newPersonPosFile.set(PositionStructureConstant.KEY_NCKD_CAUSEREMARK, ac.remark);
+        if(AdjustTypeEnum.KEEP_LEVEL.getCode().equals(ac.adjustType)){
+            //保级原因
+            newPersonPosFile.set(PositionStructureConstant.NCKD_LEVELKEEPREASON, ac.levelKeepReason+"");
+        }
 
         return newPersonPosFile;
     }
@@ -846,5 +913,13 @@ public class AnnualAdjustmentService {
 
         /** 调整说明 */
         StringJoiner whyAdjust1 = new StringJoiner(StrFormatter.LINE_SEPARATOR);
+
+        /**标记排名未升级*/
+        boolean rankNoUpGrad = false;
+
+        /***1:本自然年度内已升过级,达到升级限制;2:总积分没有达到下一级最低分数要求;3:未聘任高一级的职称;4:未聘任高一级的技能,5:R排名与全员绩效考核等级均未达到升级标准;6:总积分及排名均未达到;7:达到职级上限*/
+        Integer levelKeepReason;
+
+        Map<Integer, DynamicObject> jobLevelByJobSeqMap;
     }
 }

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

@@ -118,6 +118,8 @@ public class PositionStructureConstant extends FormConstant {
     public static final String KEY_NCKD_LOCKUSER = "nckd_lockuser";
     /** 锁定人 */
     public static final String NCKD_LOCKDATETIME = "nckd_lockdatetime";
+    /** 锁定人 */
+    public static final String NCKD_LEVELKEEPREASON = "nckd_levelkeepreason";
     /** 锁定时间*/
     public static final String POSITIONAPPOINTMENTQUERY = "positionappointmentquery";
     /*-------------------------------------- 员工职位档案 end --------------------------------------*/

+ 3 - 2
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/annualadjust/AnnualAdjustQueryListPlugin.java

@@ -35,9 +35,10 @@ public class AnnualAdjustQueryListPlugin extends AbstractListPlugin implements P
 
     @Override
     public void setFilter(SetFilterEvent e) {
-        e.addCustomQFilter(new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode()));
+        QFilter qFilter = new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode())
         //只查询年度调整的数据
-        e.addCustomQFilter(new QFilter(PositionStructureConstant.NCKD_TYPESTATE, QCP.equals, "3"));
+        .and(new QFilter(PositionStructureConstant.NCKD_TYPESTATE, QCP.equals, "3"));
+        e.addCustomQFilter(qFilter);
     }
 
     @Override

+ 46 - 5
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/annualadjust/UnAnnualAdjustListPlugin.java

@@ -2,21 +2,27 @@ package nckd.jxccl.hr.psms.plugin.form.annualadjust;
 
 import kd.bos.common.enums.EnableEnum;
 import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.entity.datamodel.ListSelectedRow;
 import kd.bos.entity.datamodel.ListSelectedRowCollection;
+import kd.bos.entity.datamodel.events.PackageDataEvent;
 import kd.bos.form.CloseCallBack;
 import kd.bos.form.FormShowParameter;
 import kd.bos.form.ShowType;
 import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.form.events.FilterContainerInitArgs;
 import kd.bos.form.events.SetFilterEvent;
 import kd.bos.list.plugin.AbstractListPlugin;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 
 import java.time.LocalDateTime;
@@ -31,21 +37,56 @@ import java.util.List;
 */
 public class UnAnnualAdjustListPlugin extends AbstractListPlugin implements Plugin {
 
+    @Override
+    public void filterContainerInit(FilterContainerInitArgs args) {
+        super.filterContainerInit(args);
+    }
+
     @Override
     public void setFilter(SetFilterEvent e) {
         //TODO 【待修改】-职位体系-默认过滤掉副科级及以上
         //TODO 【待修改】-职位体系-本年度7月前退休、辞职,则列表中删除该人员
         //过滤掉未初定或初定为当前年或当前年之前或本年度已做过调整的员工
         LocalDateTime localDateTime = DateUtil.beginOfYear(DateUtil.now());
+        //查询当年已执行年度调整的人员
+        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create().addIdNumberName(FormConstant.NCKD_PERSON);
+        QFilter yearFilter = new QFilter(PositionStructureConstant.NCKD_EXECUTEYEAR, QCP.equals, localDateTime.getYear())
+                .and(new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode()))
+                .and(new QFilter(PositionStructureConstant.NCKD_TYPESTATE, QCP.equals, TypeStateEnum.ANNUAL_ADJUSTMENT.getCode()));
+        DynamicObjectCollection query = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{yearFilter});
+        List<Long> personIds = new ArrayList<>(query.size());
+        for (DynamicObject dynamicObject : query) {
+            long personId = dynamicObject.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
+            personIds.add(personId);
+        }
+
         LocalDateTime lastYear = DateUtil.minusYears(localDateTime, 1);
-        QFilter qFilter = new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, PositionStructureConstant.NCKD_DISABLE), QCP.equals, EnableEnum.NO.getCode())
-                .and(new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, PositionStructureConstant.NCKD_FIRSTRANK), QCP.equals, EnableEnum.YES.getCode()))
-                .and(new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, PositionStructureConstant.NCKD_BEGINDATE), QCP.less_than, DateUtil.toDate(localDateTime))
-                .and(new QFilter(String.join(".", PositionStructureConstant.PERFMANAGER_ENTITYID, PositionStructureConstant.PERFMANAGER_ENTRY_ENTITYID,PositionStructureConstant.APPRAISAL_YEAR_KEY),QCP.equals,DateUtil.toDate(lastYear)))
-                );
+        QFilter qFilter = new QFilter(FormConstant.IS_PRIMARY, QCP.equals, EnableEnum.YES.getCode())
+                .and(new QFilter(String.join(".", FormConstant.ASSIGNMENT, FormConstant.IS_PRIMARY), QCP.equals, EnableEnum.YES.getCode()))
+                .and(new QFilter(String.join(".", FormConstant.ASSIGNMENT, FormConstant.IS_DELETED), QCP.equals, EnableEnum.NO.getCode()))
+                .and(new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, PositionStructureConstant.NCKD_DISABLE), QCP.equals, EnableEnum.NO.getCode()))
+                .and(new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, PositionStructureConstant.NCKD_ISCURRENTNEWEST), QCP.equals, EnableEnum.YES.getCode()))
+                //有初定的人员
+                .and(new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID+"init", PositionStructureConstant.NCKD_FIRSTRANK), QCP.equals, EnableEnum.YES.getCode()))
+                //初定时间不等于当年
+                .and(new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID+"init", PositionStructureConstant.NCKD_EXECUTEYEAR), QCP.not_equals2, localDateTime.getYear()))
+                //上年度有考核结果的人员
+                .and(new QFilter(String.join(".", PositionStructureConstant.PERFMANAGER_ENTITYID, PositionStructureConstant.PERFMANAGER_ENTRY_ENTITYID, PositionStructureConstant.APPRAISAL_YEAR_KEY), QCP.equals, DateUtil.toDate(lastYear)))
+                //当年还未年度调整的人员
+                .and(new QFilter(FormConstant.EMPLOYEE_KEY, QCP.not_in, personIds));
         e.addCustomQFilter(qFilter);
     }
 
+    @Override
+    public void packageData(PackageDataEvent e) {
+        super.packageData(e);
+        String colKey = e.getColKey();
+        int year = DateUtil.now().getYear();
+        if ("nckd_currentyear".equals(colKey)) {
+            e.setFormatValue(year);
+        }
+    }
+
     @Override
     public void itemClick(ItemClickEvent evt) {
         String itemKey = evt.getItemKey();

+ 61 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/initial/NewHireInitialBatchFormPlugin.java

@@ -1,17 +1,32 @@
 package nckd.jxccl.hr.psms.plugin.form.initial;
 
+import kd.bos.common.enums.EnableEnum;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.form.FormShowParameter;
 import kd.bos.form.MessageBoxOptions;
 import kd.bos.form.events.AfterDoOperationEventArgs;
 import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.drp.pos.common.util.StringJoin;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 
+import java.time.LocalDateTime;
+import java.util.Date;
 import java.util.EventObject;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
 
 /**
 * 新入职人员初定(弹窗)-弹窗页面插件
@@ -21,11 +36,14 @@ import java.util.Map;
 */
 public class NewHireInitialBatchFormPlugin extends AbstractFormPlugin implements Plugin {
 
+    private boolean affirm = false;
+
     @Override
     public void afterCreateNewData(EventObject e) {
         FormShowParameter showParameter = this.getView().getFormShowParameter();
         //获取列表选择的人员
         Object personId = showParameter.getCustomParam("personId");
+        affirm = ConvertUtil.toBoolean(showParameter.getCustomParam("affirm"),false);
         if(personId != null) {
             initValue(ConvertUtil.toList(personId));
         }
@@ -40,12 +58,54 @@ public class NewHireInitialBatchFormPlugin extends AbstractFormPlugin implements
      * @date: 2025/09/25 21:40
      */
     private void initValue(List<Long> personIds){
-        if(personIds.size() >1) {
+        if(!personIds.isEmpty()) {
             this.getModel().batchCreateNewEntryRow(FormConstant.NCKD_ENTRYENTITY, personIds.size() - 1);
         }
+        Map<Long, DynamicObject> personNextYearDateMap = new HashMap<>();
+        if(affirm && !personIds.isEmpty()){
+            //新入职确认操作,获取入职日期
+            QFilter filter = new QFilter(FormConstant.EMPLOYEE_KEY, QCP.in, personIds).and(new QFilter(FormConstant.ISCURRENTDATA, QCP.equals, EnableEnum.YES.getCode()));
+            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                    .add(FormConstant.ENTRYDATE)
+                    .addIdNumberName(FormConstant.EMPLOYEE_KEY);
+            DynamicObjectCollection query = QueryServiceHelper.query(FormConstant.HRPI_EMPENTREL, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
+            personNextYearDateMap = query.stream()
+                    .collect(Collectors.toMap(
+                            obj -> obj.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
+                            obj -> obj
+                    ));
+
+        }
+        StringJoiner notification = new StringJoiner(StrFormatter.LINE_SEPARATOR);
+        Date current = new Date();
         for (int i = 0; i < personIds.size(); i++) {
             this.getModel().setValue(FormConstant.NCKD_PERSON,personIds.get(i), i);
+
+            if(personNextYearDateMap.get(personIds.get(i)) != null) {
+                DynamicObject dynamicObject = personNextYearDateMap.get(personIds.get(i));
+                Date entryDate = dynamicObject.getDate(FormConstant.ENTRYDATE);
+                //获取入职日期次年1月1号
+                LocalDateTime nextYearDate = DateUtil.addYears(DateUtil.toLocalDateTime(entryDate), 1);
+                LocalDateTime beginYear = DateUtil.beginOfYear(nextYearDate);
+
+                this.getModel().setValue(PositionStructureConstant.NCKD_BEGINDATE, beginYear,i);
+
+                //判断beginYear是否大于当前日期
+                if (DateUtil.toLocalDateTime(current).isBefore(beginYear)) {
+                    String personName = dynamicObject.getString(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.NAME_KEY));
+                    notification.add(StrFormatter.format("人员【{}】的入职时间为【{}】初定日期为【{}】,初定日期不能大于当前日期;",personName,
+                            DateUtil.format(entryDate,DateUtil.NORM_DATE_PATTERN),
+                            DateUtil.format(beginYear,DateUtil.NORM_DATE_PATTERN)));
+
+                }
+            }
+
+
         }
+        if(notification.length() > 0){
+            this.getView().showTipNotification(notification.toString());
+        }
+
 
         this.getView().updateView(FormConstant.NCKD_ENTRYENTITY);
     }

+ 34 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/initial/NewHireInitialFormPlugin.java

@@ -1,19 +1,30 @@
 package nckd.jxccl.hr.psms.plugin.form.initial;
 
+import com.kingdee.cosmic.ctrl.kdf.formatter.StringFormatter;
+import kd.bos.common.enums.EnableEnum;
 import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.entity.datamodel.events.ChangeData;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
 import kd.bos.form.FormShowParameter;
 import kd.bos.form.MessageBoxOptions;
 import kd.bos.form.events.AfterDoOperationEventArgs;
 import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.exception.ValidationException;
 import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 import nckd.jxccl.hr.psms.common.bo.PositionAppointmentBO;
 import nckd.jxccl.hr.psms.helper.PositionStructureHelper;
 
+import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.EventObject;
 import java.util.Map;
@@ -27,11 +38,13 @@ import java.util.Objects;
 */
 public class NewHireInitialFormPlugin extends AbstractFormPlugin implements Plugin {
 
+    private boolean affirm = false;
     @Override
     public void afterCreateNewData(EventObject e) {
         FormShowParameter showParameter = this.getView().getFormShowParameter();
         //获取列表选择的人员
         Object personId = showParameter.getCustomParam("personId");
+        affirm = ConvertUtil.toBoolean(showParameter.getCustomParam("affirm"),false);
         if(personId != null) {
             this.getModel().setValue(FormConstant.NCKD_PERSON, personId);
             this.getView().updateView(FormConstant.NCKD_PERSON);
@@ -112,9 +125,30 @@ public class NewHireInitialFormPlugin extends AbstractFormPlugin implements Plug
                 long quaLevelId = perOcpQual.getLong(String.join(".", FormConstant.QUALEVEL_KEY, FormConstant.ID_KEY));
                 this.getModel().setValue(PositionStructureConstant.NCKD_OCPQUALLEVEL, quaLevelId == 0 ? null : quaLevelId);
             }
+
+            if(affirm){
+                String personName = positionAppointMen.getEmpPosOrgRel().getString(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.NAME_KEY));
+                //新入职确认操作,获取入职日期
+                QFilter filter = new QFilter(FormConstant.EMPLOYEE_KEY, QCP.equals, personId).and(new QFilter(FormConstant.ISCURRENTDATA, QCP.equals, EnableEnum.YES.getCode()));
+                DynamicObject query = QueryServiceHelper.queryOne(FormConstant.HRPI_EMPENTREL, FormConstant.ENTRYDATE, new QFilter[]{filter});
+                Date entryDate = query.getDate(FormConstant.ENTRYDATE);
+                //获取入职日期次年1月1号
+                LocalDateTime nextYearDate = DateUtil.addYears(DateUtil.toLocalDateTime(entryDate), 1);
+                LocalDateTime beginYear = DateUtil.beginOfYear(nextYearDate);
+                //判断beginYear是否大于当前日期
+                Date current = new Date();
+                if(DateUtil.toLocalDateTime(current).isBefore(beginYear)){
+                    this.getView().showTipNotification(StrFormatter.format("人员【{}】的入职时间为【{}】初定日期为【{}】,初定日期不能大于当前日期。",personName,
+                            DateUtil.format(entryDate,DateUtil.NORM_DATE_PATTERN),
+                            DateUtil.format(beginYear,DateUtil.NORM_DATE_PATTERN)));
+                }
+                this.getModel().setValue(PositionStructureConstant.NCKD_BEGINDATE, beginYear);
+            }
         }
         // TODO 【待修改】优秀生
         // this.getModel().setValue(PositionStructureConstant.NCKD_EXCELLENT, );
+
+
     }
 
     @Override

+ 5 - 2
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/initial/UngradedPersonQueryListPlugin.java

@@ -52,7 +52,7 @@ public class UngradedPersonQueryListPlugin extends AbstractListPlugin implements
     public void itemClick(ItemClickEvent evt) {
         String itemKey = evt.getItemKey();
 
-        if("nckd_settingjobgrade".equals(itemKey) || "nckd_settingjobgradenew".equals(itemKey) || "nckd_settingjobgradeb".equals(itemKey) || "nckd_settingjobgradenewb".equals(itemKey)) {
+        if("nckd_settingjobgrade".equals(itemKey) || "nckd_settingjobgradenew".equals(itemKey) || "nckd_settingjobgradeb".equals(itemKey) || "nckd_settingjobgradenewb".equals(itemKey) || "nckd_affirm".equals(itemKey)) {
             ListSelectedRowCollection selectedRows = this.getSelectedRows();
             if(selectedRows.isEmpty()){
                 this.getView().showTipNotification("请至少选择一条数据");
@@ -97,7 +97,8 @@ public class UngradedPersonQueryListPlugin extends AbstractListPlugin implements
                     showParameter.setCloseCallBack(new CloseCallBack(this, PositionStructureConstant.SERVINGINITIAL_ENTITYID));
                     this.getView().showForm(showParameter);
                 }
-            } else if ("nckd_settingjobgradenew".equals(itemKey) || "nckd_settingjobgradenewb".equals(itemKey)) {
+            } else if ("nckd_settingjobgradenew".equals(itemKey) || "nckd_settingjobgradenewb".equals(itemKey) || "nckd_affirm".equals(itemKey)) {
+                boolean affirm = "nckd_affirm".equals(itemKey);
                 if(selectedRows.size() > 1 || "nckd_settingjobgradenewb".equals(itemKey)){
                     //弹出【批量】新入职人员初定窗口
                     FormShowParameter showParameter = new FormShowParameter();
@@ -106,6 +107,7 @@ public class UngradedPersonQueryListPlugin extends AbstractListPlugin implements
                     showParameter.setCaption("【批量】新入职人员初定");
                     showParameter.setSendToClient(true);
                     showParameter.setCustomParam("personId", personIds);
+                    showParameter.setCustomParam("affirm", affirm);
                     showParameter.setCloseCallBack(new CloseCallBack(this, PositionStructureConstant.NEWHIREINITIALBATCH_ENTITYID));
                     this.getView().showForm(showParameter);
                 }else {
@@ -115,6 +117,7 @@ public class UngradedPersonQueryListPlugin extends AbstractListPlugin implements
                     showParameter.getOpenStyle().setShowType(ShowType.Modal);
                     showParameter.setCaption("新入职人员初定-定级信息确认");
                     showParameter.setCustomParam("personId", personIds.get(0));
+                    showParameter.setCustomParam("affirm", affirm);
                     showParameter.setCloseCallBack(new CloseCallBack(this, PositionStructureConstant.NEWHIREINITIAL_ENTITYID));
                     this.getView().showForm(showParameter);
                 }

+ 13 - 5
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/file/PersonPosFileDeleteOpPlugin.java

@@ -19,6 +19,7 @@ import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 import nckd.jxccl.hr.psms.helper.PositionStructureHelper;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -62,7 +63,12 @@ public class PersonPosFileDeleteOpPlugin extends AbstractOperationServicePlugIn
                         }else{
                             idMaps.put(id,rowDataEntity.getDataEntityIndex());
                         }
-                    }else {
+                    }else if(StringUtils.equalsAny(typeState, TypeStateEnum.NEW_ENTRY.getCode(), TypeStateEnum.IN_SERVICE_LEVEL.getCode())){
+                        idMaps.put(id,rowDataEntity.getDataEntityIndex());
+                    }else if (TypeStateEnum.POSITION_TRANSFER.getCode().equalsIgnoreCase(typeState)) {
+                        idMaps.put(id,rowDataEntity.getDataEntityIndex());
+                    }
+                    else {
                         //其他类型不能置回未生效
                         addFatalErrorMessage(rowDataEntity, StrFormatter.format("【{}】不能删除", typeStateEnum.getName()));
                     }
@@ -75,17 +81,19 @@ public class PersonPosFileDeleteOpPlugin extends AbstractOperationServicePlugIn
                     QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                             .add(PositionStructureConstant.ID_KEY)
                             .addGroup(new String[]{FormConstant.NCKD_PERSON}, FormConstant.NAME_KEY)
+                            .addGroup(new String[]{PositionStructureConstant.NCKD_LASTPERSONPOSFILE}, FormConstant.ID_KEY,PositionStructureConstant.NCKD_TYPESTATE)
                             .add(PositionStructureConstant.NCKD_EXECUTEYEAR)
-                            .add(PositionStructureConstant.NCKD_TYPESTATE);
-                    DynamicObjectCollection query = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
+                            .add(PositionStructureConstant.NCKD_TYPESTATE)
+                            .orderDesc(PositionStructureConstant.NCKD_EXECUTEYEAR);
+                    DynamicObjectCollection query = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter},queryFieldBuilder.buildOrder());
                     if(!query.isEmpty()){
                         for (DynamicObject dynamicObject : query) {
-                            long id = dynamicObject.getLong(FormConstant.ID_KEY);
+                            long id = dynamicObject.getLong(String.join(".", PositionStructureConstant.NCKD_LASTPERSONPOSFILE, FormConstant.ID_KEY));
                             String executeYear = dynamicObject.getString(PositionStructureConstant.NCKD_EXECUTEYEAR);
                             String typeState = dynamicObject.getString(PositionStructureConstant.NCKD_TYPESTATE);
                             TypeStateEnum typeStateEnum = TypeStateEnum.getByCode(typeState);
                             String personName = dynamicObject.getString(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NAME_KEY));
-                            addFatalErrorMessage(getDataEntities()[idMaps.get(id)], StrFormatter.format("【{}】的档案已被【{}】年度的“{}”档案使用,不能删除",personName, executeYear,typeStateEnum.getName()));
+                            addFatalErrorMessage(getDataEntities()[idMaps.get(id)], StrFormatter.format("【{}】的档案已被【{}】年度的【{}】档案使用,不能删除",personName, executeYear,typeStateEnum.getName()));
                         }
                     }
                 }