Procházet zdrojové kódy

feat(fi): enhance settle bill form plugin with supplier matching logic

- Add import statements for new services and components
- Implement showSettleNote method to display settlement records
- Replace writeOffMainAndAssistLists with supplier-specific version
- Comment out cache update and entry deletion in refreshBill method
- Add supplier number field to query selections
- Modify query sorting criteria for assist bills
- Update write-off logic to only match entries with same supplier
- Add supplier matching validation before performing write-off
- Include supplier information in log outputs and console messages
- Create settlement note record during write-off process
- Remove redundant all-write-off completion check method
turborao před 1 týdnem
rodič
revize
a76dcdfeb0

+ 109 - 71
code/fi/nckd-xtpoc-fi/src/main/java/nckd/xtpoc/fi/app/plugin/form/SettlebillFormPlugin.java

@@ -1,20 +1,28 @@
 package nckd.xtpoc.fi.app.plugin.form;
 
 
+import kd.bos.coderule.api.CodeRuleInfo;
+import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
+import kd.bos.form.ShowFormHelper;
+import kd.bos.form.StyleCss;
 import kd.bos.form.control.EntryGrid;
 import kd.bos.form.control.Toolbar;
 import kd.bos.form.control.events.ItemClickEvent;
 import kd.bos.form.events.BeforeDoOperationEventArgs;
 import kd.bos.form.operate.FormOperate;
 import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.list.ListShowParameter;
 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 kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
 import kd.sdk.plugin.Plugin;
 
 import java.math.BigDecimal;
@@ -94,9 +102,22 @@ public class SettlebillFormPlugin extends AbstractFormPlugin implements Plugin {
             case "refresh":
                 refreshBill();
                 break;
+            case "settlenote":
+                showSettleNote();
+                break;
 
         }
     }
+    public void showSettleNote(){
+
+        ListShowParameter listShowPara = ShowFormHelper.createShowListForm("nckd_settlenote", false);//第二个参数为是否支持多选
+        StyleCss style = new StyleCss();
+        style.setHeight("700");
+        style.setHeight("600");
+        listShowPara.getOpenStyle().setInlineStyleCss(style);
+        listShowPara.setCaption("结算记录");
+        this.getView().showForm(listShowPara);
+    }
 
     public void  autoBill(){
         DynamicObjectCollection entity = this.getModel().getEntryEntity(mainEntry);
@@ -109,7 +130,7 @@ public class SettlebillFormPlugin extends AbstractFormPlugin implements Plugin {
             assistlist.add(dynamicObject);
         }
 
-        writeOffMainAndAssistLists();
+        writeOffMainAndAssistListsWithSameSupplier();
 
         for(DynamicObject dynamicObject : entity){
             for(DynamicObject mainBill : mainlist){
@@ -136,10 +157,10 @@ public class SettlebillFormPlugin extends AbstractFormPlugin implements Plugin {
 
     public void refreshBill(){
 
-        this.getModel().deleteEntryData(mainEntry);
-        this.getModel().deleteEntryData(assistEntry);
+//        this.getModel().deleteEntryData(mainEntry);
+//        this.getModel().deleteEntryData(assistEntry);
         setBillEntry();
-        this.getModel().updateCache(); // 强制更新缓存
+        //this.getModel().updateCache(); // 强制更新缓存
         this.getView().updateView(mainEntry);
         this.getView().updateView(assistEntry);
     }
@@ -168,7 +189,7 @@ public class SettlebillFormPlugin extends AbstractFormPlugin implements Plugin {
             }
         }
 
-        writeOffMainAndAssistLists();
+        writeOffMainAndAssistListsWithSameSupplier();
 
         if(selectRows != null && selectRows.length > 0){
             for(int selectRow :selectRows){
@@ -204,7 +225,7 @@ public class SettlebillFormPlugin extends AbstractFormPlugin implements Plugin {
         this.getModel().getEntryEntity(mainEntry).clear();
         this.getModel().getEntryEntity(assistEntry).clear();
 
-        String selectField1 = "id,billno,fiperiod,company.name,expenseentryentity.id,expenseentryentity.entrywlunit.name,expenseentryentity.expenseamount,expenseentryentity.orgiexpebalanceamount";
+        String selectField1 = "id,billno,fiperiod,company.name,expenseentryentity.id,expenseentryentity.entrywlunit.number,expenseentryentity.entrywlunit.name,expenseentryentity.expenseamount,expenseentryentity.orgiexpebalanceamount";
         QFilter qFilter1 = new QFilter("expenseentryentity.expenseamount", QCP.large_equals, 0); // 启用
 
         DynamicObjectCollection mainDyns = QueryServiceHelper.query(main, selectField1,new QFilter[]{qFilter1},"fiperiod");
@@ -235,11 +256,11 @@ public class SettlebillFormPlugin extends AbstractFormPlugin implements Plugin {
 //            descEntries.add(newEntry);
 //        }
 
-        String selectField2 = "id,billno,bizdate,company.name,billpayerid.name,expenseentryentity.id,expenseentryentity.expenseamount,expenseentryentity.wbamount";
+        String selectField2 = "id,billno,bizdate,company.name,billpayerid.number,billpayerid.name,expenseentryentity.id,expenseentryentity.expenseamount,expenseentryentity.wbamount";
         QFilter qFilter2 = new QFilter("expenseentryentity.expenseamount", QCP.large_equals, 0); // 启用
         QFilter qFilter3 = new QFilter("billpayertype", QCP.equals, "bd_supplier");
 
-        DynamicObjectCollection assistDyns = QueryServiceHelper.query(assist, selectField2,new QFilter[]{qFilter2,qFilter3},"bizdate");
+        DynamicObjectCollection assistDyns = QueryServiceHelper.query(assist, selectField2,new QFilter[]{qFilter2,qFilter3},"billpayerid.number,bizdate");
         logger.info("SettlebillFormPlugin: 辅助单据数量 " + assistDyns.size());
         DynamicObjectCollection descEntries1 = this.getModel().getEntryEntity(assistEntry);
         DynamicObjectType entryType1 = descEntries1.getDynamicObjectType();
@@ -270,38 +291,45 @@ public class SettlebillFormPlugin extends AbstractFormPlugin implements Plugin {
 
     }
 
+
     /**
-     * 逐行核销主体金额集与辅助金额集,直到未核销金额扣减为0
+     * 逐行核销主体金额集与辅助金额集,仅对供应商相同的行进行核销,直到未核销金额扣减为0
      */
-    public void writeOffMainAndAssistLists() {
+    public void writeOffMainAndAssistListsWithSameSupplier() {
         if (mainlist.isEmpty() || assistlist.isEmpty()) {
             System.out.println("主体金额集或辅助金额集为空,无法进行核销");
             return;
         }
 
-        System.out.println("开始执行主体与辅助金额集逐行核销");
+        System.out.println("开始执行相同供应商的主体与辅助金额集逐行核销");
 
         // 遍历主体金额集逐行核销
         for (int i = 0; i < mainlist.size(); i++) {
             DynamicObject mainBill = mainlist.get(i);
 
-            // 获取主体行未核销金额
+            // 获取主体行供应商和未核销金额
+            String mainSupplier = mainBill.getString("nckd_supp");
             BigDecimal mainUnwrittenAmount = mainBill.getBigDecimal("nckd_writeamount");
+
             if (mainUnwrittenAmount == null || mainUnwrittenAmount.compareTo(BigDecimal.ZERO) <= 0) {
                 System.out.println("第" + (i+1) + "行主体金额已无未核销金额,跳过");
-                logger.info("SettlebillFormPlugin: "+"第" + (i+1) + "行主体金额已无未核销金额,跳过");
                 continue;
             }
 
-            System.out.println("处理第" + (i+1) + "行主体金额,未核销金额:" + mainUnwrittenAmount);
-            logger.info("SettlebillFormPlugin: "+ "处理第" + (i+1) + "行主体金额,未核销金额:" + mainUnwrittenAmount);
+            System.out.println("处理第" + (i+1) + "行主体金额,供应商:" + mainSupplier + ",未核销金额:" + mainUnwrittenAmount);
 
-            // 对当前主体行与辅助集进行逐行核销
+            // 对当前主体行与具有相同供应商的辅助集进行逐行核销
             BigDecimal remainingMainAmount = mainUnwrittenAmount;
 
             for (int j = 0; j < assistlist.size() && remainingMainAmount.compareTo(BigDecimal.ZERO) > 0; j++) {
                 DynamicObject assistBill = assistlist.get(j);
 
+                // 检查供应商是否相同
+                String assistSupplier = assistBill.getString("nckd_supp1");
+                if (!isSupplierMatch(mainSupplier, assistSupplier)) {
+                    continue; // 供应商不同,跳过
+                }
+
                 // 获取辅助行未核销金额
                 BigDecimal assistUnwrittenAmount = assistBill.getBigDecimal("nckd_writeoffamount");
                 if (assistUnwrittenAmount == null || assistUnwrittenAmount.compareTo(BigDecimal.ZERO) <= 0) {
@@ -312,7 +340,7 @@ public class SettlebillFormPlugin extends AbstractFormPlugin implements Plugin {
                 BigDecimal writeOffAmount = remainingMainAmount.min(assistUnwrittenAmount);
 
                 // 执行核销操作
-                performRowWriteOff(mainBill, assistBill, writeOffAmount);
+                performRowWriteOffWithSupplier(mainBill, assistBill, writeOffAmount, mainSupplier);
 
                 // 更新主体行未核销金额
                 remainingMainAmount = remainingMainAmount.subtract(writeOffAmount);
@@ -322,96 +350,106 @@ public class SettlebillFormPlugin extends AbstractFormPlugin implements Plugin {
                 BigDecimal newAssistUnwrittenAmount = assistUnwrittenAmount.subtract(writeOffAmount);
                 assistBill.set("nckd_writeoffamount", newAssistUnwrittenAmount);
 
-                System.out.println("主体行" + (i+1) + "与辅助行" + (j+1) + "核销金额:" + writeOffAmount +
-                        ",主体剩余未核销:" + remainingMainAmount +
-                        ",辅助剩余未核销:" + newAssistUnwrittenAmount);
-                logger.info("SettlebillFormPlugin: 主体行"+ (i+1) + "与辅助行" + (j+1) + "核销金额:" + writeOffAmount +
+                System.out.println("主体行" + (i+1) + "(供应商:" + mainSupplier + ")与辅助行" + (j+1) +
+                        "(供应商:" + assistSupplier + ")核销金额:" + writeOffAmount +
                         ",主体剩余未核销:" + remainingMainAmount +
                         ",辅助剩余未核销:" + newAssistUnwrittenAmount);
             }
 
             if (remainingMainAmount.compareTo(BigDecimal.ZERO) <= 0) {
-                System.out.println("第" + (i+1) + "行主体金额已全部核销完成");
-                logger.info("SettlebillFormPlugin: "+ (i+1) + "行主体金额已全部核销完成");
+                System.out.println("第" + (i+1) + "行主体金额(供应商:" + mainSupplier + ")已全部核销完成");
             } else {
-                System.out.println("第" + (i+1) + "行主体金额部分核销,剩余未核销金额:" + remainingMainAmount);
-                logger.info("SettlebillFormPlugin: 第" + (i+1) + "行主体金额部分核销,剩余未核销金额:" + remainingMainAmount);
+                System.out.println("第" + (i+1) + "行主体金额(供应商:" + mainSupplier + ")部分核销,剩余未核销金额:" + remainingMainAmount);
             }
         }
 
         // 检查辅助金额集中是否有未核销完的金额
-        checkRemainingAssistAmounts();
+        checkRemainingAssistAmountsWithSupplier();
 
-        System.out.println("主体与辅助金额集逐行核销处理完成");
-        logger.info("SettlebillFormPlugin: 主体与辅助金额集逐行核销处理完成");
+        System.out.println("相同供应商的主体与辅助金额集逐行核销处理完成");
     }
 
     /**
-     * 检查辅助金额集中的剩余未核销金额
+     * 检查供应商是否匹配
+     * @param mainSupplier 主体供应商
+     * @param assistSupplier 辅助供应商
+     * @return 是否匹配
      */
-    private void checkRemainingAssistAmounts() {
-        boolean hasRemaining = false;
-        for (int i = 0; i < assistlist.size(); i++) {
-            DynamicObject assistBill = assistlist.get(i);
+    private boolean isSupplierMatch(String mainSupplier, String assistSupplier) {
+        if (mainSupplier == null && assistSupplier == null) {
+            return true;
+        }
+        if (mainSupplier == null || assistSupplier == null) {
+            return false;
+        }
+        return mainSupplier.equals(assistSupplier);
+    }
+
+    /**
+     * 检查辅助金额集中相同供应商的剩余未核销金额
+     */
+    private void checkRemainingAssistAmountsWithSupplier() {
+        // 按供应商分组检查
+        for (DynamicObject assistBill : assistlist) {
             BigDecimal assistUnwrittenAmount = assistBill.getBigDecimal("nckd_writeoffamount");
+            String assistSupplier = assistBill.getString("nckd_supp1");
+
             if (assistUnwrittenAmount != null && assistUnwrittenAmount.compareTo(BigDecimal.ZERO) > 0) {
-                System.out.println("辅助行" + (i+1) + "仍有未核销金额:" + assistUnwrittenAmount);
-                hasRemaining = true;
+                System.out.println("辅助行(供应商:" + assistSupplier + ")仍有未核销金额:" + assistUnwrittenAmount);
             }
         }
-
-        if (!hasRemaining) {
-            System.out.println("所有辅助金额均已核销完成");
-        }
     }
 
     /**
-     * 执行单笔核销操作
+     * 执行单笔核销操作(带供应商信息)
      * @param mainBill 主体金额行
      * @param assistBill 辅助金额行
      * @param amount 核销金额
+     * @param supplier 供应商信息
      */
-    private void performRowWriteOff(DynamicObject mainBill, DynamicObject assistBill, BigDecimal amount) {
+    private void performRowWriteOffWithSupplier(DynamicObject mainBill, DynamicObject assistBill,
+                                                BigDecimal amount, String supplier) {
         // 获取单据相关信息
         String mainBillNo = mainBill.getString("nckd_billno");
         String assistBillNo = assistBill.getString("nckd_billno1");
 
-        logger.info("SettlebillFormPlugin: 执行核销:主体单据[" + mainBillNo + "] 与 辅助单据[" + assistBillNo + "] 核销金额:" + amount);
-        System.out.println("执行核销:主体单据[" + mainBillNo + "] 与 辅助单据[" + assistBillNo + "] 核销金额:" + amount);
+        System.out.println("执行核销:主体单据[" + mainBillNo + "] 与 辅助单据[" + assistBillNo +
+                "] (供应商:" + supplier + ") 核销金额:" + amount);
 
         // TODO: 在此处添加实际的核销业务逻辑,如:
         // 1. 更新数据库中的核销状态
         // 2. 生成核销记录
-        // 3. 更新相关账务信息
-        // 4. 更新界面显示状态等
-    }
-
-    /**
-     * 检查是否所有金额都已核销完成
-     * @return 是否全部核销完成
-     */
-    public boolean isAllWriteOffCompleted() {
-        // 检查主体金额是否全部核销完成
-        for (DynamicObject mainBill : mainlist) {
-            BigDecimal unwrittenAmount = mainBill.getBigDecimal("nckd_writeamount");
-            if (unwrittenAmount != null && unwrittenAmount.compareTo(BigDecimal.ZERO) > 0) {
-                System.out.println("存在未完成核销的主体金额");
-                return false;
-            }
-        }
 
-        // 检查辅助金额是否全部核销完成
-        for (DynamicObject assistBill : assistlist) {
-            BigDecimal unwrittenAmount = assistBill.getBigDecimal("nckd_writeoffamount");
-            if (unwrittenAmount != null && unwrittenAmount.compareTo(BigDecimal.ZERO) > 0) {
-                System.out.println("存在未完成核销的辅助金额");
-                return false;
-            }
+        String entityName = "nckd_settlenote";
+        DynamicObject dyn = BusinessDataServiceHelper.newDynamicObject(entityName);
+        CodeRuleInfo codeRule = CodeRuleServiceHelper.getCodeRule(dyn.getDataEntityType().getName(), dyn, null);
+        String number = CodeRuleServiceHelper.getNumber(codeRule, dyn);
+        dyn.set("number", number);
+        dyn.set("name", "费用预提与对公报销");
+        dyn.set("status", "C");
+        dyn.set("creator", RequestContext.get().getUserId());
+        dyn.set("nckd_mainfid", mainBill.getString("nckd_fid"));
+        dyn.set("nckd_mainbillno", mainBill.getString("nckd_billno"));
+        dyn.set("nckd_supp", mainBill.getString("nckd_supp"));
+        dyn.set("nckd_assistfid", assistBill.getString("nckd_fid1"));
+        dyn.set("nckd_asstentryid", assistBill.getString("nckd_fentryid1"));
+        dyn.set("nckd_mainentryid", mainBill.getString("nckd_fentryid"));
+        dyn.set("nckd_asstbillno", assistBill.getString("nckd_billno1"));
+        dyn.set("nckd_maintype", mainBill.getString("nckd_billtype"));
+        dyn.set("nckd_assttype", assistBill.getString("nckd_billtype1"));
+        //dyn.set("nckd_maindate", mainBill.getDate("nckd_date"));
+        //dyn.set("nckd_asstdate", assistBill.getDate("nckd_date1"));
+        dyn.set("nckd_mainamt", mainBill.getBigDecimal("nckd_amount"));
+        dyn.set("nckd_asstamt", assistBill.getBigDecimal("nckd_amount1"));
+        dyn.set("nckd_maincheckamt", mainBill.getBigDecimal("nckd_writeamount"));
+        dyn.set("nckd_asstcheckamt", assistBill.getBigDecimal("nckd_writeoffamount"));
+        dyn.set("nckd_amount", amount);
+
+        if (dyn != null) {
+            Object[] o = SaveServiceHelper.save(new DynamicObject[]{dyn});
         }
-
-        System.out.println("所有金额均已核销完成");
-        return true;
+        // 3. 更新相关账务信息
+        // 4. 更新界面显示状态等
     }
 
-
 }