ソースを参照

Merge remote-tracking branch 'origin/master'

turborao 1 週間 前
コミット
7ace59e0a3

+ 4 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/PerfRankMgmtConstant.java

@@ -95,5 +95,9 @@ public class PerfRankMgmtConstant extends FormConstant {
     public static final String NCKD_APPRAISALYEAR = "nckd_appraisalyear";
     /** 分录-是否来源全排名 */
     public static final String NCKD_ISALLRANKSOURCE = "nckd_isallranksource";
+    /** 实际周期结束年份 */
+    public static final String NCKD_ACTENDYEAR = "nckd_actendyear";
+    /** 周期状态 */
+    public static final String NCKD_THESTATUS = "nckd_thestatus";
     /*-------------------------------------- 考核周期(人员考评) end --------------------------------------*/
 }

+ 97 - 14
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/performance/PerfrankMgmtFormPlugin.java

@@ -10,11 +10,10 @@ import kd.bos.entity.EntityMetadataCache;
 import kd.bos.entity.QueryEntityType;
 import kd.bos.entity.constant.StatusEnum;
 import kd.bos.entity.datamodel.IDataModel;
+import kd.bos.entity.datamodel.ListSelectedRow;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
 import kd.bos.entity.datamodel.RowDataEntity;
-import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
-import kd.bos.entity.datamodel.events.BeforeImportEntryEventArgs;
-import kd.bos.entity.datamodel.events.ChangeData;
-import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.entity.datamodel.events.*;
 import kd.bos.ext.hr.service.query.QueryEntityHelper;
 import kd.bos.form.ConfirmCallBackListener;
 import kd.bos.form.ConfirmTypes;
@@ -22,6 +21,7 @@ import kd.bos.form.IClientViewProxy;
 import kd.bos.form.MessageBoxOptions;
 import kd.bos.form.MessageBoxResult;
 import kd.bos.form.container.Wizard;
+import kd.bos.form.control.EntryGrid;
 import kd.bos.form.control.Steps;
 import kd.bos.form.events.AfterDoOperationEventArgs;
 import kd.bos.form.events.BeforeDoOperationEventArgs;
@@ -32,6 +32,7 @@ import kd.bos.logging.Log;
 import kd.bos.logging.LogFactory;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.QueryServiceHelper;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.constant.SystemQueryConstant;
@@ -40,21 +41,17 @@ import nckd.jxccl.base.common.enums.psms.JobSeqEnum;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.base.hrpi.helper.EmpPosOrgRelHelper;
 import nckd.jxccl.hr.psms.common.PerfRankMgmtConstant;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 import nckd.jxccl.hr.psms.helper.PositionFileHelper;
 import org.apache.commons.lang3.StringUtils;
 
+import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.EventObject;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -203,12 +200,98 @@ public class PerfrankMgmtFormPlugin extends AbstractFormPlugin {
                     );
                 }
             }
-        }else if(Arrays.asList(FormConstant.SAVE_OP, FormConstant.SUBMIT_OP).contains(itemKey)){
+        } else if(Arrays.asList(FormConstant.SAVE_OP, FormConstant.SUBMIT_OP).contains(itemKey)){
             //保存或提交先计算一遍
             // calcRankCount();
+        } else if(FormConstant.DELETEENTRY_OP.equalsIgnoreCase(itemKey)){
+            //校验人员考评,若考评周期已结束,则禁止删除。
+            EntryGrid entryGrid = getView().getControl(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);
+            if (entryGrid != null) {
+                Integer theYear = ConvertUtil.toInt(this.getModel().getValue(PerfRankMgmtConstant.NCKD_THEYEAR));
+                LocalDate startDate = LocalDate.of(theYear, 1, 1);
+                // 获取选中行索引数组
+                int[] selectedRows = entryGrid.getSelectRows();
+                List<Long> personIds = new ArrayList<>();
+                if (selectedRows.length > 0) {
+                    for (int rowIndex : selectedRows) {
+                        DynamicObjectCollection entryEntity = this.getModel().getEntryEntity(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);
+                        DynamicObject rowData = entryEntity.get(rowIndex);
+                        DynamicObject person = rowData.getDynamicObject(FormConstant.NCKD_PERSON);
+                        long personId = person.getLong(FormConstant.ID_KEY);
+                        personIds.add(personId);
+                    }
+
+                    if(!personIds.isEmpty()){
+                        DynamicObject[] byDate = getByDate(DateUtil.toDate(startDate), personIds);
+                        for (DynamicObject dynamicObject : byDate) {
+                            String theStatus = dynamicObject.getString(PerfRankMgmtConstant.NCKD_THESTATUS);
+                            DynamicObject person = dynamicObject.getDynamicObject(FormConstant.NCKD_PERSON);
+                            if(!EnableEnum.YES.getCode().equals(theStatus)){
+                                DynamicObjectCollection entryList = dynamicObject.getDynamicObjectCollection(PerfRankMgmtConstant.NCKD_PERFMANAGERENTRY);
+                                for (DynamicObject object : entryList) {
+                                    LocalDateTime appraisalYear = DateUtil.toLocalDateTime(object.getDate(PerfRankMgmtConstant.NCKD_APPRAISALYEAR));
+                                    int year = appraisalYear.getYear();
+                                    if(year == theYear){
+                                        this.getView().showTipNotification(StrFormatter.format("所选人员【{}】考评周期【{}】,不能删除",person.getString(FormConstant.NAME_KEY),"2".equals(theStatus) ? "已锁定":"已结束"));
+                                        args.setCancel(true);
+                                    }
+                                }
+
+                            }
+                        }
+                    }
+                }
+            }
         }
     }
 
+
+    /**
+     * 根据日期查询范围内的考核周期
+     * 查询逻辑说明:
+     * 1. 开始时间条件:考核周期的开始年份(NCKD_BEGINYEAR)必须小于等于指定日期
+     * 2. 结束时间条件:优先使用实际结束年份(NCKD_ACTENDYEAR),如果为空则使用计划结束年份(NCKD_ENDYEAR)
+     * 3. 结束时间必须大于等于指定日期
+     * 4. 即查找满足 "NCKD_BEGINYEAR <= date <= (NCKD_ACTENDYEAR为空时取NCKD_ENDYEAR)" 条件的考核周期
+     *
+     * @param date      指定查询日期
+     * @param personIds 人员ID集合
+     * @return 符合条件的考核周期数组
+     * @author W.Y.C
+     * @date 2025/11/4 17:06
+     */
+    public static DynamicObject[] getByDate(Date date, Collection<Long> personIds) {
+        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                .add(FormConstant.ID_KEY)
+                .addIdNumberName(FormConstant.NCKD_EMPPOSORGREL)
+                .addIdNumberName(FormConstant.NCKD_PERSON)
+                .add(PerfRankMgmtConstant.NCKD_THESTATUS)
+                .addGroup(new String[]{PerfRankMgmtConstant.NCKD_PERFMANAGERENTRY},
+                        PerfRankMgmtConstant.NCKD_APPRAISALRESULT,
+                        PerfRankMgmtConstant.NCKD_APPRAISALYEAR,
+                        PerfRankMgmtConstant.NCKD_ISALLRANKSOURCE);
+
+        // 构造查询条件:日期在[NCKD_BEGINYEAR, NCKD_ENDYEAR]范围内
+        // 考虑到NCKD_ACTENDYEAR可能为空,优先使用NCKD_ACTENDYEAR作为结束时间
+        QFilter filter = new QFilter(PerfRankMgmtConstant.NCKD_BEGINYEAR, QCP.less_equals, date)
+                .and(new QFilter(PerfRankMgmtConstant.NCKD_PERSON, QCP.in, personIds));
+
+        // 添加结束时间判断逻辑
+        QFilter endDateFilter = new QFilter(PerfRankMgmtConstant.NCKD_ACTENDYEAR, QCP.large_equals, date)
+                .or(new QFilter(PerfRankMgmtConstant.NCKD_ACTENDYEAR, QCP.is_null, null)
+                        .and(new QFilter(PerfRankMgmtConstant.NCKD_ENDYEAR, QCP.large_equals, date)));
+
+        filter.and(endDateFilter);
+
+        return BusinessDataServiceHelper.load(PerfRankMgmtConstant.PERFMANAGER_ENTITYID,
+                queryFieldBuilder.buildSelect(), new QFilter[]{filter});
+    }
+
+    @Override
+    public void beforeDeleteRow(BeforeDeleteRowEventArgs e) {
+        super.beforeDeleteRow(e);
+    }
+
     @Override
     public void confirmCallBack(MessageBoxClosedEvent evt) {
         super.confirmCallBack(evt);
@@ -373,7 +456,7 @@ public class PerfrankMgmtFormPlugin extends AbstractFormPlugin {
 
     private void importResultStep() {
         this.getModel().setValue(PerfRankMgmtConstant.NCKD_STEP,1);
-        this.getView().setVisible(false, FormConstant.NUMBER_KEY, FormConstant.NAME_KEY, FormConstant.NCKD_ADMINORG, PerfRankMgmtConstant.NCKD_THEYEAR, PerfRankMgmtConstant.NCKD_GETRANKLIST);
+        this.getView().setVisible(false, FormConstant.NUMBER_KEY, PerfRankMgmtConstant.NCKD_GETRANKLIST);
         this.getView().setVisible(true, PerfRankMgmtConstant.NCKD_TOPRANKS, PerfRankMgmtConstant.NCKD_ALLOWANCERANKS, PerfRankMgmtConstant.NCKD_FAILS, PerfRankMgmtConstant.NCKD_BASICS, PerfRankMgmtConstant.NCKD_EXCELLENTS, "nckd_advconbaritemap6");
         DynamicObjectCollection entryEntity = this.getModel().getEntryEntity(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);
         for (int i = 0; i < entryEntity.size(); i++) {

+ 83 - 18
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/performance/PerfRankMgmtSaveOpPlugin.java

@@ -25,6 +25,7 @@ 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.hrpi.helper.EmpPosOrgRelHelper;
 import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
 import nckd.jxccl.hr.psms.common.PerfRankMgmtConstant;
 import nckd.jxccl.hr.psms.plugin.operate.performance.validate.PerfRankMgmtSaveValidate;
@@ -53,24 +54,64 @@ public class PerfRankMgmtSaveOpPlugin extends AbstractOperationServicePlugIn imp
         e.addValidator(new PerfRankMgmtSaveValidate());
     }
 
+    private Map<Long,List<Long>> dbPersonMap = new HashMap<>();
+
     @Override
     public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+        String invoker = (String)this.getOption().getVariables().get(FormConstant.HR_INVOKER_PARAM_INVOKER);
+        boolean dataMigration = FormConstant.DATA_MIGRATION.equalsIgnoreCase(invoker);
         for (DynamicObject dataEntity : e.getDataEntities()) {
+
+            //事务开始前先查询数据库中的排名名单,找出哪些是此次被删除的人员
+            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                    .addIdNumberName(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY,FormConstant.NCKD_PERSON);
+            QFilter qFilter = new QFilter(FormConstant.ID_KEY, QCP.equals, dataEntity.getLong(FormConstant.ID_KEY));
+            DynamicObjectCollection dbEntryList = QueryServiceHelper.query(PerfRankMgmtConstant.NCKD_PERFRANKMGMT_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
+
+            // 获取数据库中存在的人员ID列表
+            List<Long> dbPersonIds = dbEntryList.stream()
+                    .map(dbEntry -> dbEntry.getLong(String.join(".", PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY,FormConstant.NCKD_PERSON, FormConstant.ID_KEY)))
+                    .collect(Collectors.toList());
+            dbPersonMap.put(dataEntity.getLong(FormConstant.ID_KEY), dbPersonIds);
+
+            List<Long> personids = new ArrayList<>();
             DynamicObjectCollection entryList = dataEntity.getDynamicObjectCollection(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);
             for (DynamicObject entry : entryList) {
                 DynamicObject person = entry.getDynamicObject(FormConstant.NCKD_PERSON);
-                if(person == null){
-                    DynamicObject empPosOrgRel = entry.getDynamicObject(FormConstant.NCKD_EMPPOSORGREL);
+                DynamicObject empPosOrgRel = entry.getDynamicObject(FormConstant.NCKD_EMPPOSORGREL);
+                if(person == null && empPosOrgRel != null){
                     entry.set(FormConstant.NCKD_PERSON, empPosOrgRel.getDynamicObject(FormConstant.EMPLOYEE_KEY));
                 }
+                person = entry.getDynamicObject(FormConstant.NCKD_PERSON);
+                if(person != null) {
+                    personids.add(person.getLong(FormConstant.ID_KEY));
+                }
+            }
+            if(dataMigration){
+                //数据迁移逻辑
+                DynamicObject[] dbEmpPosOrgRelList = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployees(personids);
+                for (DynamicObject entry : entryList) {
+                    DynamicObject person = entry.getDynamicObject(FormConstant.NCKD_PERSON);
+                    DynamicObject empPosOrgRel = entry.getDynamicObject(FormConstant.NCKD_EMPPOSORGREL);
+                    if(empPosOrgRel == null){
+                        long personId = person.getLong(FormConstant.ID_KEY);
+                        for (DynamicObject ebEmpPosOrgRel : dbEmpPosOrgRelList) {
+                            long employeeId = ebEmpPosOrgRel.getDynamicObject(FormConstant.EMPLOYEE_KEY).getLong(FormConstant.ID_KEY);
+                            if(Objects.equals(personId, employeeId)){
+                                entry.set(FormConstant.NCKD_EMPPOSORGREL, ebEmpPosOrgRel);
+                                break;
+                            }
+                        }
+                    }
+                }
             }
-
         }
 
     }
 
     @Override
     public void endOperationTransaction(EndOperationTransactionArgs e) {
+        //-------------------------------- 同步人员考评 begin --------------------------------
         //先查询人员对应考核周期
         for (DynamicObject data : e.getDataEntities()) {
             int theYear = data.getInt(PerfRankMgmtConstant.NCKD_THEYEAR);
@@ -94,9 +135,17 @@ public class PerfRankMgmtSaveOpPlugin extends AbstractOperationServicePlugIn imp
                                 entry -> entry.getDynamicObject(PerfRankMgmtConstant.NCKD_APPRAISALRESULT)
                         ));
 
+
+                List<Long> dbPersonIds = dbPersonMap.get(data.getLong(FormConstant.ID_KEY));
+                // 找出在数据库中存在但在当前列表中不存在的人员ID(即被删除的人员)
+                List<Long> deletedPersonIds = dbPersonIds.stream()
+                        .filter(dbPersonId -> !personIds.contains(dbPersonId))
+                        .collect(Collectors.toList());
+                if(!deletedPersonIds.isEmpty()){
+                    personIds.addAll(deletedPersonIds);
+                }
                 //获取考核周期
                 List<Long> perfManagerIds = findPerfManager(theYear, personIds);
-
                 QFilter filter = QFilterCommonHelper.getIdInFilter(perfManagerIds);
                 MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType(PerfRankMgmtConstant.PERFMANAGER_ENTITYID);
                 DynamicObject[] perfManagerArray = BusinessDataServiceHelper.load(perfManagerIds.toArray(new Long[0]), dataEntityType);
@@ -106,23 +155,38 @@ public class PerfRankMgmtSaveOpPlugin extends AbstractOperationServicePlugIn imp
                 for (DynamicObject perfManager : perfManagerArray) {
                     DynamicObject person = perfManager.getDynamicObject(FormConstant.NCKD_PERSON);
                     long personId = person.getLong(FormConstant.ID_KEY);
-                    DynamicObjectCollection perfManagerEntryColl = perfManager.getDynamicObjectCollection(PerfRankMgmtConstant.NCKD_PERFMANAGERENTRY);
-                    boolean isExist = false;
-                    for (DynamicObject perfManagerEntry : perfManagerEntryColl) {
-                        LocalDateTime appraisalYear = DateUtil.toLocalDateTime(perfManagerEntry.getDate(PerfRankMgmtConstant.NCKD_APPRAISALYEAR));
-                        int year = appraisalYear.getYear();
-                        if(year == theYear){
+                    if(deletedPersonIds.contains(personId)){
+                        //此次删除的人员同步删除人员考评的考核结果
+                        DynamicObjectCollection perfManagerEntryColl = perfManager.getDynamicObjectCollection(PerfRankMgmtConstant.NCKD_PERFMANAGERENTRY);
+                        Iterator<DynamicObject> iterator = perfManagerEntryColl.iterator();
+                        while (iterator.hasNext()) {
+                            DynamicObject perfManagerEntry = iterator.next();
+                            LocalDateTime appraisalYear = DateUtil.toLocalDateTime(perfManagerEntry.getDate(PerfRankMgmtConstant.NCKD_APPRAISALYEAR));
+                            int year = appraisalYear.getYear();
+                            if(year == theYear){
+                                iterator.remove();
+                            }
+                        }
+                    }else{
+                        DynamicObjectCollection perfManagerEntryColl = perfManager.getDynamicObjectCollection(PerfRankMgmtConstant.NCKD_PERFMANAGERENTRY);
+                        boolean isExist = false;
+                        for (DynamicObject perfManagerEntry : perfManagerEntryColl) {
+                            LocalDateTime appraisalYear = DateUtil.toLocalDateTime(perfManagerEntry.getDate(PerfRankMgmtConstant.NCKD_APPRAISALYEAR));
+                            int year = appraisalYear.getYear();
+                            if(year == theYear){
+                                perfManagerEntry.set(PerfRankMgmtConstant.NCKD_APPRAISALRESULT, personAppraisalMap.get(personId));
+                                isExist = true;
+                                break;
+                            }
+                        }
+                        if(!isExist){
+                            DynamicObject perfManagerEntry = perfManagerEntryColl.addNew();
+                            perfManagerEntry.set(PerfRankMgmtConstant.NCKD_APPRAISALYEAR,appraisalYearDate);
                             perfManagerEntry.set(PerfRankMgmtConstant.NCKD_APPRAISALRESULT, personAppraisalMap.get(personId));
-                            isExist = true;
-                            break;
+                            perfManagerEntry.set(PerfRankMgmtConstant.NCKD_ISALLRANKSOURCE, EnableEnum.YES.getCode());
                         }
                     }
-                    if(!isExist){
-                        DynamicObject perfManagerEntry = perfManagerEntryColl.addNew();
-                        perfManagerEntry.set(PerfRankMgmtConstant.NCKD_APPRAISALYEAR,appraisalYearDate);
-                        perfManagerEntry.set(PerfRankMgmtConstant.NCKD_APPRAISALRESULT, personAppraisalMap.get(personId));
-                        perfManagerEntry.set(PerfRankMgmtConstant.NCKD_ISALLRANKSOURCE, EnableEnum.YES.getCode());
-                    }
+
                 }
                 OperateOption option = OperateOption.create();
                 option.setVariableValue(OperateOptionConst.IGNOREINTERACTION, Boolean.TRUE+"");
@@ -142,6 +206,7 @@ public class PerfRankMgmtSaveOpPlugin extends AbstractOperationServicePlugIn imp
                 }
             }
         }
+        //-------------------------------- 同步人员考评 end --------------------------------
     }
 
 

+ 6 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/performance/validate/PerfRankMgmtSaveValidate.java

@@ -262,8 +262,13 @@ public class PerfRankMgmtSaveValidate extends AbstractValidator {
      */
     private void validateEntry(DynamicObject entry, ExtendedDataEntity rowDataEntity,
                                int rowIndex, Set<Long> personIds, ValidationContext context) {
+        String invoker = (String)this.getOption().getVariables().get(FormConstant.HR_INVOKER_PARAM_INVOKER);
+        boolean dataMigration = FormConstant.DATA_MIGRATION.equalsIgnoreCase(invoker);
+        DynamicObject empPosOrgRel = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_EMPPOSORGREL);
         DynamicObject person = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_PERSON);
-        if (person == null) {
+        if(!dataMigration && empPosOrgRel == null){
+            this.addFatalErrorMessage(rowDataEntity, StrFormatter.format("第{}行,请选择人员\n", rowIndex));
+        }else if (person == null) {
             this.addFatalErrorMessage(rowDataEntity, StrFormatter.format("第{}行,请选择人员\n", rowIndex));
         } else {
             // 人员重复校验

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

@@ -24,8 +24,8 @@ import java.util.stream.Collectors;
 public class DataComparisonQueryService {
     private static final Log logger = LogFactory.getLog(DataComparisonQueryService.class);
     private static final String SINSURTASK = "hcsi_sinsurtask";
-    String[] leftFields = new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type", "personSysValue", "companySysValue"};
-    String[] rightFields =  new String[]{"personOutValue", "companyOutValue"};
+    String[] leftFields = new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type", "personSysValue", "personSysValuea", "companySysValue", "companySysValuea"};
+    String[] rightFields =  new String[]{"personOutValue", "personOutValuea","companyOutValue", "companyOutValuea"};
     IDataModel model = null;
     IFormView view = null;
     public DataComparisonQueryService(IDataModel model,IFormView view) {
@@ -97,17 +97,17 @@ public class DataComparisonQueryService {
      * @return
      */
     public DataSet groupCalPersonDetail (DataSet calPersonDataSet) {
-        calPersonDataSet.groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value");
+        calPersonDataSet.groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value").sum("value1");
         DataSet dataSet1 = calPersonDataSet.copy();
         DataSet dataSet2 = calPersonDataSet.copy();
 
         // 按照类型分组汇总
-        DataSet sumSet1 = dataSet1.filter("type = '1'").groupBy(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type"}).sum("value").finish();
-        DataSet sumSet2 = dataSet2.filter("type = '2'").groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value").finish();
+        DataSet sumSet1 = dataSet1.filter("type = '1'").groupBy(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type"}).sum("value").sum("value1").finish();
+        DataSet sumSet2 = dataSet2.filter("type = '2'").groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value").sum("value1").finish();
 
         // join
         JoinDataSet joinDataSet = sumSet1.join(sumSet2).on("welfarepayer", "welfarepayer").on("welfaretypeid", "welfaretypeid").on("empnumber", "empnumber").on("empname", "empname").on("empidcard", "empidcard");
-        DataSet dataSet = joinDataSet.select(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type", "value as personSysValue"}, new String[]{"value as companySysValue"}).finish();
+        DataSet dataSet = joinDataSet.select(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type", "value as personSysValue","value1 as personSysValuea"}, new String[]{"value as companySysValue","value1 as companySysValuea"}).finish();
 
         return dataSet;
     }
@@ -126,17 +126,17 @@ public class DataComparisonQueryService {
     }
 
     public DataSet groupCalPersonDetailOut (DataSet calPersonDataSet) {
-        calPersonDataSet.groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value");
+        calPersonDataSet.groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value").sum("value1");
         DataSet dataSet1 = calPersonDataSet.copy();
         DataSet dataSet2 = calPersonDataSet.copy();
 
         // 按照类型分组汇总
-        DataSet sumSet1 = dataSet1.filter("type = '1'").groupBy(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type"}).sum("value").finish();
-        DataSet sumSet2 = dataSet2.filter("type = '2'").groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value").finish();
+        DataSet sumSet1 = dataSet1.filter("type = '1'").groupBy(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type"}).sum("value").sum("value1").finish();
+        DataSet sumSet2 = dataSet2.filter("type = '2'").groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value").sum("value1").finish();
 
         // join
         JoinDataSet joinDataSet = sumSet1.join(sumSet2).on("welfarepayer", "welfarepayer").on("welfaretypeid", "welfaretypeid").on("empnumber", "empnumber").on("empname", "empname").on("empidcard", "empidcard");
-        DataSet dataSet = joinDataSet.select(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type", "value as personOutValue"}, new String[]{"value as companyOutValue"}).finish();
+        DataSet dataSet = joinDataSet.select(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type", "value as personOutValue", "value1 as personOutValuea"}, new String[]{"value as companyOutValue","value1 as companyOutValuea"}).finish();
 
         return dataSet;
     }

+ 2 - 3
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/formplugin/web/datacomparison/DetailCompareBillEdit.java

@@ -16,9 +16,6 @@ import kd.bos.form.operate.FormOperate;
 import kd.bos.form.plugin.AbstractFormPlugin;
 import kd.bos.logging.Log;
 import kd.bos.logging.LogFactory;
-import kd.bos.orm.query.QCP;
-import kd.bos.orm.query.QFilter;
-import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
 import nckd.jxccl.sit.hcsi.business.datacomparison.DataComparisonQueryService;
 
 import java.math.BigDecimal;
@@ -114,6 +111,8 @@ public class DetailCompareBillEdit extends AbstractFormPlugin {
         }
     }
 
+
+
     @Override
     public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
         super.afterDoOperation(afterDoOperationEventArgs);

+ 1 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/formplugin/web/tp/SinsurTemplateEdit.java

@@ -282,7 +282,7 @@ public class SinsurTemplateEdit extends AbstractFormPlugin implements Plugin {
                     if ("1".equals(itemType)) {
                         tableValueSetter.addRow(new Object[]{matchColumn, itemParam.get("itemType"), itemId, itemId, 0L, 0L, 0L, dataObj.get("nckd_itemnumber"), dataObj.get("nckd_itemname"), itemParam.get("dataTypeId"), common, unicode});
                     } else if ("2".equals(itemType)) {
-                        tableValueSetter.addRow(new Object[]{matchColumn, itemParam.get("itemType"), itemId, 0L, 0L, itemId, 0L, dataObj.get("nckd_itemnumber"), dataObj.get("nckd_itemname"), itemParam.get("dataTypeId"), common, unicode});
+                        tableValueSetter.addRow(new Object[]{matchColumn, itemParam.get("itemType"), itemId, itemId, 0L, 0L, 0L, dataObj.get("nckd_itemnumber"), dataObj.get("nckd_itemname"), itemParam.get("dataTypeId"), common, unicode});
                     } else if ("4".equals(itemType)) {
                         tableValueSetter.addRow(new Object[]{matchColumn, itemParam.get("itemType"), itemId, 0L, 0L, 0L, itemId, dataObj.get("nckd_itemnumber"), dataObj.get("nckd_itemname"), itemParam.get("dataTypeId"), common, unicode});
                     } else if ("3".equals(itemType)) {

+ 13 - 3
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/formplugin/web/tp/SitItemSelectAddItemPlugin.java

@@ -44,12 +44,14 @@ public class SitItemSelectAddItemPlugin extends AbstractBasePlugIn {
     private static final String TREE_VIEW = "nckd_treeviewap";
     private static final String FORM_MOVE_TO = "hsas_calitemmoveto";
     private static final String ITEM_TYPE_II = "II";
-
+    private static final String BASE_TYPE_II = "BI";
     private static final Map<String, String> ITEM_TYPE_MAPPING = new HashMap();
     private static final Map<String, String> ITEM_CATEGORY_MAPPING =  new HashMap();
     static {
         ITEM_TYPE_MAPPING.put("1", ITEM_TYPE_II);
+        ITEM_TYPE_MAPPING.put("2", BASE_TYPE_II);
         ITEM_CATEGORY_MAPPING.put(ITEM_TYPE_II, ITEM_TYPE_II);
+        ITEM_CATEGORY_MAPPING.put(BASE_TYPE_II, BASE_TYPE_II);
     }
 
     @Override
@@ -234,6 +236,7 @@ public class SitItemSelectAddItemPlugin extends AbstractBasePlugIn {
     private List<TreeNode> buildTreeNodeList(Map<String, Map<String, Map<String, Object>>> dataMap) {
         List<TreeNode> list = new ArrayList<>();
         list.addAll(SitItemSelectAddItemServiceHelper.loadInsuranceItemChildNode(null, false, dataMap));
+        list.addAll(SitItemSelectAddItemServiceHelper.loadBaseItemChildNode(false));
         return list;
     }
 
@@ -330,7 +333,7 @@ public class SitItemSelectAddItemPlugin extends AbstractBasePlugIn {
         }
 
         String treeNodeId = treeNode.getId();
-        if (treeNodeId.equals("0_@_BS") || treeNodeId.equals("1_@_BS")) {
+        if (treeNodeId.equals("II") || treeNodeId.equals("BI")) {
             return false;
         }
 
@@ -341,7 +344,12 @@ public class SitItemSelectAddItemPlugin extends AbstractBasePlugIn {
 //        String treeNodeId = treeNode.getId();
 //        String itemCategory = treeNodeId.substring(0, treeNodeId.indexOf('_'));
 //        String itemCategory = ITEM_TYPE_II;
-        return normalizeItemCategory(ITEM_TYPE_II);
+        if(treeNode.getId().equals("999990") || treeNode.getId().equals("999991")){
+            return normalizeItemCategory(BASE_TYPE_II);
+        }
+        else {
+            return normalizeItemCategory(ITEM_TYPE_II);
+        }
     }
 
     private void removeCheckNode(int[] rows) {
@@ -384,6 +392,8 @@ public class SitItemSelectAddItemPlugin extends AbstractBasePlugIn {
         switch (itemCategory) {
             case ITEM_TYPE_II:
                 return "insuranceitemkey";
+            case BASE_TYPE_II:
+                return "baseitemkey";
             default:
                 return "";
         }

+ 25 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/formplugin/web/tp/helper/SinsurTemplateHelper.java

@@ -30,9 +30,34 @@ public class SinsurTemplateHelper {
         }
         Map<String, Map<String, Object>> itemParamMap = new HashMap(itemDatas.size());
         itemParamMap.putAll(getItemParamMap("number", IIUnicodeList, "1", "sitbs_insuranceitem", existItemDataMap, (Long) null));
+        //单独处理一下基本项目:滞纳金跟利息
+        itemParamMap.putAll(getBaseItemParamMap());
         return itemParamMap;
     }
 
+    public static Map<String, Map<String, Object>> getBaseItemParamMap() {
+        Map<String, Map<String, Object>> itemParamMap = new HashMap(2);
+        for (int i = 0; i < 2; i++) {
+            Map<String, Object> itemParam = new HashMap(6);
+            if (i == 0) {
+                itemParam.put("id", 999990L);
+                itemParam.put("dataTypeId", 1020L);
+                itemParam.put("itemType", "2");
+                itemParam.put("itemname", "滞纳金");
+                itemParamMap.put("999990", itemParam);
+            }
+            else {
+                itemParam.put("id", 999991L);
+                itemParam.put("dataTypeId", 1020L);
+                itemParam.put("itemType", "2");
+                itemParam.put("itemname", "利息");
+                itemParamMap.put("999991", itemParam);
+            }
+        }
+        return itemParamMap;
+    }
+
+
     public static Map<String, Map<String, Object>> getItemParamMap(String key, List<String> keyList, String itemType, String entityName, Map<Long, Map<String, Object>> existItemDataMap, Long orgId) {
         if (CollectionUtils.isEmpty(keyList)) {
             return new HashMap(0);

+ 41 - 10
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/formplugin/web/tp/helper/SitItemSelectAddItemServiceHelper.java

@@ -22,7 +22,9 @@ public class SitItemSelectAddItemServiceHelper {
     private static final String DEFAULT_ORDER = "number asc";
 
     private static final String INSURANCEITEM_KEY = "insuranceitemkey";
+    private static final String BASEITEM_KEY = "baseitemkey";
     private static final String ITEM_TYPE_II = "II";
+    private static final String BASE_TYPE_II = "BI";
     private static final String PREFIX_SEPARATOR = "_@_";
 
     /**
@@ -34,9 +36,26 @@ public class SitItemSelectAddItemServiceHelper {
         Map<String, Map<String, Map<String, Object>>> dataMap = new HashMap(4);
         Map<String, Map<String, Object>> insuranceItemMap = this.getInsuranceItemList(false, (QFilter)null, (QFilter)null, orgId);
         dataMap.put("insuranceitemkey", insuranceItemMap);
+        dataMap.put("baseitemkey", getBaseItemMap());
         return dataMap;
     }
 
+
+    public Map<String, Map<String, Object>> getBaseItemMap() {
+        Map<String, Map<String, Object>> baseItemMap = new HashMap<>(3);
+        Map<String, Object> itemMap1 = new HashMap<>(3);
+        itemMap1.put("id", "999990");
+        itemMap1.put("number", "999990");
+        itemMap1.put("name", "滞纳金");
+        baseItemMap.put("滞纳金", itemMap1);
+        Map<String, Object> itemMap2 = new HashMap<>(3);
+        itemMap2.put("id", "999991");
+        itemMap2.put("number", "999991");
+        itemMap2.put("name", "利息");
+        baseItemMap.put("利息", itemMap2);
+        return baseItemMap;
+    }
+
     private Map<String, Map<String, Object>> getInsuranceItemList(boolean isProrationFormula, QFilter countryQFilter, QFilter calBlockQFilter, long orgId) {
         if (isProrationFormula) {
             return Collections.emptyMap();
@@ -150,18 +169,30 @@ public class SitItemSelectAddItemServiceHelper {
         else {
             return totalNodeList;
         }
-//
-//
-//
-//        insuranceItemList.forEach(item ->  {
-//            TreeNode itemNode = new TreeNode(ITEM_TYPE_II, ITEM_TYPE_II + "_" + item.get("id").toString(),
-//                    item.get("name").toString());
-//            treeNodeList.add(itemNode);
-//        });
-//
-//        return treeNodeList;
     }
 
+    public static List<TreeNode> loadBaseItemChildNode(boolean isExpend) {
+        // 最后返回树:
+        List<TreeNode> totalNodeList = new ArrayList<>(2);
+
+        // 构建根节点:
+        TreeNode itemRoot = new TreeNode("", BASE_TYPE_II,
+                ResManager.loadKDString("基本项目-II", "FormulaItemOrFuncTreeHelper_1",
+                        "swc-hsas-business", new Object[0]));
+        itemRoot.setExpend(isExpend);
+        itemRoot.setIsOpened(isExpend);
+        totalNodeList.add(itemRoot);
+
+        //构建子节点,这里固定滞纳金和利息
+        List<TreeNode> children = new ArrayList<>(2);
+        children.add(new TreeNode(BASE_TYPE_II, "999990", "滞纳金"));
+        children.add(new TreeNode(BASE_TYPE_II, "999991", "利息"));
+        itemRoot.setChildren(children);
+        return totalNodeList;
+    }
+
+
+
     private static List<Map<String, Object>> getInsuranceItemList(String name,
                                                                Map<String, Map<String, Map<String, Object>>> dataMap) {
         return SWCStringUtils.isEmpty(name)

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

@@ -22,8 +22,11 @@ public class ReportUtils {
             +"entryentity.nckd_itemvalue as value";
 
     //参保单位,险种,工号,姓名,证件号,单位缴费金额 = 单位固定+单位缴费+单位补缴,个人缴费金额=个人固定+个人缴费+个人补缴
+    //2025-11-17调整 单位缴费金额 = 单位固定+单位缴费,单位补缴金额 = 单位补缴,个人缴费金额=个人固定+个人缴费;个人补缴 = 个人补缴;
     private static String CALPERSON_FIELDS = "welfarepayer.id as welfarepayer,entryentity.insuranceitem.group.id as welfaretypeid,"
-            +"empnumberdb as empnumber,namedb as empname,percre.number as empidcard,entryentity.amountvalue as value,"
+            +"empnumberdb as empnumber,namedb as empname,percre.number as empidcard,"
+            +"case when entryentity.insuranceitem.insurancetypeattr.number in ('1006_S','1005_S','1009_S','1010_S') then entryentity.amountvalue else 0 end as value,"
+            +"case when entryentity.insuranceitem.insurancetypeattr.number in ('1011_S','1012_S') then entryentity.amountvalue else 0 end as value1,"
             +"case when entryentity.insuranceitem.insurancetypeattr.number in ('1005_S','1009_S','1011_S') then '1'"
             +"     when entryentity.insuranceitem.insurancetypeattr.number in ('1006_S','1010_S','1012_S') then '2' end as type";
     private static final String[] INSURANCEPROP = new String[]{"1005_S","1006_S","1009_S","1010_S","1011_S","1012_S"};
@@ -88,8 +91,11 @@ public class ReportUtils {
         DataSet insuranceItemDataSet = queryInsuranceItemDataSet(itemIds);
         DataSet dataSet = outsideDataSet.join(insuranceItemDataSet).on("itemid","id").select(
                 new String[]{"welfarepayer","empnumber","empname","empidcard","cast(value as Decimal(10,2)) as value"},
-                new String[]{"welfaretypeid", "case when attrnumber in ('1005_S','1009_S','1011_S') then '1' when attrnumber in ('1006_S','1010_S','1012_S') then '2' end as type"}).finish();
-        return dataSet;
+                new String[]{"attrnumber", "welfaretypeid", "case when attrnumber in ('1005_S','1009_S','1011_S') then '1' when attrnumber in ('1006_S','1010_S','1012_S') then '2' end as type"}).finish();
+        DataSet dataSet1 = dataSet.select("welfarepayer","empnumber","empname","empidcard","welfaretypeid","attrnumber","type",
+                "case when attrnumber in ('1006_S','1005_S','1009_S','1010_S') then value else 0 end as value",
+                "case when attrnumber in ('1011_S','1012_S') then value else 0 end as value1");
+        return dataSet1;
     }
 
     /**