+111
@@ -185,4 +185,115 @@ class KingdeeEntrySplitTest {
|
||||
assertFalse(KingdeeApBillSyncSupport.isFreightCategory("A10", "人工装卸费用", Map.of()));
|
||||
assertTrue(KingdeeApBillSyncSupport.isFreightCategory("", "运输费", Map.of()));
|
||||
}
|
||||
|
||||
/** 仓储同税率合并:同货物行档案 A05 的仓储费 + 堆存费同税率合并一行 */
|
||||
@Test
|
||||
void mergeWarehouseSameTaxRate() {
|
||||
Map<String, BigDecimal> feeItems = new LinkedHashMap<>();
|
||||
feeItems.put("仓储费", new BigDecimal("300"));
|
||||
feeItems.put("堆存费", new BigDecimal("200"));
|
||||
Map<String, String> feeCategoryByName = Map.of(
|
||||
"仓储费", "A05",
|
||||
"堆存费", "A05");
|
||||
Map<String, BigDecimal> taxRateByRule = Map.of(
|
||||
"仓储费", new BigDecimal("6"),
|
||||
"堆存费", new BigDecimal("6"));
|
||||
List<FeeLineSplit> splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, feeCategoryByName, taxRateByRule,
|
||||
new BigDecimal("500"));
|
||||
assertEquals(1, splits.size());
|
||||
assertTrue(splits.get(0).isWarehouse());
|
||||
assertEquals(new BigDecimal("6"), splits.get(0).getTaxRate());
|
||||
assertEquals(new BigDecimal("500"), splits.get(0).getAmount());
|
||||
assertEquals("-6", splits.get(0).taxRateSuffix());
|
||||
}
|
||||
|
||||
/** 仓储不同税率拆行:同大类不同税率各生成一行 */
|
||||
@Test
|
||||
void splitWarehouseByTaxRate() {
|
||||
Map<String, BigDecimal> feeItems = new LinkedHashMap<>();
|
||||
feeItems.put("仓储费", new BigDecimal("300"));
|
||||
feeItems.put("保管费", new BigDecimal("200"));
|
||||
Map<String, String> feeCategoryByName = Map.of(
|
||||
"仓储费", "A05",
|
||||
"保管费", "A05");
|
||||
Map<String, BigDecimal> taxRateByRule = Map.of(
|
||||
"仓储费", new BigDecimal("6"),
|
||||
"保管费", new BigDecimal("9"));
|
||||
List<FeeLineSplit> splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, feeCategoryByName, taxRateByRule,
|
||||
new BigDecimal("500"));
|
||||
assertEquals(2, splits.size());
|
||||
assertTrue(splits.get(0).isWarehouse());
|
||||
assertEquals(new BigDecimal("6"), splits.get(0).getTaxRate());
|
||||
assertEquals(new BigDecimal("300"), splits.get(0).getAmount());
|
||||
assertEquals("-6", splits.get(0).taxRateSuffix());
|
||||
assertTrue(splits.get(1).isWarehouse());
|
||||
assertEquals(new BigDecimal("9"), splits.get(1).getTaxRate());
|
||||
assertEquals(new BigDecimal("200"), splits.get(1).getAmount());
|
||||
assertEquals("-9", splits.get(1).taxRateSuffix());
|
||||
}
|
||||
|
||||
/** 仓储不混入运输组:运输费与档案 A05 仓储费按大类拆开 */
|
||||
@Test
|
||||
void warehouseNotMergedIntoFreight() {
|
||||
Map<String, BigDecimal> feeItems = new LinkedHashMap<>();
|
||||
feeItems.put("运输费", new BigDecimal("1000"));
|
||||
feeItems.put("仓储费", new BigDecimal("500"));
|
||||
Map<String, String> feeCategoryByName = Map.of("仓储费", "A05");
|
||||
Map<String, BigDecimal> taxRateByRule = Map.of(
|
||||
"运输费", new BigDecimal("9"),
|
||||
"仓储费", new BigDecimal("6"));
|
||||
List<FeeLineSplit> splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, feeCategoryByName, taxRateByRule,
|
||||
new BigDecimal("1500"));
|
||||
assertEquals(2, splits.size());
|
||||
assertFalse(splits.get(0).isWarehouse());
|
||||
assertFalse(splits.get(0).isLoading());
|
||||
assertEquals(new BigDecimal("1000"), splits.get(0).getAmount());
|
||||
assertTrue(splits.get(1).isWarehouse());
|
||||
assertEquals(new BigDecimal("500"), splits.get(1).getAmount());
|
||||
}
|
||||
|
||||
/** 档案未配 A05 不做名称关键字兜底:「仓储服务费」档案 A02 仍归运输组 */
|
||||
@Test
|
||||
void warehouseWithoutArchiveCodeStaysFreight() {
|
||||
Map<String, BigDecimal> feeItems = Map.of("仓储服务费", new BigDecimal("500"));
|
||||
List<FeeLineSplit> splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems,
|
||||
Map.of("仓储服务费", "A02"), Map.of(), new BigDecimal("500"));
|
||||
assertEquals(1, splits.size());
|
||||
assertFalse(splits.get(0).isWarehouse());
|
||||
assertFalse(splits.get(0).isLoading());
|
||||
assertEquals(new BigDecimal("500"), splits.get(0).getAmount());
|
||||
}
|
||||
|
||||
/** 残差勾稽不变:含仓储费时残差仍并入运输无税率组 */
|
||||
@Test
|
||||
void residualStillGoesToFreightWhenWarehousePresent() {
|
||||
Map<String, BigDecimal> feeItems = new LinkedHashMap<>();
|
||||
feeItems.put("运输费", new BigDecimal("2000"));
|
||||
feeItems.put("仓储费", new BigDecimal("500"));
|
||||
Map<String, String> feeCategoryByName = Map.of("仓储费", "A05");
|
||||
List<FeeLineSplit> splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, feeCategoryByName,
|
||||
Map.of("运输费", new BigDecimal("9")), new BigDecimal("2520"));
|
||||
assertEquals(3, splits.size());
|
||||
assertEquals(new BigDecimal("2000"), splits.get(0).getAmount());
|
||||
assertTrue(splits.get(1).isWarehouse());
|
||||
assertEquals(new BigDecimal("500"), splits.get(1).getAmount());
|
||||
assertFalse(splits.get(2).isWarehouse());
|
||||
assertFalse(splits.get(2).isLoading());
|
||||
assertNull(splits.get(2).getTaxRate());
|
||||
assertEquals(new BigDecimal("20"), splits.get(2).getAmount());
|
||||
}
|
||||
|
||||
/** 手工合计行仓储判定:档案 A05 或费用类型编码 A05 归仓储物料 */
|
||||
@Test
|
||||
void warehouseCategoryMatchesArchiveOrFeeType() {
|
||||
Map<String, String> feeCategoryByName = Map.of("仓储堆存保管费", "A05");
|
||||
assertTrue(KingdeeApBillSyncSupport.isWarehouseCategory("A05", "仓储堆存保管费", feeCategoryByName));
|
||||
assertFalse(KingdeeApBillSyncSupport.isWarehouseCategory("A05", "人工装卸费用",
|
||||
Map.of("人工装卸费用", "A10")));
|
||||
// 档案未维护:回退行费用类型编码 A05
|
||||
assertTrue(KingdeeApBillSyncSupport.isWarehouseCategory("A05", "临时仓储杂费", Map.of()));
|
||||
assertFalse(KingdeeApBillSyncSupport.isWarehouseCategory("A10", "临时仓储杂费", Map.of()));
|
||||
// 无名称关键字兜底:名称含仓储但档案/费用类型均非 A05 不归仓储
|
||||
assertFalse(KingdeeApBillSyncSupport.isWarehouseCategory("A02", "仓储服务费", Map.of()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
-- 金蝶分录仓储大类(A102-2/A302-2/A103-1 分录拆分按费用项档案分类编码判定仓储大类,无名称关键字兜底)。
|
||||
-- ① 业务字典 fee_category 新增子项 A05 仓储;② 费用项档案仓储类费用项归入 A05(分类生效前提)。
|
||||
-- id 由 UUID_SHORT() 动态生成,幂等可重复执行。
|
||||
-- 排序规则:utf8mb4_general_ci(与业务表一致)
|
||||
|
||||
-- ① 业务字典 fee_category 新增子项:A05 仓储
|
||||
INSERT INTO blade_dict_biz (id, tenant_id, parent_id, code, dict_key, dict_value, sort, remark, is_sealed, status, is_deleted)
|
||||
SELECT UUID_SHORT(), '000000',
|
||||
(SELECT id FROM blade_dict_biz WHERE code = 'fee_category' AND dict_key = '-1' AND tenant_id = '000000' AND is_deleted = 0 LIMIT 1),
|
||||
'fee_category', 'A05', '仓储', 1, '金蝶分录仓储大类', 0, 1, 0
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM blade_dict_biz
|
||||
WHERE code = 'fee_category' AND dict_key = 'A05' AND tenant_id = '000000' AND is_deleted = 0
|
||||
);
|
||||
|
||||
-- ② 费用项档案:仓储类费用项归入 A05(已执行则更新 0 行,幂等)
|
||||
-- 执行前请先核对命中清单,避免把名称含「保管」但非仓储的费用项误归仓:
|
||||
-- SELECT id, name, fee_category FROM blade_fee_item
|
||||
-- WHERE is_deleted = 0 AND fee_category <> 'A05'
|
||||
-- AND (name LIKE '%仓储%' OR name LIKE '%堆存%' OR name LIKE '%保管%');
|
||||
UPDATE blade_fee_item
|
||||
SET fee_category = 'A05'
|
||||
WHERE is_deleted = 0
|
||||
AND fee_category <> 'A05'
|
||||
AND (name LIKE '%仓储%' OR name LIKE '%堆存%' OR name LIKE '%保管%');
|
||||
Reference in New Issue
Block a user