From 60c1cbe98da4ead86ab45e1ecda69845a75d8d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com> Date: Tue, 13 Oct 2026 11:34:33 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E6=96=B0=E5=A2=9E=E9=87=91=E8=9D=B6?= =?UTF-8?q?=E5=88=86=E5=BD=95=E8=B4=B9=E7=94=A8=E9=A1=B9=E6=8C=89=E5=A4=A7?= =?UTF-8?q?=E7=B1=BB=E7=A8=8E=E7=8E=87=E6=8B=86=E5=88=86=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 覆盖同大类多税率拆行、运输+装卸拆行、费用项档案分类判定、残差勾稽、空费用项兜底、同组金额合并六个场景 --- .../transport/KingdeeEntrySplitTest.java | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 blade-service/blade-transport/src/test/java/org/springblade/transport/KingdeeEntrySplitTest.java diff --git a/blade-service/blade-transport/src/test/java/org/springblade/transport/KingdeeEntrySplitTest.java b/blade-service/blade-transport/src/test/java/org/springblade/transport/KingdeeEntrySplitTest.java new file mode 100644 index 00000000..1b34b596 --- /dev/null +++ b/blade-service/blade-transport/src/test/java/org/springblade/transport/KingdeeEntrySplitTest.java @@ -0,0 +1,139 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to the License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport; + +import org.junit.jupiter.api.Test; +import org.springblade.transport.support.KingdeeApBillSyncSupport; +import org.springblade.transport.support.KingdeeApBillSyncSupport.FeeLineSplit; + +import java.math.BigDecimal; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * 金蝶应付/应收单分录拆分逻辑测试(纯函数,无环境依赖): + * 结算明细费用项按 费用大类(运输/装卸)→ 税率 拆分行,验证三个联调场景与残差勾稽 + * + * @author Chill + */ +class KingdeeEntrySplitTest { + + /** 场景1:同费用大类(运输)、多税率 → 按税率拆两行 */ + @Test + void splitFreightByTaxRate() { + Map feeItems = new LinkedHashMap<>(); + feeItems.put("运输费", new BigDecimal("2000")); + feeItems.put("附加运输补贴", new BigDecimal("1120")); + Map taxRateByRule = Map.of( + "运输费", new BigDecimal("9"), + "附加运输补贴", new BigDecimal("6")); + List splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, Map.of(), taxRateByRule, new BigDecimal("3120")); + assertEquals(2, splits.size()); + assertFalse(splits.get(0).isLoading()); + assertEquals(new BigDecimal("9"), splits.get(0).getTaxRate()); + assertEquals(new BigDecimal("2000"), splits.get(0).getAmount()); + assertEquals("-9", splits.get(0).taxRateSuffix()); + assertFalse(splits.get(1).isLoading()); + assertEquals(new BigDecimal("6"), splits.get(1).getTaxRate()); + assertEquals(new BigDecimal("1120"), splits.get(1).getAmount()); + assertEquals("-6", splits.get(1).taxRateSuffix()); + } + + /** 场景2:运输费 + 装卸费 → 运输行 + 装卸行(装卸行税率独立) */ + @Test + void splitFreightAndLoading() { + Map feeItems = new LinkedHashMap<>(); + feeItems.put("运输费", new BigDecimal("3120")); + feeItems.put("装卸费", new BigDecimal("800")); + Map taxRateByRule = Map.of( + "运输费", new BigDecimal("9"), + "装卸费", new BigDecimal("6")); + List splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, Map.of(), taxRateByRule, new BigDecimal("3920")); + assertEquals(2, splits.size()); + assertFalse(splits.get(0).isLoading()); + assertEquals(new BigDecimal("3120"), splits.get(0).getAmount()); + assertTrue(splits.get(1).isLoading()); + assertEquals(new BigDecimal("6"), splits.get(1).getTaxRate()); + assertEquals(new BigDecimal("800"), splits.get(1).getAmount()); + } + + /** 费用项档案分类判定:名称不含“装卸”的费用项,档案费用类型名称含“装卸”即归装卸大类 */ + @Test + void loadingCategoryFromFeeItemArchive() { + Map feeItems = Map.of("吊装作业", new BigDecimal("500")); + Map feeCategoryByName = Map.of("吊装作业", "装卸"); + List splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, feeCategoryByName, Map.of(), new BigDecimal("500")); + assertEquals(1, splits.size()); + assertTrue(splits.get(0).isLoading()); + } + + /** 残差勾稽:费用项JSON未含运费(历史数据)时,结算金额与费用项合计的差额并入运输类无税率组 */ + @Test + void residualGoesToFreightDefaultGroup() { + Map feeItems = new LinkedHashMap<>(); + feeItems.put("运输费", new BigDecimal("2000")); + List splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, Map.of(), Map.of("运输费", new BigDecimal("9")), new BigDecimal("2020")); + assertEquals(2, splits.size()); + assertEquals(new BigDecimal("2000"), splits.get(0).getAmount()); + assertFalse(splits.get(1).isLoading()); + assertNull(splits.get(1).getTaxRate()); + assertEquals(new BigDecimal("20"), splits.get(1).getAmount()); + assertEquals("", splits.get(1).taxRateSuffix()); + } + + /** 费用项JSON为空:整行结算金额归运输类无税率组单行 */ + @Test + void emptyFeeItemsFallbackToFreightLine() { + List splits = KingdeeApBillSyncSupport.splitFeeItems(Map.of(), Map.of(), Map.of(), new BigDecimal("3120")); + assertEquals(1, splits.size()); + assertFalse(splits.get(0).isLoading()); + assertNull(splits.get(0).getTaxRate()); + assertEquals(new BigDecimal("3120"), splits.get(0).getAmount()); + } + + /** 税率未配置的费用项归入无税率组,同大类同税率费用项金额合并 */ + @Test + void mergeSameCategorySameRate() { + Map feeItems = new LinkedHashMap<>(); + feeItems.put("装卸费", new BigDecimal("500")); + feeItems.put("装卸吊装费", new BigDecimal("300")); + feeItems.put("其他费用", new BigDecimal("100")); + List splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, Map.of(), Map.of(), new BigDecimal("900")); + assertEquals(2, splits.size()); + assertTrue(splits.get(0).isLoading()); + assertEquals(new BigDecimal("800"), splits.get(0).getAmount()); + assertNull(splits.get(0).getTaxRate()); + assertEquals("装卸费", splits.get(0).getFirstFeeItem()); + assertFalse(splits.get(1).isLoading()); + assertEquals(new BigDecimal("100"), splits.get(1).getAmount()); + } +}