Эх сурвалжийг харах

feat(stm): 新增工资总额分解相关功能

- 在 StmConstant 中新增填报部门常量 NCKD_DEP
- 新增工资总额预算、调整、执行分解的实体标识常量
- 更新 IGNORE_FIELDS 列表,加入新增的填报部门字段
- 新增工资总额调整分解表单插件 TtlWgAdjdeCompFormPlugin
- 新增工资总额执行分解表单插件 TtlWgExecDeCompFormPlugin
- 新增工资总额预算分解总表列表布局插件 TtlWgBgtDeCompListLayoutPlugin
- 实现根据年度和部门自动加载并填充分解数据的功能
- 添加数据差异计算与格式化显示逻辑
wyc 1 өдөр өмнө
parent
commit
59ca9282a4

+ 10 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/stm/common/StmConstant.java

@@ -14,6 +14,8 @@ public class StmConstant extends FormConstant {
     public static final String UNITSTBUDGETAPPLY_ENTITYID = "nckd_unitstbudgetapply";
     /** 填报单位 */
     public static final String NCKD_PAYUNIT = "nckd_payunit";
+    /** 填报部门 */
+    public static final String NCKD_DEP = "nckd_dep";
     /** 年度 */
     public static final String NCKD_YEAR = "nckd_year";
     /** 利润总额/模拟利润 */
@@ -223,7 +225,14 @@ public class StmConstant extends FormConstant {
     /** 本年度预算 */
     public static final String NCKD_SPFCTNUM = "nckd_spfctnum";
 
+    /** 工资总额预算分解-实体标识 */
+    public static final String TTLWGBGTDECOMP_ENTITYID = "nckd_ttlwgbgtdecomp";
+    /** 工资总额调整分解-实体标识 */
+    public static final String TTLWGADJDECOMP_ENTITYID = "nckd_ttlwgadjdecomp";
+    /** 工资总额执行分解-实体标识 */
+    public static final String TTLWGEXECDECOMP_ENTITYID = "nckd_ttlwgexecdecomp";
 
-    public static final List<String> IGNORE_FIELDS = Lists.newArrayList(NCKD_YEAR,NCKD_PAYUNIT,UNITSTBUDGETAPPLY_ENTITYID,GRPTTLWGBGTSUB_ENTITYID,StmConstant.NCKD_PAYUNIT,String.join( ".", StmConstant.NCKD_PAYUNIT, FormConstant.NAME_KEY));
+
+    public static final List<String> IGNORE_FIELDS = Lists.newArrayList(NCKD_YEAR,NCKD_PAYUNIT,NCKD_DEP,UNITSTBUDGETAPPLY_ENTITYID,GRPTTLWGBGTSUB_ENTITYID,StmConstant.NCKD_PAYUNIT,String.join( ".", StmConstant.NCKD_PAYUNIT, FormConstant.NAME_KEY));
     public static final List<String> IGNORE_SUMMARY_FIELDS = Lists.newArrayList(NCKD_DMTEAMTOTAL ,NCKD_DMOTHERTTOTAL ,NCKD_PROFMGRTOTAL,NCKD_TOTALWAGE );
 }

+ 127 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/stm/plugin/form/ttlwg/TtlWgAdjdeCompFormPlugin.java

@@ -0,0 +1,127 @@
+package nckd.jxccl.swc.stm.plugin.form.ttlwg;
+
+import kd.bos.bill.BillShowParameter;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.form.plugin.AbstractFormPlugin;
+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.utils.ConvertUtil;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.entity.helper.EntityHelper;
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
+import nckd.jxccl.swc.mas.common.MasConstant;
+import nckd.jxccl.swc.stm.business.StmService;
+import nckd.jxccl.swc.stm.common.StmConstant;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+/**
+* 工资总额调整分解
+* 实体标识:nckd_ttlwgadjdecomp
+* @author W.Y.C
+* @date 2025/12/15 18:34
+* @version 1.0
+*/
+public class TtlWgAdjdeCompFormPlugin extends AbstractFormPlugin implements Plugin {
+
+    @Override
+    public void propertyChanged(PropertyChangedArgs e) {
+        String fieldKey = e.getProperty().getName();
+        ChangeData[] changeSet = e.getChangeSet();
+        Object oldValue = changeSet[0].getOldValue();
+        Object newValue = changeSet[0].getNewValue();
+        if (Stream.of(StmConstant.NCKD_YEAR,  StmConstant.NCKD_DEP)
+                .anyMatch(op -> op.equalsIgnoreCase(fieldKey))) {
+            if(!Objects.equals(oldValue, newValue)){
+                loadData();
+            }
+
+        }
+    }
+
+    private void loadData(){
+        BillShowParameter showParameter = (BillShowParameter) this.getView().getFormShowParameter();
+        String formId = showParameter.getFormId();
+        if(formId.equalsIgnoreCase(StmConstant.TTLWGADJDECOMP_ENTITYID)) {
+            Date year = this.getModel().getDataEntity(true).getDate(MasConstant.NCKD_YEAR);
+            if (year != null) {
+                // 清理现有数据
+                clearExistingData();
+
+                // 加载同年度同单位的预算申报数据
+                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                        .add(FormConstant.ID_KEY)
+                        .orderDesc(FormConstant.CREATE_TIME_KEY);
+
+                LocalDateTime beginOfYear = DateUtil.beginOfYear(DateUtil.toLocalDateTime(year));
+                LocalDateTime endOfYear = DateUtil.endOfYear(DateUtil.toLocalDateTime(year));
+
+                QFilter qFilter = new QFilter(StmConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
+                        .and(StmConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
+                        .and(QFilterCommonHelper.getBillStatusFilter());
+
+                DynamicObjectCollection unitStBudgetApplyColl = QueryServiceHelper.query(
+                        StmConstant.TTLWGBGTDECOMP_ENTITYID,
+                        queryFieldBuilder.buildSelect(),
+                        new QFilter[]{qFilter},
+                        queryFieldBuilder.buildOrder());
+
+                if (unitStBudgetApplyColl == null || unitStBudgetApplyColl.isEmpty()) {
+                    this.getView().showTipNotification("未加载到数据,根据【年度】【填报部门】未加载到\"工资总额预算分解\"数据!");
+                    return;
+                }
+
+                DynamicObject unitStBudgetApply = unitStBudgetApplyColl.get(0);
+                long id = unitStBudgetApply.getLong(FormConstant.ID_KEY);
+                MainEntityType entityType = EntityMetadataCache.getDataEntityType(StmConstant.TTLWGBGTDECOMP_ENTITYID);
+                DynamicObject[] load = BusinessDataServiceHelper.load(new Long[]{id}, entityType);
+
+                if (load == null || load.length == 0) {
+                    this.getView().showTipNotification("未加载到数据,根据【年度】【填报部门】未加载到\"工资总额预算分解\"数据!");
+                    return;
+                }
+
+                copyBudgetData(load[0]);
+                DynamicObject dynamicObject = EntityHelper.newEntity(StmConstant.TTLWGBGTDECOMP_ENTITYID, load[0].getLong(StmConstant.ID_KEY));
+                this.getModel().setValue(StmConstant.TTLWGBGTDECOMP_ENTITYID, dynamicObject);
+                this.getView().showSuccessNotification("数据加载成功!");
+            }
+        }
+    }
+
+    private void clearExistingData() {
+        DataEntityPropertyCollection properties = this.getModel().getDataEntityType().getProperties();
+        for (IDataEntityProperty property : properties) {
+            String name = property.getName();
+            if (name.indexOf("nckd_") > -1 && this.getModel().getDataEntityType().getProperties().containsKey(name) &&  !name.endsWith("ex") && StmConstant.IGNORE_FIELDS.stream().noneMatch(ignoreField -> ignoreField.equalsIgnoreCase(name))) {
+                this.getModel().setValue(name, null);
+            }
+        }
+    }
+
+    // 提取复制数据逻辑
+    private void copyBudgetData(DynamicObject source) {
+        DataEntityPropertyCollection properties = source.getDynamicObjectType().getProperties();
+        for (IDataEntityProperty property : properties) {
+            String name = property.getName();
+            if (name.indexOf("nckd_") > -1 && this.getModel().getDataEntityType().getProperties().containsKey(name) &&  !name.endsWith("ex") && StmConstant.IGNORE_FIELDS.stream().noneMatch(ignoreField -> ignoreField.equalsIgnoreCase(name))) {
+                this.getModel().setValue(name, source.get(name));
+            }
+        }
+    }
+}

+ 38 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/stm/plugin/form/ttlwg/TtlWgBgtDeCompListLayoutPlugin.java

@@ -0,0 +1,38 @@
+package nckd.jxccl.swc.stm.plugin.form.ttlwg;
+
+import kd.bos.entity.datamodel.events.PackageDataEvent;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.sdk.plugin.Plugin;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+* 工资总额预算分解总表
+* 实体标识:nckd_ttlwgexecdeco_layout
+* @author W.Y.C
+* @date 2025/12/15 19:28
+* @version 1.0
+*/
+public class TtlWgBgtDeCompListLayoutPlugin extends AbstractListPlugin implements Plugin {
+
+
+    @Override
+    public void packageData(PackageDataEvent e) {
+        String colKey = e.getColKey();
+        if("nckd_diff".equalsIgnoreCase(colKey)){
+            BigDecimal itemAmtEx = e.getRowData().getBigDecimal("nckd_itemamtex");
+            BigDecimal itemAmt = e.getRowData().getBigDecimal("nckd_itemamt");
+
+            // 空值处理
+            if (itemAmtEx == null) {
+                itemAmtEx = BigDecimal.ZERO;
+            }
+            if (itemAmt == null) {
+                itemAmt = BigDecimal.ZERO;
+            }
+
+            e.setFormatValue("¥"+itemAmtEx.subtract(itemAmt).setScale(2, RoundingMode.HALF_UP).toString());
+        }
+    }
+}

+ 124 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/stm/plugin/form/ttlwg/TtlWgExecDeCompFormPlugin.java

@@ -0,0 +1,124 @@
+package nckd.jxccl.swc.stm.plugin.form.ttlwg;
+
+import kd.bos.bill.BillShowParameter;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.form.plugin.AbstractFormPlugin;
+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.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.entity.helper.EntityHelper;
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
+import nckd.jxccl.swc.mas.common.MasConstant;
+import nckd.jxccl.swc.stm.common.StmConstant;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+/**
+* 工资总额执行分解
+* 实体标识:nckd_ttlwgexecdecomp
+* @author W.Y.C
+* @date 2025/12/15 18:39
+* @version 1.0
+*/
+public class TtlWgExecDeCompFormPlugin extends AbstractFormPlugin implements Plugin {
+    @Override
+    public void propertyChanged(PropertyChangedArgs e) {
+        String fieldKey = e.getProperty().getName();
+        ChangeData[] changeSet = e.getChangeSet();
+        Object oldValue = changeSet[0].getOldValue();
+        Object newValue = changeSet[0].getNewValue();
+        if (Stream.of(StmConstant.NCKD_YEAR,  StmConstant.NCKD_DEP)
+                .anyMatch(op -> op.equalsIgnoreCase(fieldKey))) {
+            if(!Objects.equals(oldValue, newValue)){
+                loadData();
+            }
+
+        }
+    }
+
+    private void loadData(){
+        BillShowParameter showParameter = (BillShowParameter) this.getView().getFormShowParameter();
+        String formId = showParameter.getFormId();
+        if(formId.equalsIgnoreCase(StmConstant.TTLWGEXECDECOMP_ENTITYID)) {
+            Date year = this.getModel().getDataEntity(true).getDate(MasConstant.NCKD_YEAR);
+            if (year != null) {
+                // 清理现有数据
+                clearExistingData();
+
+                // 加载同年度同单位的预算申报数据
+                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                        .add(FormConstant.ID_KEY)
+                        .orderDesc(FormConstant.CREATE_TIME_KEY);
+
+                LocalDateTime beginOfYear = DateUtil.beginOfYear(DateUtil.toLocalDateTime(year));
+                LocalDateTime endOfYear = DateUtil.endOfYear(DateUtil.toLocalDateTime(year));
+
+                QFilter qFilter = new QFilter(StmConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
+                        .and(StmConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
+                        .and(QFilterCommonHelper.getBillStatusFilter());
+
+                DynamicObjectCollection unitStBudgetApplyColl = QueryServiceHelper.query(
+                        StmConstant.TTLWGADJDECOMP_ENTITYID,
+                        queryFieldBuilder.buildSelect(),
+                        new QFilter[]{qFilter},
+                        queryFieldBuilder.buildOrder());
+
+                if (unitStBudgetApplyColl == null || unitStBudgetApplyColl.isEmpty()) {
+                    this.getView().showTipNotification("未加载到数据,根据【年度】【填报部门】未加载到\"工资总额调整分解\"数据!");
+                    return;
+                }
+
+                DynamicObject unitStBudgetApply = unitStBudgetApplyColl.get(0);
+                long id = unitStBudgetApply.getLong(FormConstant.ID_KEY);
+                MainEntityType entityType = EntityMetadataCache.getDataEntityType(StmConstant.TTLWGADJDECOMP_ENTITYID);
+                DynamicObject[] load = BusinessDataServiceHelper.load(new Long[]{id}, entityType);
+
+                if (load == null || load.length == 0) {
+                    this.getView().showTipNotification("未加载到数据,根据【年度】【填报部门】未加载到\"工资总额调整分解\"数据!");
+                    return;
+                }
+
+                copyBudgetData(load[0]);
+                DynamicObject dynamicObject = EntityHelper.newEntity(StmConstant.TTLWGADJDECOMP_ENTITYID, load[0].getLong(StmConstant.ID_KEY));
+                this.getModel().setValue(StmConstant.TTLWGADJDECOMP_ENTITYID, dynamicObject);
+                this.getView().showSuccessNotification("数据加载成功!");
+            }
+        }
+    }
+
+    private void clearExistingData() {
+        DataEntityPropertyCollection properties = this.getModel().getDataEntityType().getProperties();
+        for (IDataEntityProperty property : properties) {
+            String name = property.getName();
+            if (name.indexOf("nckd_") > -1 && this.getModel().getDataEntityType().getProperties().containsKey(name)  && !name.endsWith("ex") && StmConstant.IGNORE_FIELDS.stream().noneMatch(ignoreField -> ignoreField.equalsIgnoreCase(name))) {
+                this.getModel().setValue(name, null);
+            }
+        }
+    }
+
+    // 提取复制数据逻辑
+    private void copyBudgetData(DynamicObject source) {
+        DataEntityPropertyCollection properties = source.getDynamicObjectType().getProperties();
+        for (IDataEntityProperty property : properties) {
+            String name = property.getName();
+            if (name.indexOf("nckd_") > -1 && this.getModel().getDataEntityType().getProperties().containsKey(name)  && !name.endsWith("ex") && StmConstant.IGNORE_FIELDS.stream().noneMatch(ignoreField -> ignoreField.equalsIgnoreCase(name))) {
+                this.getModel().setValue(name, source.get(name));
+            }
+        }
+    }
+}