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

feat(salary): 实现员工薪酬查询功能

- 新增薪酬数据展示逻辑,支持按日期范围查询
- 动态生成表格列,按薪资项目编号分组显示
- 实现薪资金额汇总计算与格式化显示
- 添加员工信息展示,包括公司与部门信息
- 支持按发放日期和薪资归属日期两种统计口径
- 优化数据绑定逻辑,提升界面响应速度
- 修复标签字段引用错误,确保数据显示正确
- 移除无用的子金额字段定义
- 增加空值处理,提高程序健壮性
- 更新日期选择器默认值为上个月初
turborao 4 өдөр өмнө
parent
commit
b8cc31201d

+ 38 - 0
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/swc/helper/SWCHelper.java

@@ -10,6 +10,7 @@ import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.QueryServiceHelper;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -105,6 +106,43 @@ public class SWCHelper {
         return personIDs;
     }
 
+    /**
+     * 按员工ID查询薪酬数据
+     * @param calPersonIds
+     * @param startdate
+     * @param enddate
+     * @return
+     */
+    public static DynamicObjectCollection querySalaryList(List<Long> calPersonIds, Date startdate, Date enddate, String type) {
+        String entityName = "hsas_caltable";
+        // 获取核算列表信息
+        QFilter filter = new QFilter("calpersonid", QCP.in, calPersonIds);
+        if(type.equals("10")){
+            filter.and("caltask.paydate", QCP.large_equals, startdate);
+            filter.and("caltask.paydate", QCP.less_equals, enddate);
+        }else{
+            filter.and("caltask.payrolldate", QCP.large_equals, startdate);
+            filter.and("caltask.payrolldate", QCP.less_equals, enddate);
+        }
+        //filter.and("caltask.taskstatuse", QCP.equals, "7");   ///任务状态  已审核
+        filter.and("hsas_caltableentry.calamountvalue", QCP.large_than, 0);
+        String orderStr = "";
+        String selectFields = "calpersonid,hsas_caltableentry.salaryitem.number,hsas_caltableentry.salaryitem.name,hsas_caltableentry.calamountvalue";
+        if(type.equals("10")){
+            selectFields = selectFields + ",caltask.paydate as bizdate";
+            orderStr = "caltask.paydate";
+        }else{
+            selectFields = selectFields + ",caltask.payrolldate as bizdate";
+            orderStr = "caltask.payrolldate";
+        }
+        orderStr = orderStr + "hsas_caltableentry.salaryitem.number";
+        selectFields = selectFields + ",caltask.paydate,caltask.payrolldate";
+
+        DynamicObjectCollection calTableDyns = QueryServiceHelper.query(entityName, selectFields, new QFilter[]{filter}, orderStr);
+
+        return calTableDyns;
+    }
+
     /**
      * 判断集合是否为空
      * @param list

+ 283 - 43
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/init/plugin/form/EmpSalaryQueryWebFormPlugin.java

@@ -1,7 +1,10 @@
 package nckd.jxccl.swc.init.plugin.form;
 
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.entity.LocaleString;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.form.control.Label;
 import kd.bos.form.control.grid.DataGrid;
 import kd.bos.form.control.grid.DataGridRow;
 import kd.bos.form.control.grid.DataGridRowBuilder;
@@ -12,13 +15,20 @@ import kd.bos.form.control.grid.events.BeforeCreateDataGridColumnsEvent;
 import kd.bos.form.control.grid.events.BeforeCreateDataGridColumnsListener;
 import kd.bos.form.control.grid.events.DataGridBindDataEvent;
 import kd.bos.form.control.grid.events.DataGridBindDataListener;
+import kd.bos.form.mcontrol.mobtable.MobTable;
 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.bos.servicehelper.user.UserServiceHelper;
 import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.swc.helper.SWCHelper;
+import nckd.jxccl.swc.constants.SwcConstant;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.EventObject;
-import java.util.List;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.util.*;
 
 /**
  * 动态表单插件
@@ -28,11 +38,10 @@ import java.util.List;
 public class EmpSalaryQueryWebFormPlugin extends AbstractFormPlugin implements Plugin, DataGridBindDataListener, BeforeCreateDataGridColumnsListener {
 
 
-    private static final String KEY_LAB_EMP_NAME = "nckd_employee";
+    private static final String KEY_LAB_EMP_NAME = "nckd_name";
     private static final String KEY_LAB_EMP_DESCRIPTION = "nckd_desc";
     private static final String KEY_LAB_REALAMT = "nckd_realamt";
     private static final String KEY_LAB_GROSSAMT = "nckd_grossamt";
-    private static final String KEY_LAB_SUBAMT = "nckd_subamt";
     private static String KEY_CTL_STARTDATE = "startmonth";
     private static String KEY_CTL_ENDDATE = "endmonth";
     private static String KEY_META_PERUSER = "hrpi_personuserrel";
@@ -41,24 +50,230 @@ public class EmpSalaryQueryWebFormPlugin extends AbstractFormPlugin implements P
     private static Date KEY_ENDDATE = new Date();
     private static String KEY_TYPE = "10";
 
+    Map<String, String> itemNameMap = new HashMap<>();
+    Map<String, BigDecimal> calItemAmtMap = new HashMap<>();
+    Map<String, Map<String, BigDecimal>> calItemAmtMapByPeriod = new HashMap<>();
+
+
+    @Override
+    public void beforeBindData(EventObject e) {
+        super.beforeBindData(e);
+
+        this.getModel().setValue(KEY_CTL_STARTDATE, KEY_STARTDATE);
+
+        this.getModel().setValue(KEY_CTL_ENDDATE, KEY_ENDDATE);
+
+        Long userId = UserServiceHelper.getCurrentUserId();
+        this.getModel().setValue("nckd_user", userId);
+
+        DynamicObject personUserDyn = SWCHelper.queryOne(KEY_META_PERUSER, "employee.id","user",userId);
+
+        if(personUserDyn == null){
+            /**
+             * 没有员工信息时,返回常量,用于测试
+             */
+            KEY_EMPID = 2313784485549715456L;
+            // this.getView().showMessage("未找到员工!");
+            // return;
+        }else {
+            KEY_EMPID = personUserDyn.getLong("employee.id");
+        }
+    }
 
-    /**
-     * 初始化为控件增加监听事件
-     */
     @Override
-    public void initialize() {
-        DataGrid dataGrid = this.getControl("nckd_datagridap");
-        // 注册创建列监听事件
-        dataGrid.addBeforeCreateDataGridColumnsListener(this);
-        // 注册绑定数据监听事件
-        dataGrid.addBindDataListener(this);
+    public void afterBindData(EventObject e) {
+        super.afterBindData(e);
+        showData();
     }
 
     @Override
     public void afterCreateNewData(EventObject e) {
         super.afterCreateNewData(e);
-        DataGrid dataGrid = this.getControl("nckd_datagridap");
-        dataGrid.addBindDataListener(this);
+
+        // 设置最大日期为上个月
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(new Date());
+        calendar.add(Calendar.MONTH, -1);
+        calendar.set(Calendar.DAY_OF_MONTH, 1);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        Date lastMonthDate = calendar.getTime();
+        KEY_STARTDATE = lastMonthDate;
+
+    }
+
+    /**
+     * 显示薪酬数据
+     * caltask.paydate       预计支付日期  发放口径
+     * caltask.payrolldate   薪资所属年月  统计口径
+     */
+    public void showData() {
+        // 获取单据头日期范围,开始时间、结束时间
+        Date startdate = KEY_STARTDATE;
+        Date enddate = KEY_ENDDATE;
+        String type = KEY_TYPE;
+
+        if(KEY_EMPID == 0L) {
+            this.getView().showMessage("未找到员工!");
+            return;
+        }
+        String selectFields1 = "id,company.name,adminorg.name,employee.id,employee.name";
+        QFilter filter1 = new QFilter("isprimary", QCP.equals, "1");
+        QFilter filter2 = new QFilter("iscurrentdata", QCP.equals, "1");
+        QFilter filter3 = new QFilter("employee.id", QFilter.equals, KEY_EMPID);
+        DynamicObject employeeDyn = QueryServiceHelper.queryOne("hrpi_empposorgrel",selectFields1, new QFilter[]{filter1, filter2, filter3});
+
+        if(employeeDyn == null){
+            this.getView().showMessage("未找到员工!");
+            return;
+        }
+
+        List<Long> calPersonIds = SWCHelper.queryCalPersonList(KEY_EMPID);
+        if(calPersonIds == null && calPersonIds.size() == 0) {
+            this.getView().showMessage("未找到员工!");
+            return;
+        }
+
+
+        Label label = this.getView().getControl(KEY_LAB_EMP_NAME);
+        label.setText(employeeDyn.getString("employee.name"));
+
+        Label labelDesc = this.getView().getControl(KEY_LAB_EMP_DESCRIPTION);
+        String companyName = employeeDyn.getString("company.name");
+        String adminorgName = employeeDyn.getString("adminorg.name");
+        String desc = "";
+        if(companyName != null){
+            desc = "公司:" + companyName;
+        }
+        if(adminorgName != null){
+            desc = desc + " 部门:" + adminorgName;
+        }
+        labelDesc.setText( desc);
+
+        // 获取核算列表信息
+        DynamicObjectCollection calTableDyns = SWCHelper.querySalaryList(calPersonIds, startdate, enddate, type) ;
+        calItemAmtMap = getCalItemAmt(calTableDyns);
+        itemNameMap = getItemName(calTableDyns);
+        calItemAmtMapByPeriod = getCalItemAmtByPeriod(calTableDyns);
+
+
+        if(calItemAmtMap != null && calItemAmtMap.size() > 0 && itemNameMap != null && !itemNameMap.isEmpty()){
+            DecimalFormat df = new DecimalFormat("#,##0.00");
+            Label label1 = this.getView().getControl(KEY_LAB_REALAMT);
+            if(calItemAmtMap.get("JT_477") == null){
+                label1.setText("0.00");
+            }else {
+                label1.setText(df.format(calItemAmtMap.get("JT_477")));    //实发合计
+            }
+
+            Label label2 = this.getView().getControl(KEY_LAB_GROSSAMT);
+            if(calItemAmtMap.get("JT_283") == null){
+                label2.setText("0.00");
+            }else {
+                label2.setText(df.format(calItemAmtMap.get("JT_283")));   //应发合计
+            }
+
+            /**
+             * 构建表格数据
+             */
+            DataGrid dataGrid = this.getControl("nckd_datagridap");
+            // 注册创建列监听事件
+            dataGrid.addBeforeCreateDataGridColumnsListener(this);
+            // 注册绑定数据监听事件
+            dataGrid.addBindDataListener(this);
+
+        }else{
+            Label label1 = this.getView().getControl(KEY_LAB_REALAMT);
+            label1.setText("0.00");
+            Label label2 = this.getView().getControl(KEY_LAB_GROSSAMT);
+            label2.setText("0.00");
+
+        }
+
+    }
+
+    /**
+     * 按 salaryitem.number 分组汇总金额
+     * @param calTableDyns
+     * @return
+     */
+    public Map<String, BigDecimal> getCalItemAmt(DynamicObjectCollection calTableDyns) {
+        // 按 salaryitem.number 分组汇总金额
+        Map<String, BigDecimal> groupedAmounts = new HashMap<>();
+
+        for (DynamicObject item : calTableDyns) {
+            String salaryItemNumber = item.getString("hsas_caltableentry.salaryitem.number");
+            BigDecimal amount = item.getBigDecimal("hsas_caltableentry.calamountvalue");
+            if (amount == null) {
+                amount = BigDecimal.ZERO;
+            }else{
+                amount = amount.setScale(2, BigDecimal.ROUND_HALF_UP);
+            }
+
+            if (salaryItemNumber != null) {
+                groupedAmounts.put(salaryItemNumber, groupedAmounts.getOrDefault(salaryItemNumber, BigDecimal.ZERO) .add(amount != null ? amount : BigDecimal.ZERO));
+            }
+        }
+        if(groupedAmounts.size() > 0){
+            return groupedAmounts;
+        }
+        return null;
+    }
+
+    /**
+     * 按 period 和 salaryitem.number 分组汇总金额
+     * @param calTableDyns 薪酬数据集合
+     * @return Map<period, Map<itemnumber, amount>> 嵌套Map结构
+     */
+    public Map<String, Map<String, BigDecimal>> getCalItemAmtByPeriod(DynamicObjectCollection calTableDyns) {
+        // 按 period 分组,每个 period 再按 salaryitem.number 分组汇总金额
+        Map<String, Map<String, BigDecimal>> result = new HashMap<>();
+
+        for (DynamicObject item : calTableDyns) {
+            Date bizPeriod = item.getDate("bizdate");
+            String period = DateUtil.format(bizPeriod, "yyyy-MM");
+            String salaryItemNumber = item.getString("hsas_caltableentry.salaryitem.number");
+            BigDecimal amount = item.getBigDecimal("hsas_caltableentry.calamountvalue");
+
+            if (amount == null) {
+                amount = BigDecimal.ZERO;
+            } else {
+                amount = amount.setScale(2, BigDecimal.ROUND_HALF_UP);
+            }
+
+            if (period != null && salaryItemNumber != null) {
+                // 获取当前 period 的子 map,如果不存在则创建新的
+                Map<String, BigDecimal> periodMap = result.computeIfAbsent(period, k -> new HashMap<>());
+                // 在 period 子 map 中累加 salaryItemNumber 对应的金额
+                periodMap.put(salaryItemNumber, periodMap.getOrDefault(salaryItemNumber, BigDecimal.ZERO).add(amount != null ? amount : BigDecimal.ZERO));
+            }
+        }
+
+        return result.isEmpty() ? null : result;
+    }
+
+
+    /**
+     * 按 salaryitem.number 获取名称
+     * @param calTableDyns
+     * @return
+     */
+    public Map<String, String> getItemName(DynamicObjectCollection calTableDyns) {
+        Map<String, String> itemNameMap = new HashMap<>();
+        for (DynamicObject item : calTableDyns) {
+            String salaryItemNumber = item.getString("hsas_caltableentry.salaryitem.number");
+            String salaryItemName = item.getString("hsas_caltableentry.salaryitem.name");
+
+            if (salaryItemNumber != null) {
+                itemNameMap.put(salaryItemNumber, salaryItemName);
+            }
+        }
+        if(itemNameMap.size() > 0){
+            return itemNameMap;
+        }
+        return null;
     }
 
     @Override
@@ -66,16 +281,16 @@ public class EmpSalaryQueryWebFormPlugin extends AbstractFormPlugin implements P
         super.propertyChanged(e);
         String fieldKey = e.getProperty().getName();
         if (fieldKey.equals(KEY_CTL_STARTDATE) || fieldKey.equals(KEY_CTL_ENDDATE)){
-
             KEY_STARTDATE = (Date)this.getModel().getValue(KEY_CTL_STARTDATE);
             KEY_ENDDATE = (Date)this.getModel().getValue(KEY_CTL_ENDDATE);
+            showData();
             this.getView().updateView();
         }
         if (fieldKey.equals("nckd_type")){
 
             KEY_TYPE = (String)this.getModel().getValue("nckd_type");
+            showData();
             this.getView().updateView();
-
         }
     }
 
@@ -87,16 +302,21 @@ public class EmpSalaryQueryWebFormPlugin extends AbstractFormPlugin implements P
     public void beforeCreateDataGridColumns(BeforeCreateDataGridColumnsEvent event) {
         // 所有列集合
         List<DataGridColumn> dataGridColumns = event.getDataGridColumns();
-        // 动态创建文本列
-        TextDataGridColumn column = new TextDataGridColumn();
-        AmountDataGridColumn amountColumn = new AmountDataGridColumn();
-        amountColumn.setKey("colKey");
-        amountColumn.setCaption(new LocaleString("测试列"));
-
-        column.setKey("colKey");
-        column.setCaption(new LocaleString("测试列"));
-        // 加入列集合
-        dataGridColumns.add(column);
+
+        if (itemNameMap != null && !itemNameMap.isEmpty()) {
+            // itemNameMap 为空或者为 null
+            for (String key : itemNameMap.keySet()){
+                // 动态创建金额列
+                AmountDataGridColumn amountColumn = new AmountDataGridColumn();
+                amountColumn.setKey(key);
+                amountColumn.setCaption(new LocaleString(itemNameMap.get( key)));
+
+                // 加入列集合
+                dataGridColumns.add(amountColumn);
+            }
+        }
+
+
     }
 
     /**
@@ -106,20 +326,40 @@ public class EmpSalaryQueryWebFormPlugin extends AbstractFormPlugin implements P
     public void dataGridBindData(DataGridBindDataEvent e) {
         List<Object> list = new ArrayList<>();
         int index = 0;
-        // 从参数获取rowBuilder来辅助构造行数据
-        DataGridRowBuilder builder = e.getDataGridRowBuilder();
-        for (int i = 0; i < 10; i++) {
-            DataGridRow row = builder.buildRow();
-            // rk和seq为系统保留字段(主键和序列号),支持自定义传值
-            row.setValue("rk", index);  // rk必须存在且唯一不能重复
-            row.setValue("seq", index + 1);
-            row.setValue("textfield", "文本列数据");
-            row.setValue("colKey", "动态列数据");
-            list.add(row.get());
-            index++;
-        }
-        // 重要: 传递列表数据
-        e.setData(list);
+        if(calItemAmtMapByPeriod !=  null && calItemAmtMapByPeriod.isEmpty()) {
+            DataGridRowBuilder builder = e.getDataGridRowBuilder();
+            // 遍历每个周期
+            for (Map.Entry<String, Map<String, BigDecimal>> periodEntry : calItemAmtMapByPeriod.entrySet()) {
+                String period = periodEntry.getKey();
+                Map<String, BigDecimal> itemAmountMap = periodEntry.getValue();
+
+                // 为每个周期构建一行数据
+                DataGridRow row = builder.buildRow();
+
+                // 设置系统保留字段
+                row.setValue("rk", index);  // rk必须存在且唯一不能重复
+                row.setValue("seq", index + 1);
+
+                // 设置周期字段(假设用"period"字段表示)
+                row.setValue("nckd_period", period);
+
+                // 遍历该项目的所有薪资项,按itemnumber设置列值
+                for (Map.Entry<String, BigDecimal> itemEntry : itemAmountMap.entrySet()) {
+                    String itemNumber = itemEntry.getKey();
+                    BigDecimal amount = itemEntry.getValue();
+
+                    // 按itemnumber设置对应列的值
+                    row.setValue(itemNumber, amount);
+                }
+
+                list.add(row.get());
+                index++;
+
+            }
+            // 重要: 传递列表数据
+            e.setData(list);
+
+        }
     }
 
 }