فهرست منبع

Merge branch 'refs/heads/feat-swc-mas_1.0'

wyc 9 ساعت پیش
والد
کامیت
fe53be1ef8

+ 142 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/onlineperf/business/extpoint/OnlinePerfSalaryCalServiceExPlugin.java

@@ -0,0 +1,142 @@
+package nckd.jxccl.swc.onlineperf.business.extpoint;
+
+import com.alibaba.fastjson.JSONObject;
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.MainEntityType;
+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.MetadataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.sdk.swc.hscs.business.extpoint.ISalaryCalExtPlugin;
+import kd.sdk.swc.hscs.common.events.AfterSalaryCalEventArgs;
+import kd.sdk.swc.hscs.common.events.CalRollBackEventArgs;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.swc.constants.SwcConstant;
+import nckd.jxccl.swc.onlineperf.common.OnlinePerfConstant;
+
+import java.math.BigDecimal;
+import java.nio.file.OpenOption;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+* 薪酬计算扩展(处理在线即时考核)
+* @author W.Y.C
+* @date 2025/12/17 21:04
+* @version 1.0
+*/
+public class OnlinePerfSalaryCalServiceExPlugin implements ISalaryCalExtPlugin {
+
+    private static final Log log = LogFactory.getLog(OnlinePerfSalaryCalServiceExPlugin.class);
+
+    /**
+     * 薪资计算完成后逻辑处理场景
+     * @param event 薪资计算完成后事件,其中属性包括:
+     * Long taskId 核算任务ID,用于获取核算任务信息
+     * Long recordId 计算会话ID
+     * Long batchId 核算批次ID
+     * String calType 计算类型("onlyPreTaxCal":仅计算税前, "preTaxCal":计算税前,"afterTaxCal":计算税后,"cal":计算(不开启个税计算开关,税前 和税后一起计算)),计算保存埋点在分段计算时或进来两次,计算税前和计算税后,计算只进来一次,可以通过计算类型进行判断是否需要进行业务处理
+     * List<Long> calPersonIdList 当前批次核算名单Id集合,用于获取需要处理的明细结果信息
+     * boolean isFinished 是否计算完成,判断当前次计算是否完成
+     * String traceId 日志跟踪ID,可用于日志打印
+     */
+    @Override
+    public void afterSalaryCal(AfterSalaryCalEventArgs event) {
+        //锁定在线即时考核
+        processOnlinePerfLock(event.getCalPersonIdList(), true);
+    }
+
+    /**
+     * 计算回滚扩展场景
+     */
+    @Override
+    public void afterCancelCalRollBack(CalRollBackEventArgs event) {
+        //解锁在线即时考核
+        processOnlinePerfLock(event.getCalPersonIdList(), false);
+    }
+
+    /**
+     * 处理在线即时考核锁定状态
+     * @param calPersonIdList 核算人员ID列表
+     * @param isLocked 是否锁定
+     */
+    private void processOnlinePerfLock(List<Long> calPersonIdList, boolean isLocked) {
+        // 构建查询字段
+        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                .add(FormConstant.ID_KEY)
+                .add("empnumber")
+                .add("name")
+                .add("org")
+                .addGroup(new String[]{"caltask"}, "calcount", "payrolldate")
+                .addGroup(new String[]{"caltask", "calrule"}, FormConstant.ID_KEY)
+                .addGroup(new String[]{FormConstant.EMPLOYEE_KEY}, FormConstant.ID_KEY);
+        
+        QFilter qFilter = new QFilter("id", "in", calPersonIdList);
+        DynamicObject[] load = SwcConstant.CALPERSON_HELPER.load(queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
+
+        // 如果没有加载到数据则直接返回
+        if(load == null || load.length <= 0) {
+            return;
+        }
+        
+        Map<Long, Long> employeeToCalPersonMap = Arrays.stream(load)
+                .collect(Collectors.toMap(
+                        obj -> obj.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
+                        obj -> obj.getLong(FormConstant.ID_KEY)
+                ));
+
+        long orgId = load[0].getLong(String.join(".", FormConstant.ORG_KEY, FormConstant.ID_KEY));
+        DynamicObject calTask = load[0].getDynamicObject("caltask");
+        Date date = calTask.getDate("payrolldate");
+        int year = DateUtil.getYear(date);
+        int month = DateUtil.getMonthValue(date);
+        long calRuleId = calTask.getLong(String.join(".", "calrule", FormConstant.ID_KEY));
+        int calCount = calTask.getInt("calcount");
+
+        // 在线即时考核查询构建
+        QueryFieldBuilder onlinePerfQueryFieldBuilder = QueryFieldBuilder.create()
+                .add(FormConstant.ID_KEY)
+                .addIdNumberName(OnlinePerfConstant.NCKD_CALRULE)
+                .addIdNumberName(OnlinePerfConstant.NCKD_ADMINORGUNIT)
+                .add(OnlinePerfConstant.NCKD_PERIODYEAR)
+                .add(OnlinePerfConstant.NCKD_PERIODMONTH)
+                .addIdNumberName(OnlinePerfConstant.NCKD_ENTRYENTITY, FormConstant.NCKD_PERSON)
+                .addIdNumberName(OnlinePerfConstant.NCKD_ENTRYENTITY, OnlinePerfConstant.NCKD_SALARYITEM)
+                .add(OnlinePerfConstant.NCKD_ENTRYENTITY, OnlinePerfConstant.NCKD_NMONEY);
+                
+        QFilter onlinePerfFilter = new QFilter(OnlinePerfConstant.NCKD_PERIODYEAR, QCP.equals, year)
+                .and(OnlinePerfConstant.NCKD_PERIODMONTH, QCP.equals, month)
+                .and(String.join(".", OnlinePerfConstant.NCKD_ADMINORGUNIT, FormConstant.ID_KEY),QCP.equals, orgId)
+                .and(String.join(".", OnlinePerfConstant.NCKD_CALRULE, FormConstant.ID_KEY),QCP.equals, calRuleId)
+                .and(String.join(".", OnlinePerfConstant.NCKD_ENTRYENTITY, OnlinePerfConstant.NCKD_PERSON),QCP.in, employeeToCalPersonMap.keySet());
+                
+        DynamicObjectCollection onlinePerfColl = QueryServiceHelper.query(OnlinePerfConstant.ONLINEPERF_ENTITYID, onlinePerfQueryFieldBuilder.buildSelect(), new QFilter[]{onlinePerfFilter});
+        
+        // 如果查询结果为空则直接返回
+        if(!onlinePerfColl.isEmpty()) {
+
+            List<Long> ids = onlinePerfColl.stream().map(obj -> obj.getLong(FormConstant.ID_KEY)).collect(Collectors.toList());
+            MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType(OnlinePerfConstant.ONLINEPERF_ENTITYID);
+            DynamicObject[] dbOnlinePerfArray = BusinessDataServiceHelper.load(ids.toArray(), dataEntityType);
+
+            for (DynamicObject dynamicObject : dbOnlinePerfArray) {
+                dynamicObject.set(OnlinePerfConstant.NCKD_ISCALDYNLOCK, isLocked);
+            }
+
+            // 锁定/解锁在线即时考核结果
+            SaveServiceHelper.saveOperate(OnlinePerfConstant.ONLINEPERF_ENTITYID, dbOnlinePerfArray, OperateOption.create());
+        }
+    }
+}

+ 9 - 2
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/onlineperf/common/OnlinePerfFetchDataService.java

@@ -35,6 +35,7 @@ public class OnlinePerfFetchDataService implements ICustomFetchDataService {
                 .add(FormConstant.ID_KEY)
                 .add("empnumber")
                 .add("name")
+                .add("org")
                 .addGroup(new String[]{"caltask"}, "calcount", "payrolldate")
                 .addGroup(new String[]{"caltask", "calrule"}, FormConstant.ID_KEY)
                 .addGroup(new String[]{FormConstant.EMPLOYEE_KEY}, FormConstant.ID_KEY);
@@ -48,12 +49,13 @@ public class OnlinePerfFetchDataService implements ICustomFetchDataService {
                             obj -> obj.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
                             obj -> obj.getLong(FormConstant.ID_KEY)
                     ));
-
+            long orgId = load[0].getLong(String.join(".", FormConstant.ORG_KEY, FormConstant.ID_KEY));
             DynamicObject calTask = load[0].getDynamicObject("caltask");
             Date date = calTask.getDate("payrolldate");
             int year = DateUtil.getYear(date);
             int month = DateUtil.getMonthValue(date);
             long calRuleId = calTask.getLong(String.join(".", "calrule", FormConstant.ID_KEY));
+            int calCount = calTask.getInt("calcount");
             //在线即时考核
             QueryFieldBuilder onlinePerfQueryFieldBuilder = QueryFieldBuilder.create()
                     .add(FormConstant.ID_KEY)
@@ -66,6 +68,7 @@ public class OnlinePerfFetchDataService implements ICustomFetchDataService {
                     .add(OnlinePerfConstant.NCKD_ENTRYENTITY, OnlinePerfConstant.NCKD_NMONEY);
             QFilter onlinePerfFilter = new QFilter(OnlinePerfConstant.NCKD_PERIODYEAR, QCP.equals, year)
                     .and(OnlinePerfConstant.NCKD_PERIODMONTH, QCP.equals, month)
+                    .and(String.join(".", OnlinePerfConstant.NCKD_ADMINORGUNIT, FormConstant.ID_KEY),QCP.equals, orgId)
                     .and(String.join(".", OnlinePerfConstant.NCKD_CALRULE, FormConstant.ID_KEY),QCP.equals, calRuleId)
                     .and(String.join(".", OnlinePerfConstant.NCKD_ENTRYENTITY, OnlinePerfConstant.NCKD_PERSON),QCP.in, employeeToCalPersonMap.keySet());
             DynamicObjectCollection onlinePerfColl = QueryServiceHelper.query(OnlinePerfConstant.ONLINEPERF_ENTITYID, onlinePerfQueryFieldBuilder.buildSelect(), new QFilter[]{onlinePerfFilter});
@@ -82,7 +85,11 @@ public class OnlinePerfFetchDataService implements ICustomFetchDataService {
                         String salaryItemNumber = onlinePerf.getString(String.join(".", OnlinePerfConstant.NCKD_ENTRYENTITY, OnlinePerfConstant.NCKD_SALARYITEM, FormConstant.NUMBER_KEY));
                         BigDecimal money = onlinePerf.getBigDecimal(String.join(".", OnlinePerfConstant.NCKD_ENTRYENTITY, OnlinePerfConstant.NCKD_NMONEY));
                         if(money.compareTo(BigDecimal.ZERO) > 0) {
-                            json.put(salaryItemNumber, money);
+                            if(calCount == 1) {
+                                json.put(salaryItemNumber, money);
+                            }else{
+                                json.put(salaryItemNumber, BigDecimal.ZERO);
+                            }
                         }
                     }
                 }

+ 22 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/onlineperf/plugin/form/OnlinePerfListPlugin.java

@@ -0,0 +1,22 @@
+package nckd.jxccl.swc.onlineperf.plugin.form;
+
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+
+/**
+ * 标准单据列表插件
+ */
+public class OnlinePerfListPlugin extends AbstractListPlugin implements Plugin {
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
+        if(afterDoOperationEventArgs.getOperationResult() != null && afterDoOperationEventArgs.getOperationResult().isSuccess()){
+            String operateKey = afterDoOperationEventArgs.getOperateKey();
+            if(operateKey.equalsIgnoreCase("unlock")){
+                this.getView().invokeOperation(FormConstant.REFRESH_OP);
+            }
+        }
+    }
+}

+ 98 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/onlineperf/plugin/operate/UnLockOnlinePerfOpPlugin.java

@@ -0,0 +1,98 @@
+package nckd.jxccl.swc.onlineperf.plugin.operate;
+
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.ExtendedDataEntity;
+import kd.bos.entity.operate.result.OperationResult;
+import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
+import kd.bos.entity.plugin.AddValidatorsEventArgs;
+import kd.bos.entity.plugin.PreparePropertysEventArgs;
+import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
+import kd.bos.entity.validate.AbstractValidator;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.swc.constants.SwcConstant;
+import nckd.jxccl.swc.onlineperf.common.OnlinePerfConstant;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+* 解锁在线即时考核
+* 实体标识:nckd_onlineperf
+* @author W.Y.C
+* @date 2025/12/17 21:21
+* @version 1.0
+*/
+public class UnLockOnlinePerfOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
+
+    @Override
+    public void onPreparePropertys(PreparePropertysEventArgs e) {
+        e.getFieldKeys().addAll(this.billEntityType.getAllFields().keySet());
+    }
+
+    @Override
+    public void onAddValidators(AddValidatorsEventArgs e) {
+        e.addValidator(new AbstractValidator() {
+            /*已创建	1
+            未计算	2
+            处理中	3
+            计算完成	9
+            已审核	7
+            审批处理中	8
+            审批不通过	5
+            审批通过	4
+            已废弃	6*/
+//            1、2、5、6
+            @Override
+            public void validate() {
+
+                for (ExtendedDataEntity dataEntity : this.getDataEntities()) {
+                    DynamicObject data = dataEntity.getDataEntity();
+                    boolean isCalDynLock = data.getBoolean(OnlinePerfConstant.NCKD_ISCALDYNLOCK);
+                    if(isCalDynLock) {
+                        long calRuleId = data.getLong(String.join(".", OnlinePerfConstant.NCKD_CALRULE, FormConstant.ID_KEY));
+                        int periodYear = data.getInt(OnlinePerfConstant.NCKD_PERIODYEAR);
+                        int periodMonth = data.getInt(OnlinePerfConstant.NCKD_PERIODMONTH);
+                        long orgId = data.getLong(String.join(".", OnlinePerfConstant.NCKD_ADMINORGUNIT, FormConstant.ID_KEY));
+                        LocalDateTime periodDate = LocalDateTime.of(periodYear, periodMonth, 1, 0, 0);
+                        LocalDateTime beginOfMonth = DateUtil.beginOfMonth(periodDate);
+                        LocalDateTime endOfMonth = DateUtil.endOfMonth(periodDate);
+
+                        QFilter qFilter = new QFilter(String.join(".", "calrule", FormConstant.ID_KEY), QCP.equals, calRuleId)
+                                .and("payrolldate", QCP.large_equals, DateUtil.toDate(beginOfMonth))
+                                .and("payrolldate", QCP.less_equals, DateUtil.toDate(endOfMonth))
+                                .and(String.join(".", FormConstant.ORG_KEY, FormConstant.ID_KEY), QCP.equals, orgId)
+                                .and("taskstatus", QCP.not_in, new String[]{"1", "2", "5", "6"});
+
+                        String selectProperties = QueryFieldBuilder.create().add(FormConstant.ID_KEY).add("taskstatus").buildSelect();
+                        DynamicObject[] load = SwcConstant.CALPAYROLLTASK_HELPER.load(selectProperties, new QFilter[]{qFilter});
+                        if (load != null && load.length > 0) {
+                            this.addFatalErrorMessage(dataEntity, "在线即时考核已被应用于薪酬核算,不能解锁");
+                        }
+                    }else{
+                        this.addFatalErrorMessage(dataEntity, "在线即时考核未锁定,不能解锁");
+                    }
+                }
+            }
+        });
+    }
+
+    @Override
+    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+        for (DynamicObject dataEntity : e.getDataEntities()) {
+            dataEntity.set(OnlinePerfConstant.NCKD_ISCALDYNLOCK, false);
+        }
+        SaveServiceHelper.saveOperate(OnlinePerfConstant.ONLINEPERF_ENTITYID, e.getDataEntities(), OperateOption.create());
+    }
+}