fix: 金蝶分录拆分跳过0元费用项避免生成0元明细行

fee_items_json 中金额为0的费用项(附加运输补贴/仓储服务费等)不再参与分组,0元货物行整体跳过;修复FJS2026101300005推送8条分录(其中5条为0元行)的问题,修复后该单应为3条有效分录
This commit is contained in:
刘泉佳
2026-10-13 15:02:26 +08:00
parent 52da9aab24
commit 975ff75eb3
2 changed files with 37 additions and 1 deletions
@@ -463,7 +463,9 @@ public class KingdeeApBillSyncSupport {
List<FeeLineSplit> splits = splitFeeItems(parseFeeItems(feeItemsJson), context.feeCategoryByName(),
context.taxRateByRule(), rowAmount);
if (splits.isEmpty()) {
throw new ServiceException("推送金蝶失败:" + sourceDesc + "无费用项金额,无法拆分明细分录");
// 0元货物行(费用项与结算金额均为0)跳过不生成0元分录
log.info("金蝶应付单分录生成:来源[{}],费用项与结算金额均为0,跳过该货物行", sourceDesc);
return;
}
// 运输类数量:取运单运输量(未维护兜底 1)
BigDecimal freightQuantity = transportQuantity != null && transportQuantity.compareTo(BigDecimal.ZERO) > 0
@@ -656,6 +658,10 @@ public class KingdeeApBillSyncSupport {
continue;
}
BigDecimal amount = item.getValue() == null ? BigDecimal.ZERO : item.getValue();
// 0元费用项跳过,不生成0元分录(金额缺失由运输类无税率组残差兜底)
if (amount.signum() == 0) {
continue;
}
boolean loading = isLoadingCategory(item.getKey(), feeCategoryByName);
BigDecimal taxRate = taxRateByRule == null ? null : taxRateByRule.get(item.getKey());
FeeLineSplit split = grouped.get(splitGroupKey(loading, taxRate));
@@ -136,4 +136,34 @@ class KingdeeEntrySplitTest {
assertFalse(splits.get(1).isLoading());
assertEquals(new BigDecimal("100"), splits.get(1).getAmount());
}
/** 0元费用项跳过:不生成0元分录(FJS2026101300005 结算单8条分录问题的回归用例) */
@Test
void zeroAmountFeeItemsSkipped() {
Map<String, BigDecimal> feeItems = new LinkedHashMap<>();
feeItems.put("运输费", new BigDecimal("3120"));
feeItems.put("附加运输补贴", BigDecimal.ZERO);
feeItems.put("装卸费", new BigDecimal("800"));
feeItems.put("仓储服务费", BigDecimal.ZERO);
Map<String, BigDecimal> taxRateByRule = Map.of(
"运输费", new BigDecimal("9"),
"附加运输补贴", new BigDecimal("6"),
"装卸费", new BigDecimal("6"));
List<FeeLineSplit> 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("800"), splits.get(1).getAmount());
}
/** 全部费用项为0且结算金额为0:拆分结果为空(调用方跳过该0元货物行) */
@Test
void allZeroFeeItemsYieldEmptySplits() {
Map<String, BigDecimal> feeItems = new LinkedHashMap<>();
feeItems.put("运输费", BigDecimal.ZERO);
feeItems.put("装卸费", BigDecimal.ZERO);
List<FeeLineSplit> splits = KingdeeApBillSyncSupport.splitFeeItems(feeItems, Map.of(), Map.of(), BigDecimal.ZERO);
assertTrue(splits.isEmpty());
}
}