Sfoglia il codice sorgente

feat(sit): 新增社保年收入计算功能

Tyx 1 giorno fa
parent
commit
ee8f03bacc

+ 223 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/business/annualincome/AnnualIncomeCalculateService.java

@@ -0,0 +1,223 @@
+package nckd.jxccl.sit.hcsi.business.annualincome;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.utils.ObjectUtils;
+import kd.bos.entity.datamodel.IDataModel;
+import kd.bos.form.IFormView;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import nckd.jxccl.sit.hcsi.common.constant.SitConstant;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Tyx 2025-11-20
+ * 社保年度收入计算服务
+ */
+public class AnnualIncomeCalculateService {
+
+    DynamicObject welfarePayer = null;
+    Date year = null;
+
+    IDataModel model;
+
+    IFormView view;
+
+    public AnnualIncomeCalculateService(DynamicObject welfarePayer, Date year, IDataModel model, IFormView view) {
+        this.welfarePayer = welfarePayer;
+        this.year = year;
+        this.model = model;
+        this.view = view;
+    }
+
+    /**
+     * 计算步骤:
+     * 1.根据参保单位获取到人员
+     * 2.根据1获取到的人员去取薪酬模块-年收入统计中的薪酬数据
+     * 3.根据年份+人员去业务数据提报下取外单位年收入数据
+     *
+     * @return
+     */
+    public int calculate() {
+        // 获取社保档案
+        Map<Long, DynamicObject> fileMap = getSinSurFile();
+        // 根据参保单位获取人员
+        Set<Long> employeeIds = fileMap.keySet();
+        // 取薪酬-年收入统计单中的数据
+        Map<Long, Map> incomeBillData = getSalIncomeBillData(employeeIds);
+        // 业务项目
+        Map<Long, DynamicObject> bizItemMap = getBizItem();
+        // 取业务数据提报中的数据
+        Map<Long, Map<Long, String>> bizData = getBizData(bizItemMap);
+        // 处理页面数据
+        return dealData(fileMap, employeeIds, incomeBillData, bizItemMap, bizData);
+    }
+
+    /**
+     * 处理页面数据
+     *
+     * @param employeeIds
+     * @param incomeBillData
+     * @param bizItemMap
+     * @param bizData
+     * @return
+     */
+    public int dealData(Map<Long, DynamicObject> fileMap, Set<Long> employeeIds, Map<Long, Map> incomeBillData, Map<Long, DynamicObject> bizItemMap, Map<Long, Map<Long, String>> bizData) {
+        DynamicObjectCollection billCols = new DynamicObjectCollection();
+        for(Long employeeId : employeeIds) {
+            DynamicObject dyn = SitConstant.SITINCOMEBILL_HELPER.generateEmptyDynamicObject();
+            // 默认值字段
+            dyn.set("billstatus", "A");
+            dyn.set("auditstatus", "A");
+            dyn.set("nckd_year", year);
+            dyn.set("nckd_employee", employeeId);
+            dyn.set("nckd_datastatus", "A");
+            dyn.set("nckd_welfarepayer", welfarePayer);
+            dyn.set("nckd_sinsurfile", fileMap.get(employeeId).getLong("id"));
+            dyn.set("org", fileMap.get(employeeId).getLong("org.id"));
+            dyn.set("billno", UUID.randomUUID().toString().substring(0,29));
+
+            Map incomeBillMap = incomeBillData.get(employeeId);
+            if(!ObjectUtils.isEmpty(incomeBillMap)) {
+                dyn.set("nckd_sysmonth", incomeBillMap.get("totalMonth"));
+                dyn.set("nckd_sysyearamount", incomeBillMap.get("totalAmount"));
+            }
+            Map<Long, String> bizDataMap = bizData.get(employeeId);
+            if(!ObjectUtils.isEmpty(bizDataMap)) {
+                for(Long bizItemId : bizItemMap.keySet()) {
+                    String matchKey = bizItemMap.get(bizItemId).getString("entryentity.bizitem.nckd_incomematchkey");
+                    switch(matchKey) {
+                        case "nckd_outmonth":
+                            int month = Integer.parseInt(bizDataMap.get(bizItemId));
+                            dyn.set(matchKey, month);
+                            break;
+                        case "nckd_outyearamount":
+                            BigDecimal amount = new BigDecimal(bizDataMap.get(bizItemId));
+                            dyn.set(matchKey, amount);
+                            break;
+                    }
+                }
+            }
+            billCols.add(dyn);
+        }
+        // 保存数据
+        Object[] saveDyns = SaveServiceHelper.save(billCols.stream().toArray(DynamicObject[]::new));
+        int successCount = saveDyns.length;
+        return successCount;
+    }
+
+
+    /**
+     * 获取计薪人员ID
+     * @return
+     */
+    public List<Long> getEmployee(DynamicObjectCollection cols) {
+        return cols.stream().map(dynamicObject -> dynamicObject.getLong("employee.id")).collect(Collectors.toList());
+    }
+
+    public Map<Long, DynamicObject> getSinSurFile() {
+        QFilter filter = new QFilter("welfarepayer.id", QCP.equals, welfarePayer.getLong("id"));
+        DynamicObjectCollection cols = SitConstant.SINSURFILE_HELPER.queryOriginalCollection("id,employee.id,org.id", new QFilter[]{filter});
+        return cols.stream().collect(Collectors.toMap((dyx) -> {
+            return dyx.getLong("employee.id");
+        }, (dyx) -> {
+            return dyx;
+        }, (key1, key2) -> {
+            return key2;
+        }));
+    }
+
+
+
+
+    /**
+     * 获取薪酬模块-年收入统计中的数据
+     *
+     * @param employeeIds
+     * @return
+     */
+    public Map<Long, Map> getSalIncomeBillData(Set<Long> employeeIds) {
+        QFilter filter = new QFilter("nckd_entryentity.nckd_employee.id", QCP.in, employeeIds);
+        filter.and("nckd_calyear", QCP.equals, year);
+        DynamicObjectCollection cols = SitConstant.SALINCOMEBILL_HELPER.queryOriginalCollection(SitConstant.SALINCOMEBILL_SELECTFIELDS, new QFilter[]{filter});
+
+        //按照人员汇总
+        Map<Long, Map> incomeMap = cols.stream().collect(Collectors.groupingBy(
+                dyx -> dyx.getLong("nckd_entryentity.nckd_employee"),
+                Collectors.collectingAndThen(
+                        Collectors.toList(),
+                        list -> {
+                            int totalMonth = list.stream().mapToInt(dyx -> dyx.getInt("nckd_entryentity.nckd_month")).sum();
+                            BigDecimal totalAmount = list.stream().map(dyx -> dyx.getBigDecimal("nckd_entryentity.nckd_totalsalary")).reduce(BigDecimal.ZERO, BigDecimal::add);
+                            Map map = new HashMap();
+                            map.put("totalMonth", totalMonth);
+                            map.put("totalAmount", totalAmount);
+                            return map;
+                        }
+                )
+        ));
+
+        return incomeMap;
+
+    }
+
+    public Map<Long, Map<Long, String>> getBizData(Map<Long, DynamicObject> bizItemMap) {
+        Set<Long> bizItemIds = bizItemMap.keySet();
+        //年份转日期
+        String yearStr = yearToStr(year);
+
+        // 前台是显示一行,但实际存储是多行,这里用BusinessDataServiceHelper查
+        QFilter filter = new QFilter("entryentity.bizitem.id", QCP.in, bizItemIds);
+        filter.and("entryentity.value", QCP.equals, yearStr);
+        String selectFields = "id";
+        // 这里不知道什么原因查不出分录业务项目ID,取出ID再调用标准查询
+        DynamicObjectCollection cols = SitConstant.BIZDATABILLENT_HELPER.queryOriginalCollection(selectFields, new QFilter[]{filter});
+        List<Long> entryIds = cols.stream().map(dyx -> dyx.getLong("id")).collect(Collectors.toList());
+        filter = new QFilter("id", QCP.in, entryIds);
+        DynamicObject[] bizDatas = SitConstant.BIZDATABILLENT_HELPER.queryOriginalArray("empposorgrel.employee.id,entryentity.bizitem.id,entryentity.value", new QFilter[]{filter});
+        // 根据employeeId提取出来,k = employeeid, v = Map(k1,v1), k1 = 业务项目ID, v1 = 业务项目值
+        Map<Long, Map<Long, String>> dataMap = Arrays.stream(bizDatas).collect(Collectors.groupingBy(
+                dyx -> dyx.getLong("empposorgrel.employee.id"),
+                Collectors.toMap((dyx) -> {
+                    return dyx.getLong("entryentity.bizitem.id");
+                }, (dyx) -> {
+                    return dyx.getString("entryentity.value");
+                }, (key1, key2) -> {
+                    return key2;
+                })));
+        return dataMap;
+    }
+    /**
+     * 获取业务项目ID
+     *
+     * @return
+     */
+    public Map<Long, DynamicObject> getBizItem() {
+        QFilter filter = new QFilter("number", "=", SitConstant.WDWSR_NUMBER);
+        filter.and("enable", "=", "1");
+        filter.and("status", "=", "C");
+        String selectFields = "id, name, entryentity.bizitem, entryentity.bizitem.id, entryentity.bizitem.name, entryentity.bizitem.number, entryentity.bizitem.nckd_incomematchkey";
+        DynamicObjectCollection bizItemGrpColl = SitConstant.BIZITEMGROUP_HELPER.queryOriginalCollection(selectFields, new QFilter[]{filter});
+
+        Map<Long, DynamicObject> map = bizItemGrpColl.stream().collect(Collectors.toMap((dyx) -> {
+            return dyx.getLong("entryentity.bizitem.id");
+        }, (dyx) -> {
+            return dyx;
+        }, (key1, key2) -> {
+            return key2;
+        }));
+        return map;
+    }
+
+    public String yearToStr(Date year) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(year);
+        return String.valueOf(calendar.get(Calendar.YEAR));
+    }
+
+
+}

+ 15 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/common/constant/SitConstant.java

@@ -5,9 +5,23 @@ import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
 public class SitConstant {
     /*社保档案*/
     public static final HRBaseServiceHelper SINSURFILE_HELPER = new HRBaseServiceHelper("hcsi_sinsurfile");
-
     /*业务项目*/
     public static final HRBaseServiceHelper BIZITEM_HELPER = new HRBaseServiceHelper("hsbs_bizitem");
+    /*薪酬年收入统计单*/
+    public static final HRBaseServiceHelper SALINCOMEBILL_HELPER = new HRBaseServiceHelper("nckd_salannualincomebill");
+    /*查询字段*/
+    public static final String SALINCOMEBILL_SELECTFIELDS = "nckd_entryentity.nckd_employee,nckd_entryentity.nckd_month,nckd_entryentity.nckd_totalsalary";
+    /*社保年收入统计单*/
+    public static final HRBaseServiceHelper SITINCOMEBILL_HELPER = new HRBaseServiceHelper("nckd_sitannualincomebill");
+    /*业务数据提报*/
+    public static final HRBaseServiceHelper BIZDATABILL_HELPER = new HRBaseServiceHelper("hpdi_bizdatabill");
+    /*业务数据提报-业务数据明细*/
+    public static final HRBaseServiceHelper BIZDATABILLENT_HELPER = new HRBaseServiceHelper("hpdi_bizdatabillent");
+    /*业务数据模板*/
+    public static final HRBaseServiceHelper BIZITEMGROUP_HELPER = new HRBaseServiceHelper("hsbs_bizitemgroup");
+    /*业务数据提报-外单位收入模板编码*/
+    public static final String WDWSR_NUMBER = "JT001";
+
 
     public static final String SeparatorA = "_A";
     public static final String SeparatorB = "_B";

+ 58 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/formplugin/web/annualincome/IncomeCalSelectFormPlugin.java

@@ -0,0 +1,58 @@
+package nckd.jxccl.sit.hcsi.formplugin.web.annualincome;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.datamodel.IDataModel;
+import kd.bos.form.IFormView;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.sit.hcsi.business.annualincome.AnnualIncomeCalculateService;
+
+import java.util.Date;
+import java.util.EventObject;
+
+/**
+ * Tyx 2025-11-20
+ * 社保年收入统计列表点击计算打开的界面
+ * 【nckd_incomecalselectform】
+ */
+public class IncomeCalSelectFormPlugin extends AbstractFormPlugin implements Plugin {
+
+
+    @Override
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+
+    }
+
+    @Override
+    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
+        super.beforeDoOperation(args);
+    }
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
+        super.afterDoOperation(afterDoOperationEventArgs);
+        String key = afterDoOperationEventArgs.getOperateKey();
+        switch(key) {
+            case "donothing_calculate":
+                doCalculate();
+        }
+    }
+
+    /**
+     * 执行计算
+     */
+    private void doCalculate() {
+        IDataModel model = this.getModel();
+        IFormView view = this.getView();
+        DynamicObject dyn = model.getDataEntity();
+        DynamicObject welfarePayer = dyn.getDynamicObject("nckd_welfarepayer");
+        Date year = dyn.getDate("nckd_year");
+        AnnualIncomeCalculateService service = new AnnualIncomeCalculateService(welfarePayer, year, model, view);
+        int successCount = service.calculate();
+        view.returnDataToParent(successCount);
+        view.close();
+    }
+}

+ 52 - 0
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/sit/hcsi/formplugin/web/annualincome/SitAnnualIncomeBillListPlugin.java

@@ -0,0 +1,52 @@
+package nckd.jxccl.sit.hcsi.formplugin.web.annualincome;
+
+import kd.bos.form.CloseCallBack;
+import kd.bos.form.FormShowParameter;
+import kd.bos.form.ShowType;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
+import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.form.operate.FormOperate;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.sdk.plugin.Plugin;
+
+import java.util.Map;
+
+/**
+ * 标准单据列表插件
+ */
+public class SitAnnualIncomeBillListPlugin extends AbstractListPlugin implements Plugin {
+
+    @Override
+    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
+        super.beforeDoOperation(args);
+        FormOperate formOperate = (FormOperate)args.getSource();
+        String opKey = formOperate.getOperateKey();
+        switch (opKey) {
+            case "donothing_calculate":
+                this.openCalculatePage();
+                break;
+        }
+    }
+
+    public void openCalculatePage() {
+        FormShowParameter formShowParameter = new FormShowParameter();
+        formShowParameter.setShowTitle(false);
+        formShowParameter.setFormId("nckd_incomecalselectform");
+        formShowParameter.getOpenStyle().setShowType(ShowType.Modal);
+        formShowParameter.setCloseCallBack(new CloseCallBack(this, "calculate"));
+        this.getView().showForm(formShowParameter);
+    }
+
+    @Override
+    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
+        super.closedCallBack(closedCallBackEvent);
+        String actionId = closedCallBackEvent.getActionId();
+        if ("calculate".equals(actionId)) {
+            if(closedCallBackEvent.getReturnData() != null) {
+                int successCount = (int) closedCallBackEvent.getReturnData();
+                this.getView().showSuccessNotification("计算成功,共" + successCount + "条数据");
+                this.getView().invokeOperation("refresh");
+            }
+        }
+    }
+}

+ 1 - 1
code/swc/nckd-jxccl-swc/src/main/java/nckd/jxccl/swc/hpdi/business/coordination/api/SwcCoordBizSaveHandler.java

@@ -38,7 +38,7 @@ public class SwcCoordBizSaveHandler implements CoordBizSaveHandler {
             dyn.set("enddate", endDate);
             dyn.set("nckd_salarygroup", salaryGroup);
             dyn.set("nckd_employee", employee);
-            dyn.set("nckd_salaryfile", salaryFile);
+            dyn.set("nckd_salaryfile", salaryFile.getLong("boid"));
 
             OperationResult result = SaveServiceHelper.saveOperate(SALARYGROUP_ENTITY, new DynamicObject[]{dyn}, OperateOption.create());
             log.info("-------- 薪酬分类保存结果:" + result.isSuccess());