From 75f33803221c63a93668661d19358eb902911f64 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Wed, 4 Nov 2026 16:00:23 +0800
Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=E4=BB=98=E6=AC=BE=E8=AE=B0?=
=?UTF-8?q?=E5=BD=95=E8=90=BD=E5=BA=93=E9=87=91=E8=9D=B6=E4=BB=98=E6=AC=BE?=
=?UTF-8?q?=E5=A4=84=E7=90=86=E5=8D=95=E5=86=85=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../pojo/entity/PaymentApplicationRecord.java | 2 ++
.../impl/PaymentApplicationServiceImpl.java | 2 ++
...cation_record_kingdee_bill_id_20261104.sql | 21 +++++++++++++++++++
3 files changed, 25 insertions(+)
create mode 100644 doc/sql/transport/lqj/temp/23_blade_payment_application_record_kingdee_bill_id_20261104.sql
diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationRecord.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationRecord.java
index 1c5c1afe..9d97e3d9 100644
--- a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationRecord.java
+++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationRecord.java
@@ -40,4 +40,6 @@ public class PaymentApplicationRecord extends TenantEntity {
private String paymentNo;
private String voucherJson;
private String kingdeeBillNo;
+ /** 金蝶付款处理单id(cas_paybill.id,A103-4 回写,应付单 preentry 预付抵扣取数用) */
+ private String kingdeeBillId;
}
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java
index e9d56acf..5fc32654 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java
@@ -1146,6 +1146,8 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl
Date: Wed, 4 Nov 2026 16:00:28 +0800
Subject: [PATCH 02/11] =?UTF-8?q?feat:=20=E8=B4=A2=E5=8A=A1=E5=BA=94?=
=?UTF-8?q?=E4=BB=98=E5=8D=95=E6=8E=A8=E9=80=81=E6=90=BA=E5=B8=A6=E9=A2=84?=
=?UTF-8?q?=E4=BB=98=E4=BF=A1=E6=81=AF=E5=88=86=E5=BD=95=E5=B9=B6=E6=8B=A6?=
=?UTF-8?q?=E6=88=AA=E6=9C=AA=E5=9B=9E=E5=86=99=E9=A2=84=E4=BB=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../support/KingdeeApBillSyncSupport.java | 166 +++++++++++++++++-
1 file changed, 163 insertions(+), 3 deletions(-)
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
index 12a1060f..21be0c4f 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
@@ -39,26 +39,39 @@ import org.springblade.system.pojo.entity.FeeItem;
import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillQueryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillSaveDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillSaveEntryDTO;
+import org.springblade.thirdparty.bfi.pojo.dto.BfiApBillSavePreEntryDTO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiApBillVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultItemVO;
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultVO;
import org.springblade.thirdparty.bfi.service.IBfiService;
import org.springblade.thirdparty.bfi.util.BfiUtil;
+import org.springblade.thirdparty.bfi.constant.BfiConstant;
import org.springblade.transport.config.BfiProperties;
import org.springblade.transport.constant.KingdeeBfiConstant;
+import org.springblade.transport.constant.TransportBusiConstant;
import org.springblade.transport.mapper.ContractManageMapper;
import org.springblade.transport.mapper.CustomerArchiveMapper;
import org.springblade.transport.mapper.FormalSettlementDetailFeeMapper;
import org.springblade.transport.mapper.FormalSettlementMapper;
+import org.springblade.transport.mapper.FormalSettlementSourceMapper;
import org.springblade.transport.mapper.FormalSettlementSummaryFeeMapper;
+import org.springblade.transport.mapper.PaymentApplicationMapper;
+import org.springblade.transport.mapper.PaymentApplicationRecordMapper;
+import org.springblade.transport.mapper.PreSettlementAdvanceMapper;
import org.springblade.transport.mapper.ProjectApplyMapper;
+import org.springblade.transport.mapper.SettlementProjectAdvanceWriteOffMapper;
import org.springblade.transport.pojo.entity.ContractManage;
import org.springblade.transport.pojo.entity.CustomerArchive;
import org.springblade.transport.pojo.entity.FormalSettlement;
import org.springblade.transport.pojo.entity.FormalSettlementDetail;
import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
+import org.springblade.transport.pojo.entity.FormalSettlementSource;
import org.springblade.transport.pojo.entity.FormalSettlementSummaryFee;
+import org.springblade.transport.pojo.entity.PaymentApplication;
+import org.springblade.transport.pojo.entity.PaymentApplicationRecord;
+import org.springblade.transport.pojo.entity.PreSettlementAdvance;
import org.springblade.transport.pojo.entity.ProjectApply;
+import org.springblade.transport.pojo.entity.SettlementProjectAdvanceWriteOff;
import org.springblade.transport.service.KingdeeSyncContext;
import org.springframework.stereotype.Component;
@@ -73,6 +86,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -100,6 +114,8 @@ public class KingdeeApBillSyncSupport {
private static final int PAY_RESULT_PAGE_SIZE = 200;
/** 结算明细行(运费)计费方案匹配费用项(运输类无税率残差组标识用) */
private static final String FREIGHT_FEE_ITEM = "运输费";
+ /** 预付抵扣拦截提示最多列出的预付单笔数(超出部分汇总"等N笔",kingdee_fail_reason 列长 500 截断兜底) */
+ private static final int PREPAY_BLOCK_REASON_LIMIT = 3;
/** 费用大类编码(业务字典 fee_category 键值):运输 */
public static final String FEE_CATEGORY_FREIGHT = "A01";
/** 费用大类编码(业务字典 fee_category 键值):装卸 */
@@ -138,7 +154,12 @@ public class KingdeeApBillSyncSupport {
private final FormalSettlementDetailFeeMapper formalSettlementDetailFeeMapper;
private final FormalSettlementSummaryFeeMapper formalSettlementSummaryFeeMapper;
private final FormalSettlementMapper formalSettlementMapper;
+ private final FormalSettlementSourceMapper formalSettlementSourceMapper;
+ private final PaymentApplicationMapper paymentApplicationMapper;
+ private final PaymentApplicationRecordMapper paymentApplicationRecordMapper;
+ private final PreSettlementAdvanceMapper preSettlementAdvanceMapper;
private final ProjectApplyMapper projectApplyMapper;
+ private final SettlementProjectAdvanceWriteOffMapper projectAdvanceWriteOffMapper;
private final ISysClient sysClient;
private final BfiProperties bfiProperties;
@@ -381,11 +402,16 @@ public class KingdeeApBillSyncSupport {
// 付款计划 planentity 暂不传(联调待确认后启用):启用后送正式结算单下绑定、单据状态为审核通过(approved)
// 的付款信息,每条付款信息一行,awrp_entry_code_p 取付款单号(A103-1 下推 awrp_finapbill_entryid 勾稽此值);
// 当前不传由金蝶按明细自动汇总生成,A103-1 推送前经 A102-4 反查金蝶生成的 awrp_entry_code_p
- // TODO 待业务确认:存在预付款抵扣时是否需传预付信息 preentry(y_billtype/y_billid/y_settleamt),本期不传、后续迭代
+ // 预付信息分录 preentry:存在预付款抵扣(进度预付/项目预付核销)时按金蝶付款处理单逐笔送出,
+ // 任一笔无法定位金蝶付款处理单内码(未付款/内码未回写/实付不足)时拦截推送(见 resolvePreEntries)
+ List preEntries = this.resolvePreEntries(settlement);
+ if (!preEntries.isEmpty()) {
+ param.setPreentry(preEntries);
+ }
// 推送入参摘要(联调排查:防重键、分录条数、页面维护的汇率口径)
- log.info("推送金蝶财务应付单:正式结算单[{}],防重键[{}],明细分录{}条,汇率日期[{}],汇率[{}]",
- subject, apBillSrcCode, detailentry.size(), param.getExratedate(), param.getExchangerate());
+ log.info("推送金蝶财务应付单:正式结算单[{}],防重键[{}],明细分录{}条,预付信息{}条,汇率日期[{}],汇率[{}]",
+ subject, apBillSrcCode, detailentry.size(), preEntries.size(), param.getExratedate(), param.getExchangerate());
BfiBillSaveResultVO saveResult = bfiService.saveApBill(param);
// 应付单id不落库,后续如需可经 A102-4 按防重键(awrp_src_sys + awrp_src_code)查询
@@ -397,6 +423,140 @@ public class KingdeeApBillSyncSupport {
return new BfiApBillPushOutcome(savedItem.getNumber(), savedItem.getId() == null ? null : String.valueOf(savedItem.getId()), false);
}
+ // ==================== 预付信息分录(A102-2 preentry,预付抵扣) ====================
+
+ /**
+ * 解析正式结算单预付信息分录(A102-2 preentry):每条对应一张金蝶付款处理单(cas_paybill),
+ * 项目预付取核销行核销金额、进度预付取预付记录已付金额,按付款处理单实付占比分摊后同 y_billid 合并求和。
+ * 任一笔应抵扣预付无法定位金蝶付款处理单(付款申请不存在/未付款/内码未回写/实付不足)时抛异常拦截应付单推送,
+ * 失败落 kingdee_fail_reason,付款结果回写后由重推任务自动续推
+ *
+ * @param settlement 正式结算单(应付)
+ * @return 预付信息分录列表(按 y_billid 合并后),无预付抵扣返回空列表
+ */
+ private List resolvePreEntries(FormalSettlement settlement) {
+ // 应抵扣需求按底层付款申请归集:付款申请id -> (本次抵扣金额, 来源描述)
+ Map demandAmounts = new LinkedHashMap<>();
+ Map demandSources = new LinkedHashMap<>();
+ // 项目预付:核销行核销金额即本次抵扣金额(核销保存校验已要求预付金蝶已付款)
+ List writeOffs = this.projectAdvanceWriteOffMapper.selectList(
+ Wrappers.lambdaQuery()
+ .eq(SettlementProjectAdvanceWriteOff::getSettlementType, TransportBusiConstant.SETTLEMENT_BILL_FORMAL)
+ .eq(SettlementProjectAdvanceWriteOff::getSettlementId, settlement.getId())
+ .eq(SettlementProjectAdvanceWriteOff::getIsDeleted, 0));
+ for (SettlementProjectAdvanceWriteOff writeOff : writeOffs) {
+ if (writeOff.getPaymentApplicationId() == null || this.money(writeOff.getWriteOffAmount()).signum() <= 0) {
+ continue;
+ }
+ demandAmounts.merge(writeOff.getPaymentApplicationId(), this.money(writeOff.getWriteOffAmount()), BigDecimal::add);
+ demandSources.putIfAbsent(writeOff.getPaymentApplicationId(), "项目预付[" + Func.toStr(writeOff.getPaymentNo()) + "]");
+ }
+ // 进度预付:来源预结算的预付记录已付金额即本次抵扣金额(syncOnePreSettlementAdvance 已按预结算关联行分摊)
+ List sources = this.formalSettlementSourceMapper.selectList(
+ Wrappers.lambdaQuery()
+ .eq(FormalSettlementSource::getFormalSettlementId, settlement.getId())
+ .eq(FormalSettlementSource::getIsDeleted, 0));
+ List preSettlementIds = sources.stream().map(FormalSettlementSource::getPreSettlementId)
+ .filter(Objects::nonNull).distinct().toList();
+ if (!preSettlementIds.isEmpty()) {
+ List advances = this.preSettlementAdvanceMapper.selectList(
+ Wrappers.lambdaQuery()
+ .in(PreSettlementAdvance::getPreSettlementId, preSettlementIds)
+ .eq(PreSettlementAdvance::getIsDeleted, 0)
+ .ne(PreSettlementAdvance::getBillStatus, TransportBusiConstant.VOIDED));
+ // 预付记录 advanceNo 即付款申请单号,按单号批量定位底层付款申请(避免循环内逐单查询)
+ List advanceNos = advances.stream().map(PreSettlementAdvance::getAdvanceNo)
+ .filter(Func::isNotBlank).distinct().toList();
+ Map applicationsByNo = advanceNos.isEmpty() ? Map.of()
+ : this.paymentApplicationMapper.selectList(Wrappers.lambdaQuery()
+ .in(PaymentApplication::getPaymentNo, advanceNos)
+ .eq(PaymentApplication::getIsDeleted, 0))
+ .stream().collect(Collectors.toMap(PaymentApplication::getPaymentNo, Function.identity(),
+ (first, second) -> first));
+ for (PreSettlementAdvance advance : advances) {
+ if (this.money(advance.getPaidAmount()).signum() <= 0) {
+ continue;
+ }
+ PaymentApplication application = applicationsByNo.get(advance.getAdvanceNo());
+ if (application == null) {
+ throw new ServiceException("推送金蝶财务应付单失败:预付单[" + Func.toStr(advance.getAdvanceNo())
+ + "]不存在付款申请,无法解析预付信息");
+ }
+ demandAmounts.merge(application.getId(), this.money(advance.getPaidAmount()), BigDecimal::add);
+ demandSources.putIfAbsent(application.getId(), "进度预付[" + Func.toStr(advance.getAdvanceNo()) + "]");
+ }
+ }
+ if (demandAmounts.isEmpty()) {
+ return List.of();
+ }
+ // 批量取付款申请与付款处理记录(仅保留带回金蝶付款处理单内码的记录),逐笔校验并分摊
+ Map applications = this.paymentApplicationMapper.selectBatchIds(demandAmounts.keySet()).stream()
+ .collect(Collectors.toMap(PaymentApplication::getId, Function.identity(), (first, second) -> first));
+ Map> recordsByApplicationId = this.paymentApplicationRecordMapper.selectList(
+ Wrappers.lambdaQuery()
+ .in(PaymentApplicationRecord::getPaymentApplicationId, demandAmounts.keySet())
+ .eq(PaymentApplicationRecord::getIsDeleted, 0))
+ .stream().filter(record -> Func.isNotBlank(record.getKingdeeBillId()))
+ .collect(Collectors.groupingBy(PaymentApplicationRecord::getPaymentApplicationId));
+ Map settleAmountsByBillId = new LinkedHashMap<>();
+ Map sourcesByBillId = new LinkedHashMap<>();
+ List blockReasons = new ArrayList<>();
+ demandAmounts.forEach((applicationId, demandAmount) -> {
+ String source = demandSources.get(applicationId);
+ PaymentApplication application = applications.get(applicationId);
+ if (application == null) {
+ blockReasons.add(source + "不存在付款申请");
+ return;
+ }
+ List records = recordsByApplicationId.getOrDefault(applicationId, List.of());
+ if (records.isEmpty()) {
+ blockReasons.add(source + (KingdeeBfiConstant.KINGDEE_STATUS_PAID.equals(application.getKingdeeStatus())
+ ? "金蝶付款处理单内码未回写,请先在付款管理执行[同步付款结果]后再推送应付单"
+ : "尚未付款完成,预付须金蝶付款完成后方可抵扣"));
+ return;
+ }
+ BigDecimal recordTotal = records.stream().map(record -> this.money(record.getPaidAmount()))
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ if (recordTotal.compareTo(demandAmount) < 0) {
+ blockReasons.add(source + "付款处理单实付金额不足");
+ return;
+ }
+ // 按付款处理单实付占比分摊(末条取剩余补差保证合计精确),同 y_billid 合并求和
+ BigDecimal remaining = demandAmount;
+ for (int index = 0; index < records.size(); index++) {
+ PaymentApplicationRecord record = records.get(index);
+ BigDecimal settleAmount = index == records.size() - 1 ? remaining
+ : demandAmount.multiply(this.money(record.getPaidAmount()))
+ .divide(recordTotal, 2, RoundingMode.HALF_UP)
+ .min(remaining);
+ settleAmount = settleAmount.setScale(2, RoundingMode.HALF_UP);
+ if (settleAmount.signum() <= 0) {
+ continue;
+ }
+ remaining = remaining.subtract(settleAmount);
+ settleAmountsByBillId.merge(record.getKingdeeBillId(), settleAmount, BigDecimal::add);
+ sourcesByBillId.putIfAbsent(record.getKingdeeBillId(), source);
+ }
+ });
+ if (!blockReasons.isEmpty()) {
+ String summary = blockReasons.size() > PREPAY_BLOCK_REASON_LIMIT
+ ? String.join(";", blockReasons.subList(0, PREPAY_BLOCK_REASON_LIMIT)) + ";等" + blockReasons.size() + "笔预付无法抵扣"
+ : String.join(";", blockReasons);
+ throw new ServiceException("推送金蝶财务应付单失败:" + summary);
+ }
+ List preEntries = new ArrayList<>();
+ settleAmountsByBillId.forEach((billId, settleAmount) -> {
+ BfiApBillSavePreEntryDTO preEntry = new BfiApBillSavePreEntryDTO();
+ preEntry.setYBilltype(BfiConstant.PREPAY_BILL_TYPE_PAY_BILL);
+ preEntry.setYBillid(billId);
+ preEntry.setYSettleamt(settleAmount);
+ preEntries.add(preEntry);
+ log.info("应付单预付信息分录: 正式结算单[{}], 来源[{}], y_billid={}, y_settleamt={}",
+ settlement.getFormalSettlementNo(), sourcesByBillId.get(billId), billId, settleAmount);
+ });
+ return preEntries;
+ }
+
// ==================== 结算明细分录解析(结算明细行 + 结算合计费用项) ====================
/**
From 01cc9f7f37c9a71a13f93be7ab9eeceee95cdd7f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Wed, 4 Nov 2026 16:01:06 +0800
Subject: [PATCH 03/11] =?UTF-8?q?docs:=20=E6=96=B0=E5=A2=9E=E8=B4=A2?=
=?UTF-8?q?=E5=8A=A1=E5=BA=94=E4=BB=98=E5=8D=95preentry=E9=A2=84=E4=BB=98?=
=?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=8E=A8=E9=80=81=E9=87=91=E8=9D=B6=E8=AE=BE?=
=?UTF-8?q?=E8=AE=A1=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...金蝶设计(A102-2预付抵扣-y_billid落库-拦截规则与分摊).md | 195 ++++++++++++++++++
1 file changed, 195 insertions(+)
create mode 100644 doc/docs/业务流程/2026-11-04-财务应付单preentry预付信息推送金蝶设计(A102-2预付抵扣-y_billid落库-拦截规则与分摊).md
diff --git a/doc/docs/业务流程/2026-11-04-财务应付单preentry预付信息推送金蝶设计(A102-2预付抵扣-y_billid落库-拦截规则与分摊).md b/doc/docs/业务流程/2026-11-04-财务应付单preentry预付信息推送金蝶设计(A102-2预付抵扣-y_billid落库-拦截规则与分摊).md
new file mode 100644
index 00000000..8783f30b
--- /dev/null
+++ b/doc/docs/业务流程/2026-11-04-财务应付单preentry预付信息推送金蝶设计(A102-2预付抵扣-y_billid落库-拦截规则与分摊).md
@@ -0,0 +1,195 @@
+# 财务应付单预付信息 preentry 推送金蝶设计
+
+> 范围:正式结算单「同步金蝶」推送财务应付单(A102-2)时,携带预付信息 `preentry`(`y_billtype / y_billid / y_settleamt`)的取数口径、每笔计算规则、拦截规则与落地改动。
+> 背景:`KingdeeApBillSyncSupport.pushApBill` 现有 TODO"存在预付款抵扣时是否需传预付信息 preentry,本期不传、后续迭代",本文为该迭代的实现设计。
+> 关联文档:`2026-10-18-预付完整流程梳理(进度预付-项目预付-正式结算单-付款-金蝶回写).md`、`2026-09-16-付款管理正式付款同步金蝶(财务应付单+付款申请下推)技术文档.md`、`2026-09-17-付款管理金蝶付款结果定时回写(A103-2付款申请单查询+A103-4付款处理查询)技术文档.md`。
+> 设计日期:2026-11-04。
+
+---
+
+## 一、字段语义与结论
+
+`preentry` 是 A102-2 财务应付单的预付信息分录,**支持多条**,用于登记本张应付单抵扣了哪些已付款的预付单。每条 `preentry` 对应**一张金蝶付款处理单(`cas_paybill`)**:
+
+```json
+"preentry": [
+ { "y_billtype": "cas_paybill", "y_billid": "付款处理单1 id", "y_settleamt": 10000.00 },
+ { "y_billtype": "cas_paybill", "y_billid": "付款处理单2 id", "y_settleamt": 5000.00 }
+]
+```
+
+### 字段取值
+
+| 字段 | 必填 | 取值 | 说明 |
+| --- | --- | --- | --- |
+| `y_billtype` | 是 | 固定 `cas_paybill`(`BfiConstant.PREPAY_BILL_TYPE_PAY_BILL`) | TMS 预付均经 A103-3 付款申请 → 金蝶付款处理,不产生期初预付单(`ap_paidbill` 不使用) |
+| `y_billid` | 是 | 金蝶**付款处理单** `id`(A103-4 `BfiPayBillVO.id`) | **不能**用 `blade_payment_application.kingdee_bill_id`(那是 A103-2 返回的付款申请单 id,类型不对) |
+| `y_settleamt` | 否 | 本次应付单实际抵扣该预付的金额,2 位小数 | 进度预付取 `PreSettlementAdvance.paid_amount`,项目预付取核销行 `write_off_amount` |
+
+### 两个易混淆字段(不在本次改造范围)
+
+| 字段 | 取值 | 现状 |
+| --- | --- | --- |
+| `awrp_src_type`(A102-2 应付单头) | `TMS财务应付单` | `KingdeeBfiConstant.BFI_AP_BILL_SRC_TYPE`,保持不变,**不要**改成 `0KzXs` |
+| `awrp_src_type`(A103-1/A103-3 付款申请头/分录) | 固定 `0KzXs` | Nacos `thirdParty.bfi.payApply.srcType` 配置,已是正确值,无需改 |
+
+---
+
+## 二、现状核查
+
+### 1. preentry 目前未送
+
+`KingdeeApBillSyncSupport.pushApBill`(A102-2 保存)明细分录之后保留 TODO,`setPreentry` 全项目无调用;DTO `BfiApBillSavePreEntryDTO`(`y_billtype / y_billid / y_settleamt`)已就绪,`@JsonInclude(NON_NULL)`——**为空时保持 `null`,不要设置空数组**(避免报文送 `preentry: []`)。
+
+### 2. y_billid 需要的内码未落库
+
+| 数据 | 实际值 | 可否作 `y_billid` |
+| --- | --- | --- |
+| `blade_payment_application.kingdee_bill_id` | A103-2 返回的付款申请单 id(`ap_payapply`) | ❌ 类型不对 |
+| `blade_payment_application_record.kingdee_bill_no` | A103-4 返回的付款处理单号(`cas_paybill.billno`) | ❌ 只有单号 |
+| `blade_payment_application_record.voucher_json` | A103-4 付款处理单整单 JSON,含 `id` | ⚠️ 仅 JSON 内有,无独立字段 |
+| `blade_pre_settlement_advance.kingdee_advance_no` | 付款申请单号 | ❌ |
+| `blade_settlement_project_advance_write_off.kingdee_bill_no` | 付款申请单号 | ❌ |
+
+**结论:必须先补存 `cas_paybill.id`**,否则 preentry 无值可送。
+
+---
+
+## 三、每笔 preentry 的计算规则
+
+### 粒度与合并
+
+- 一条 `preentry` = 一张金蝶付款处理单(按 `y_billid` 唯一)。
+- 同一 `y_billid` 被多行业务数据引用(如一张付款申请跨多个预结算分摊后落到同一张付款处理单)时,**按 `y_billid` 汇总金额只出一条**,避免向金蝶送重复键。
+
+### 项目预付
+
+数据源 `blade_settlement_project_advance_write_off`(本身就是"本结算单核销了某张项目预付多少"):
+
+```
+遍历核销行(settlement_type='formal' AND settlement_id=本单id)
+ → payment_application_id → 付款申请
+ → 付款处理记录(blade_payment_application_record,kingdee_bill_id 非空)
+ → 应抵扣金额 = write_off_amount,按付款处理单实付分摊
+ → 每条记录生成一条 preentry
+```
+
+### 进度预付
+
+数据源 `blade_formal_settlement_source` + `blade_pre_settlement_advance`(`syncOnePreSettlementAdvance` 已把付款申请按预结算关联行拆分,`paid_amount` 即本预结算分摊额):
+
+```
+遍历正式结算来源(formal_settlement_id=本单id)
+ → pre_settlement_id
+ → 预付记录(pre_settlement_id= ? AND paid_amount>0 AND is_deleted=0)
+ → advance_no(=付款申请单号)→ 付款申请
+ → 付款处理记录(kingdee_bill_id 非空)
+ → 应抵扣金额 = advance.paid_amount,按付款处理单实付分摊
+ → 每条记录生成一条 preentry
+```
+
+### 多付款处理单分摊(部分付款兜底)
+
+一张付款申请可能对应多张付款处理单(A103-4 多条回写):
+
+1. 按各记录 `paid_amount` 占比分摊应抵扣金额;
+2. 金额 `setScale(2, HALF_UP)`;
+3. 最后一条取"总额 − 已分摊"补差,保证合计不差分;
+4. 单条 `y_settleamt` 不超过该记录 `paid_amount`;
+5. 应抵扣金额超过付款处理单实付合计时封顶为实付合计(正常业务不会出现,防御性处理)。
+
+---
+
+## 四、拦截规则(已确认:拦截应付单推送)
+
+拦截点在 **A102-4 幂等预检(确认金蝶无本单应付单)之后、`saveApBill` 之前**;预检命中"已存在"直接幂等返回,不做校验(已推单据无法补 preentry)。
+
+任一笔应抵扣预付不满足以下条件即抛 `ServiceException`,整张应付单不推:
+
+| # | 校验 | 不满足提示 |
+| --- | --- | --- |
+| 1 | 底层付款申请存在 | 预付单[XXX]不存在付款申请 |
+| 2 | 付款申请已付款(`kingdee_status='paid'` / 已有付款处理记录) | 预付单[XXX]尚未付款完成,预付须金蝶付款完成后方可抵扣 |
+| 3 | `kingdee_bill_id` 非空(至少一条付款处理记录带回内码) | 预付单[XXX]金蝶付款处理单内码未回写,请先在付款管理执行【同步付款结果】后再推送应付单 |
+| 4 | 付款处理单实付合计 ≥ 本次抵扣金额 | 预付单[XXX]付款处理单实付金额不足 |
+
+提示信息**汇总所有不满足的预付单**,最多列 3 笔 + "等 N 笔",控制在 `kingdee_fail_reason` 的 500 字符内。
+
+失败后的自动流转(复用现有机制,无需新增代码):
+
+```
+doSyncKingdee 抛 ServiceException
+ → syncKingdee 捕获 → markKingdeeSyncFailed(failed + 失败原因留档)
+ → retryKingdeeFailed 定时重推
+ → A103-4 回写 kingdee_bill_id 后,下一轮重推自动成功
+```
+
+---
+
+## 五、落地改动清单
+
+### 1. 数据表与实体
+
+- `blade_payment_application_record` 增加 `kingdee_bill_id varchar(64) DEFAULT NULL COMMENT '金蝶付款处理单id(cas_paybill.id,A103-4回写)'`;
+- `PaymentApplicationRecord` 增加 `kingdeeBillId` 字段;
+- SQL 放 `doc/sql/transport/lqj/temp/`,**可重复执行**,含存量回填:
+
+```sql
+ALTER TABLE `blade_payment_application_record`
+ ADD COLUMN `kingdee_bill_id` varchar(64) DEFAULT NULL COMMENT '金蝶付款处理单id(cas_paybill.id,A103-4回写)' AFTER `kingdee_bill_no`;
+
+UPDATE `blade_payment_application_record`
+SET `kingdee_bill_id` = JSON_UNQUOTE(JSON_EXTRACT(`voucher_json`, '$.id'))
+WHERE `kingdee_bill_id` IS NULL AND `voucher_json` IS NOT NULL;
+```
+
+### 2. A103-4 回写
+
+`PaymentApplicationServiceImpl.applyPayBillRecord` 补一行:
+
+```java
+record.setKingdeeBillId(payBill.getId() == null ? null : String.valueOf(payBill.getId()));
+```
+
+### 3. preentry 解析(KingdeeApBillSyncSupport)
+
+- `KingdeeApBillSyncSupport` 追加注入 5 个 Mapper:`FormalSettlementSourceMapper`、`PreSettlementAdvanceMapper`、`SettlementProjectAdvanceWriteOffMapper`、`PaymentApplicationMapper`、`PaymentApplicationRecordMapper`;
+- 新增私有方法 `resolvePreEntries(FormalSettlement settlement)`:按第三章两条链路取数 → 逐笔校验(第四章拦截规则)→ 分摊 → 按 `y_billid` 合并,返回 `List`;
+- `pushApBill` 中 A102-4 预检通过后、保存前调用:
+
+```java
+List preEntries = this.resolvePreEntries(settlement);
+if (!preEntries.isEmpty()) {
+ param.setPreentry(preEntries);
+}
+```
+
+同时删除原 TODO 注释。
+
+### 4. 日志
+
+每笔输出:来源(进度预付/项目预付)、`y_billid`、`y_settleamt`;跳过/封顶/拦截输出原因。日志禁用中文标点。
+
+---
+
+## 六、边界与风险
+
+| # | 边界 | 处理 |
+| --- | --- | --- |
+| 1 | 历史已推送的应付单 | A102-4 预检命中幂等返回,**不会补 preentry**(现有设计,不处理) |
+| 2 | 预付未付款(synced/paying)但有抵扣金额 | 按拦截规则 #2 阻断,等付款完成后重推自动成功 |
+| 3 | 进度预付部分付款 | 按已付金额(`paid_amount`)送,未付部分不抵扣;如业务后续要求"全额付清才可推应付单",在拦截规则追加 `paid_amount >= applied_amount` |
+| 4 | 存量付款记录无 `kingdee_bill_id` 且 `voucher_json` 缺失 | 拦截规则 #3 阻断,走付款管理【同步付款结果】重新回写 |
+| 5 | preentry 合计超应付单金额 | 正常业务不会出现(核销/预付均封顶于结算金额);防御性不额外校验,依赖金蝶侧报错 |
+| 6 | `ap_paidbill`(期初预付单) | TMS 不产生,不在本期范围;如有手工核销需求由金蝶侧人工处理 |
+
+---
+
+## 七、验证要点
+
+1. 无预付抵扣的应付单:报文无 `preentry` 字段(非空数组)。
+2. 单笔项目预付核销 + 已付款:一条 preentry,`y_settleamt` = 核销额。
+3. 进度预付跨多个预结算分摊:同 `y_billid` 合并为一条,金额为各行之和。
+4. 预付未付款时推应付单:拦截、落 `failed` 与原因;付款完成后定时重推成功且带 preentry。
+5. 部分付款(多条付款处理记录):分摊合计 = 应抵扣金额,末条补差无分差。
+6. 存量数据回填:SQL 重复执行幂等,回填后无需重新同步付款结果。
From d69b293dd3c712a22ed5025a3a5b86c519aafac5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Wed, 4 Nov 2026 16:17:00 +0800
Subject: [PATCH 04/11] =?UTF-8?q?refactor:=20=E8=A7=84=E8=8C=83=E9=87=91?=
=?UTF-8?q?=E8=9D=B6=E5=BA=94=E4=BB=98=E5=8D=95=E5=90=8C=E6=AD=A5=E6=97=A5?=
=?UTF-8?q?=E5=BF=97=E8=8B=B1=E6=96=87=E6=A0=87=E7=82=B9=E5=B9=B6=E8=A1=A5?=
=?UTF-8?q?=E5=85=85=E9=A2=84=E4=BB=98=E4=BF=A1=E6=81=AF=E5=85=B3=E9=94=AE?=
=?UTF-8?q?=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../support/KingdeeApBillSyncSupport.java | 40 ++++++++++++++-----
1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
index 21be0c4f..c967fad6 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
@@ -100,6 +100,10 @@ import java.util.stream.Collectors;
* + 结算合计费用项(手动添加的每行一条);
* 物料编码按装卸大类/项目业务模式/运单运输方式映射,编码维护在 Nacos 配置 thirdparty.bfi.material.*(见 {@link #resolveMaterialNumber});
* 运输类分录数量取运输量(按税率拆行时每行都取运输量)、装卸类默认 1;单价按结算金额/数量反算。
+ * 预付信息分录(preentry,见 {@link #resolvePreEntries}):存在预付款抵扣(进度预付/项目预付核销)时,
+ * 按金蝶付款处理单(cas_paybill)逐笔送出 y_billtype/y_billid/y_settleamt,同 y_billid 合并求和;
+ * 任一笔应抵扣预付无法定位金蝶付款处理单内码(未付款/内码未回写/实付不足)时抛异常拦截应付单推送,
+ * 失败落 kingdee_fail_reason,付款结果回写后由重推任务自动续推。
*
* @author Chill
*/
@@ -283,7 +287,9 @@ public class KingdeeApBillSyncSupport {
* 幂等跳过保存并返回已有单据编号(说明上次同步已保存成功、在后续环节中断,应续推而非拦截报错)。
* 明细分录取页面结算明细(每行按 货物→费用大类→税率 拆分)+ 结算合计费用项(每行一条),结算金额逐行直送;
* 汇率日期/汇率取结算单页面维护值;付款计划 planentity 暂不传(启用方案见方法内注释),
- * 当前由金蝶按明细自动汇总生成
+ * 当前由金蝶按明细自动汇总生成;
+ * 预付信息分录 preentry 仅在真正新建应付单时解析(幂等跳过路径不做预付校验),
+ * 每条对应一张金蝶付款处理单(cas_paybill),取数口径见 {@link #resolvePreEntries}
*
* @param apBillSrcCode 财务应付单防重键(正式结算单号_结算明细单据号拼接)
* @param settlement 正式结算单(合同/汇率日期/汇率取数来源)
@@ -299,7 +305,7 @@ public class KingdeeApBillSyncSupport {
String existBillNo = context.apBillNoCache().computeIfAbsent(apBillSrcCode, code ->
queryApBillExistNos(List.of(code)).getOrDefault(code, ""));
if (Func.isNotEmpty(existBillNo)) {
- log.info("正式结算单[{}]金蝶财务应付单已生成(单据编号[{}]),幂等跳过 A102-2 保存", subject, existBillNo);
+ log.info("正式结算单[{}]金蝶财务应付单已生成(单据编号[{}]), 幂等跳过 A102-2 保存", subject, existBillNo);
return new BfiApBillPushOutcome(existBillNo, null, true);
}
ContractManage contract = requireContract(settlement.getContractId(), context);
@@ -410,14 +416,14 @@ public class KingdeeApBillSyncSupport {
}
// 推送入参摘要(联调排查:防重键、分录条数、页面维护的汇率口径)
- log.info("推送金蝶财务应付单:正式结算单[{}],防重键[{}],明细分录{}条,预付信息{}条,汇率日期[{}],汇率[{}]",
+ log.info("推送金蝶财务应付单: 正式结算单[{}], 防重键[{}], 明细分录{}条, 预付信息{}条, 汇率日期[{}], 汇率[{}]",
subject, apBillSrcCode, detailentry.size(), preEntries.size(), param.getExratedate(), param.getExchangerate());
BfiBillSaveResultVO saveResult = bfiService.saveApBill(param);
// 应付单id不落库,后续如需可经 A102-4 按防重键(awrp_src_sys + awrp_src_code)查询
requireBfiSaveSuccess(saveResult, "推送金蝶财务应付单");
String billNo = saveResult.getResult().get(0).getNumber();
- log.info("金蝶财务应付单保存成功:正式结算单[{}],单据编号[{}],明细分录{}条", subject, billNo, detailentry.size());
+ log.info("金蝶财务应付单保存成功: 正式结算单[{}], 单据编号[{}], 明细分录{}条", subject, billNo, detailentry.size());
// 星瀚应付单内码随结果返回(A902 附件上传定位用)
BfiBillSaveResultItemVO savedItem = saveResult.getResult().get(0);
return new BfiApBillPushOutcome(savedItem.getNumber(), savedItem.getId() == null ? null : String.valueOf(savedItem.getId()), false);
@@ -487,8 +493,14 @@ public class KingdeeApBillSyncSupport {
}
}
if (demandAmounts.isEmpty()) {
+ // 无预付抵扣(无核销行且预付记录已付金额均为0):不送 preentry,保持报文字段缺省
+ log.info("应付单预付信息归集: 正式结算单[{}], 无预付抵扣, 不送预付信息分录", settlement.getFormalSettlementNo());
return List.of();
}
+ // 预付抵扣归集摘要(联调排查: 项目预付按核销行、进度预付按预付记录已付金额归集到底层付款申请)
+ log.info("应付单预付信息归集: 正式结算单[{}], 应抵扣付款申请{}笔, 合计金额{}",
+ settlement.getFormalSettlementNo(), demandAmounts.size(),
+ demandAmounts.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add));
// 批量取付款申请与付款处理记录(仅保留带回金蝶付款处理单内码的记录),逐笔校验并分摊
Map applications = this.paymentApplicationMapper.selectBatchIds(demandAmounts.keySet()).stream()
.collect(Collectors.toMap(PaymentApplication::getId, Function.identity(), (first, second) -> first));
@@ -542,6 +554,9 @@ public class KingdeeApBillSyncSupport {
String summary = blockReasons.size() > PREPAY_BLOCK_REASON_LIMIT
? String.join(";", blockReasons.subList(0, PREPAY_BLOCK_REASON_LIMIT)) + ";等" + blockReasons.size() + "笔预付无法抵扣"
: String.join(";", blockReasons);
+ // 拦截关键日志:原因落盘供排查(异常文案同步落 kingdee_fail_reason,付款结果回写后由重推任务自动续推)
+ log.warn("应付单预付信息校验未通过, 拦截应付单推送: 正式结算单[{}], 应抵扣付款申请{}笔, 原因: {}",
+ settlement.getFormalSettlementNo(), demandAmounts.size(), summary);
throw new ServiceException("推送金蝶财务应付单失败:" + summary);
}
List preEntries = new ArrayList<>();
@@ -554,6 +569,11 @@ public class KingdeeApBillSyncSupport {
log.info("应付单预付信息分录: 正式结算单[{}], 来源[{}], y_billid={}, y_settleamt={}",
settlement.getFormalSettlementNo(), sourcesByBillId.get(billId), billId, settleAmount);
});
+ // 分录解析摘要:同一付款申请跨多预结算分摊后落在同一付款处理单的金额已按 y_billid 合并
+ log.info("应付单预付信息解析完成: 正式结算单[{}], 应抵扣付款申请{}笔, 生成分录{}条, 合计金额{}",
+ settlement.getFormalSettlementNo(), demandAmounts.size(), preEntries.size(),
+ preEntries.stream().map(BfiApBillSavePreEntryDTO::getYSettleamt)
+ .reduce(BigDecimal.ZERO, BigDecimal::add));
return preEntries;
}
@@ -635,7 +655,7 @@ public class KingdeeApBillSyncSupport {
+ "]无结算明细与结算合计费用项,无法解析分录");
}
// 分录解析摘要(联调排查:分录数=结算明细拆分行+手动添加的结算合计费用项,物料/分录标识逐条见下方分录生成日志)
- log.info("金蝶应付单分录解析完成:正式结算单[{}],结算明细{}条 + 手工结算合计{}条 = 共{}条分录",
+ log.info("金蝶应付单分录解析完成: 正式结算单[{}], 结算明细{}条 + 手工结算合计{}条 = 共{}条分录",
settlement.getFormalSettlementNo(), settlementDetails.size(), manualSummaryFees.size(), entryGroups.size());
return entryGroups;
}
@@ -680,7 +700,7 @@ public class KingdeeApBillSyncSupport {
context.taxRateByRule(), rowAmount);
if (splits.isEmpty()) {
// 0元货物行(费用项与结算金额均为0)跳过不生成0元分录
- log.info("金蝶应付单分录生成:来源[{}],费用项与结算金额均为0,跳过该货物行", sourceDesc);
+ log.info("金蝶应付单分录生成: 来源[{}], 费用项与结算金额均为0, 跳过该货物行", sourceDesc);
return;
}
// 运输类数量:取运单运输量(未维护兜底 1)
@@ -707,7 +727,7 @@ public class KingdeeApBillSyncSupport {
String entryCode = entryCodePrefix + "-" + split.getCategory().getLabel() + split.taxRateSuffix();
entryGroups.add(new BfiEntryGroup(materialNumber, entryCode, quantity, price, amount,
amountNoTax, cargoName, vehicleNo, context.settlement().getId()));
- log.info("金蝶应付单分录生成:来源[{}],分录标识[{}],物料编码[{}],数量[{}],单价[{}],含税金额[{}],不含税金额[{}]",
+ log.info("金蝶应付单分录生成: 来源[{}], 分录标识[{}], 物料编码[{}], 数量[{}], 单价[{}], 含税金额[{}], 不含税金额[{}]",
sourceDesc, entryCode, materialNumber, quantity, price, amount, amountNoTax);
}
}
@@ -741,7 +761,7 @@ public class KingdeeApBillSyncSupport {
+ (Func.isBlank(feeItem) ? feeType : feeType + "-" + feeItem);
entryGroups.add(new BfiEntryGroup(materialNumber, entryCode, quantity, price, amount,
null, null, null, settlement.getId()));
- log.info("金蝶应付单分录生成:来源[{}],分录标识[{}],物料编码[{}],数量[{}],单价[{}],含税金额[{}]",
+ log.info("金蝶应付单分录生成: 来源[{}], 分录标识[{}], 物料编码[{}], 数量[{}], 单价[{}], 含税金额[{}]",
sourceDesc, entryCode, materialNumber, quantity, price, amount);
}
@@ -840,7 +860,7 @@ public class KingdeeApBillSyncSupport {
} catch (RuntimeException ignored) {
// 计费方案 JSON 兼容历史数据,解析失败按未配置处理
}
- log.info("合同[{}]计费方案解析:{}项费用类型/费用项配置税率{}", contract.getContractNo(), taxRateByRule.size(), taxRateByRule);
+ log.info("合同[{}]计费方案解析: {}项费用类型/费用项配置税率{}", contract.getContractNo(), taxRateByRule.size(), taxRateByRule);
return taxRateByRule;
}
@@ -1090,7 +1110,7 @@ public class KingdeeApBillSyncSupport {
}
loaded.putIfAbsent(feeItem.getName().trim(), feeItem.getFeeCategory().trim());
}
- log.info("费用项档案加载:{}项(费用项名称 -> 费用大类编码)", loaded.size());
+ log.info("费用项档案加载: {}项(费用项名称 -> 费用大类编码)", loaded.size());
cache.putAll(loaded);
return cache;
}
From 23c0d66037f45c059a783c12019c63cce92bc65f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Wed, 4 Nov 2026 23:10:05 +0800
Subject: [PATCH 05/11] =?UTF-8?q?:sparkles:=20=E9=87=91=E8=9D=B6=E6=8E=A8?=
=?UTF-8?q?=E9=80=81=E9=A1=B9=E7=9B=AE=E7=BC=96=E7=A0=81=E7=9C=9F=E5=AE=9E?=
=?UTF-8?q?=E5=8C=96=E4=B8=8E=E5=90=88=E5=90=8C=E5=85=A5=E5=8F=82=E9=80=81?=
=?UTF-8?q?=E5=87=BA=EF=BC=88P0/P1=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增公共方法 kingdeeProjectNumber:开关开启取 blade_project_apply.project_code 真实编码,未关联项目兜底 999;应付/应收/预付款/应付下推/开票五处赋值统一复用
- 应付/应收上游合同号按开关送出(awrp_src_bt=awrp_contract_info + awrp_src_con_no,仅 kingdee_id 非空的已同步合同)
- 开票申请送合同三件套:contractno/contractamount/contractdate(取申请日期)
- BfiProperties 新增 projectRealCodeEnabled、contractRefEnabled 开关,默认关闭;Nacos 模板同步补充
---
.../transport/config/BfiProperties.java | 16 +++++++++
.../impl/InvoiceApplicationServiceImpl.java | 20 ++++++++---
.../impl/PaymentApplicationServiceImpl.java | 16 +++------
.../support/KingdeeApBillSyncSupport.java | 35 ++++++++++++++-----
.../support/KingdeeArBillSyncSupport.java | 10 ++++--
doc/nacos/blade-dev.yaml | 6 ++++
doc/nacos/blade-prod.yaml | 5 +++
doc/nacos/third-party-api.yaml | 5 +++
8 files changed, 86 insertions(+), 27 deletions(-)
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java
index 19174df4..213e316a 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java
@@ -55,6 +55,22 @@ public class BfiProperties {
*/
private String srcSys = BfiConstant.DATA_SOURCE_WLTMS;
+ /**
+ * 项目编码真实化开关(thirdparty.bfi.project-real-code-enabled):开启后推送金蝶的项目编码取
+ * blade_project_apply.project_code 真实值(前提:金蝶项目档案已存在且编码与 project_code 一致,
+ * 否则该单推送失败、失败原因回写单据可重推),单据未关联项目/编码为空仍兜底 999;
+ * 关闭维持联调临时值 999,出问题关开关即回退
+ */
+ private boolean projectRealCodeEnabled = false;
+
+ /**
+ * 合同引用开关(thirdparty.bfi.contract-ref-enabled):开启后财务应付/应收送上游合同号
+ * (awrp_src_bt=awrp_contract_info + awrp_src_con_no,仅 blade_contract_manage.kingdee_id 非空的已同步合同,
+ * 防上游合同勾稽挂空)、开票申请送合同三件套(contractno/contractdate/contractamount,contractdate 取申请日期);
+ * 关闭维持不送,出问题关开关即回退
+ */
+ private boolean contractRefEnabled = false;
+
/**
* 付款申请推送配置(A103-3 付款申请保存)
*/
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java
index f2f9e7ac..9c513a2e 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java
@@ -885,7 +885,8 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl items) {
+ String firstArSrcCode, BigDecimal sheetAmount, List items,
+ ContractManage contract, KingdeeSyncContext kingdeeContext) {
BfiInvoiceApplySaveDTO param = new BfiInvoiceApplySaveDTO();
// ==================== 以下为【必填】字段(BfiInvoiceApplySaveDTO 标注),非必填字段先注释保留 ====================
// 【必填】组织.编码:合同平台公司金蝶组织编码
@@ -1005,8 +1009,8 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl
Date: Thu, 5 Nov 2026 00:05:35 +0800
Subject: [PATCH 06/11] =?UTF-8?q?:sparkles:=20=E9=87=91=E8=9D=B6=E8=B4=A2?=
=?UTF-8?q?=E5=8A=A1=E5=BA=94=E4=BB=98=E5=8D=95=E6=98=8E=E7=BB=86=E5=88=86?=
=?UTF-8?q?=E5=BD=95=E6=8E=A8=E9=80=81=E7=A8=8E=E7=8E=87(taxrate)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../transport/support/KingdeeApBillSyncSupport.java | 13 ++++++++-----
.../bfi/pojo/dto/BfiApBillSaveEntryDTO.java | 4 ++++
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
index ee0018ea..82e0b0e3 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
@@ -381,6 +381,8 @@ public class KingdeeApBillSyncSupport {
entry.setEPricetaxtotal(entryGroup.amount());
// 金额(不含税):结算明细行结算金额(不含税),结算合计费用项行无不含税金额不传
entry.setEAmount(entryGroup.amountNoTax());
+ // 税率(%):合同计费方案规则税率(按税率拆行维度),未配置税率/结算合计费用项行不送,金蝶按默认带出
+ entry.setTaxrate(entryGroup.taxRate());
// 【必填】项目.项目编码:开关开启取项目档案真实编码(金蝶档案须已存在且编码一致),未关联项目兜底 999
entry.setProjectNumber(this.kingdeeProjectNumber(settlement.getProjectId(), context));
// 【必填】外部系统来源分录标识(候选键):结算明细行取单据号,结算合计费用项行取结算单号-费用类型-费用项拼接
@@ -560,9 +562,9 @@ public class KingdeeApBillSyncSupport {
// 分录唯一标识:单据号-货物序号-费用大类-税率(税率未配置不拼)
String entryCode = entryCodePrefix + "-" + split.getCategory().getLabel() + split.taxRateSuffix();
entryGroups.add(new BfiEntryGroup(materialNumber, entryCode, quantity, price, amount,
- amountNoTax, cargoName, vehicleNo, context.settlement().getId()));
- log.info("金蝶应付单分录生成:来源[{}],分录标识[{}],物料编码[{}],数量[{}],单价[{}],含税金额[{}],不含税金额[{}]",
- sourceDesc, entryCode, materialNumber, quantity, price, amount, amountNoTax);
+ amountNoTax, cargoName, vehicleNo, context.settlement().getId(), split.getTaxRate()));
+ log.info("金蝶应付单分录生成:来源[{}],分录标识[{}],物料编码[{}],数量[{}],单价[{}],含税金额[{}],不含税金额[{}],税率[{}]",
+ sourceDesc, entryCode, materialNumber, quantity, price, amount, amountNoTax, split.getTaxRate());
}
}
@@ -594,7 +596,7 @@ public class KingdeeApBillSyncSupport {
String entryCode = settlement.getFormalSettlementNo() + "-"
+ (Func.isBlank(feeItem) ? feeType : feeType + "-" + feeItem);
entryGroups.add(new BfiEntryGroup(materialNumber, entryCode, quantity, price, amount,
- null, null, null, settlement.getId()));
+ null, null, null, settlement.getId(), null));
log.info("金蝶应付单分录生成:来源[{}],分录标识[{}],物料编码[{}],数量[{}],单价[{}],含税金额[{}]",
sourceDesc, entryCode, materialNumber, quantity, price, amount);
}
@@ -1297,10 +1299,11 @@ public class KingdeeApBillSyncSupport {
* @param transportGoods 运输货物(金蝶接口新字段 awrp_transport):结算明细货物名称,结算合计费用项行为 null 不传
* @param vehicleNo 车号(金蝶接口新字段 awrp_lpn):结算明细车号,结算合计费用项行为 null 不传
* @param formalSettlementId 分录所属正式结算单id(多结算单付款申请 A103-1 按结算单勾稽各自应付单)
+ * @param taxRate 该行税率(%)(合同计费方案规则税率,按税率拆行维度),无税率组/结算合计费用项行为 null 不传
*/
public record BfiEntryGroup(String materialNumber, String entryCode,
BigDecimal quantity, BigDecimal price, BigDecimal amount, BigDecimal amountNoTax,
- String transportGoods, String vehicleNo, Long formalSettlementId) {
+ String transportGoods, String vehicleNo, Long formalSettlementId, BigDecimal taxRate) {
}
/**
diff --git a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiApBillSaveEntryDTO.java b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiApBillSaveEntryDTO.java
index 7810ec0e..1ef2004e 100644
--- a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiApBillSaveEntryDTO.java
+++ b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiApBillSaveEntryDTO.java
@@ -102,6 +102,10 @@ public class BfiApBillSaveEntryDTO implements Serializable {
*/
@JsonProperty("taxrateid_number")
private String taxrateidNumber;
+ /**
+ * 税率(%),取合同计费方案规则税率数值(如 9 表示 9%),未取到税率不送
+ */
+ private BigDecimal taxrate;
/**
* 核心单据行号
*/
From 8d189eb0d57da30a3ca30939bcaba14761dd2e91 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Thu, 5 Nov 2026 00:16:38 +0800
Subject: [PATCH 07/11] =?UTF-8?q?:sparkles:=20=E9=87=91=E8=9D=B6=E8=B4=A2?=
=?UTF-8?q?=E5=8A=A1=E5=BA=94=E4=BB=98=E5=8D=95=E5=88=86=E5=BD=95=E9=80=81?=
=?UTF-8?q?=E7=A8=8E=E7=8E=87=E7=BC=96=E7=A0=81(taxrateid=5Fnumber)?=
=?UTF-8?q?=EF=BC=8C=E7=A8=8E=E7=8E=87=E6=98=A0=E5=B0=84Nacos=E5=8F=AF?=
=?UTF-8?q?=E7=BB=B4=E6=8A=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../transport/config/BfiProperties.java | 14 +++++++++++
.../support/KingdeeApBillSyncSupport.java | 24 +++++++++++++++++++
.../bfi/pojo/dto/BfiApBillSaveEntryDTO.java | 2 +-
doc/nacos/blade-dev.yaml | 11 +++++++++
doc/nacos/third-party-api.yaml | 11 +++++++++
5 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java
index 213e316a..11a8c2dc 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java
@@ -148,6 +148,20 @@ public class BfiProperties {
*/
private Material material = new Material();
+ /**
+ * 金蝶税率编码映射(A102-2 财务应付单分录 taxrateid_number):税率数值 -> 金蝶税率.编码(如 9 -> V9),
+ * 键为税率数值文本(如 "9"、"6.5"),推送时按分录税率查表;未维护该税率时直接拦截报错;
+ * 分录无税率(计费方案未配置税率组/残差组/手动结算合计费用行)时税率与税率编码均不送
+ */
+ private Map taxrate = new LinkedHashMap<>() {{
+ put("0", "V0");
+ put("1", "V1");
+ put("3", "V3");
+ put("6", "V6");
+ put("9", "V9");
+ put("13", "V13");
+ }};
+
/**
* 付款申请推送配置项
*/
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
index 82e0b0e3..5455c2d8 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java
@@ -383,6 +383,8 @@ public class KingdeeApBillSyncSupport {
entry.setEAmount(entryGroup.amountNoTax());
// 税率(%):合同计费方案规则税率(按税率拆行维度),未配置税率/结算合计费用项行不送,金蝶按默认带出
entry.setTaxrate(entryGroup.taxRate());
+ // 税率编码(taxrateid_number):thirdparty.bfi.taxrate 配置 税率数值->编码,未维护该税率拦截报错
+ entry.setTaxrateidNumber(taxrateCode(entryGroup.taxRate()));
// 【必填】项目.项目编码:开关开启取项目档案真实编码(金蝶档案须已存在且编码一致),未关联项目兜底 999
entry.setProjectNumber(this.kingdeeProjectNumber(settlement.getProjectId(), context));
// 【必填】外部系统来源分录标识(候选键):结算明细行取单据号,结算合计费用项行取结算单号-费用类型-费用项拼接
@@ -655,6 +657,28 @@ public class KingdeeApBillSyncSupport {
return text != null && text.contains("国际");
}
+ /**
+ * 金蝶税率编码(taxrateid_number):thirdparty.bfi.taxrate 配置 税率数值 -> 编码(如 9 -> V9),
+ * 税率为空(无税率组/手动结算合计费用行)返回 null 不送;配置未维护该税率时直接拦截报错
+ * (与物料映射拦截口径一致),税率数值键去除尾零精确匹配(9.00 按 "9" 匹配)
+ *
+ * @param taxRate 分录税率(百分数,来自合同计费方案规则)
+ * @return 金蝶税率.编码,无税率为 null
+ */
+ private String taxrateCode(BigDecimal taxRate) {
+ if (taxRate == null) {
+ return null;
+ }
+ String rateKey = taxRate.stripTrailingZeros().toPlainString();
+ String code = bfiProperties.getTaxrate() == null ? null : bfiProperties.getTaxrate().get(rateKey);
+ if (Func.isBlank(code)) {
+ throw new ServiceException("推送金蝶财务应付单失败:税率[" + rateKey + "%]未在配置 thirdparty.bfi.taxrate 中维护税率编码,请补充后重试");
+ }
+ // 税率编码映射判定依据(联调排查:税率 -> 金蝶税率档案编码)
+ log.info("金蝶税率编码映射: 税率[{}%] -> 编码[{}]", rateKey, code);
+ return code.trim();
+ }
+
/**
* 合同计费方案规则税率解析:费用类型/费用项 -> 税率(取首个配置了税率的规则,
* 计费方案 JSON 解析失败按未配置处理,由税率分组处兜底为无税率组)
diff --git a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiApBillSaveEntryDTO.java b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiApBillSaveEntryDTO.java
index 1ef2004e..53f71b83 100644
--- a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiApBillSaveEntryDTO.java
+++ b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/pojo/dto/BfiApBillSaveEntryDTO.java
@@ -98,7 +98,7 @@ public class BfiApBillSaveEntryDTO implements Serializable {
*/
private Boolean ispresent = Boolean.FALSE;
/**
- * 税率.编码,城矿传 V13(BfiConstant.TAX_RATE_V13)
+ * 税率.编码,按 thirdparty.bfi.taxrate 配置的 税率数值->编码 映射取值(如 9 -> V9),未维护该税率拦截报错
*/
@JsonProperty("taxrateid_number")
private String taxrateidNumber;
diff --git a/doc/nacos/blade-dev.yaml b/doc/nacos/blade-dev.yaml
index f214c5e1..4bfa61ec 100644
--- a/doc/nacos/blade-dev.yaml
+++ b/doc/nacos/blade-dev.yaml
@@ -190,6 +190,17 @@ thirdParty:
# 仓储大类、手动添加仓储费用物料编码(仓储)
warehouse: ${BFI_MATERIAL_WAREHOUSE:XDWL11002001}
+ # 金蝶税率编码映射(A102-2 财务应付单分录 taxrateid_number):税率数值 -> 税率.编码(如 9 -> V9),
+ # 键为税率数值文本(含小数税率如 "[6.5]"),未维护该税率时推送拦截报错;
+ # 分录无税率(计费方案未配置税率组/残差组/手动结算合计费用行)时税率与税率编码均不送
+ taxrate:
+ "[0]": ${BFI_TAXRATE_0:V0}
+ "[1]": ${BFI_TAXRATE_1:V1}
+ "[3]": ${BFI_TAXRATE_3:V3}
+ "[6]": ${BFI_TAXRATE_6:V6}
+ "[9]": ${BFI_TAXRATE_9:V9}
+ "[13]": ${BFI_TAXRATE_13:V13}
+
# 付款申请推送配置(A103-3 付款申请保存)
payApply:
# 单据类型编码:ap_payapply_BT_S 采购付款申请、ap_payapply_oth_BT_S 其他付款申请
diff --git a/doc/nacos/third-party-api.yaml b/doc/nacos/third-party-api.yaml
index 145ef35e..a44464a0 100644
--- a/doc/nacos/third-party-api.yaml
+++ b/doc/nacos/third-party-api.yaml
@@ -91,6 +91,17 @@ thirdParty:
loading: ${BFI_MATERIAL_LOADING:XDWL11002004}
# 仓储大类、手动添加仓储费用物料编码(仓储)
warehouse: ${BFI_MATERIAL_WAREHOUSE:XDWL11002001}
+
+ # 金蝶税率编码映射(A102-2 财务应付单分录 taxrateid_number):税率数值 -> 税率.编码(如 9 -> V9),
+ # 键为税率数值文本(含小数税率如 "[6.5]"),未维护该税率时推送拦截报错;
+ # 分录无税率(计费方案未配置税率组/残差组/手动结算合计费用行)时税率与税率编码均不送
+ taxrate:
+ "[0]": ${BFI_TAXRATE_0:V0}
+ "[1]": ${BFI_TAXRATE_1:V1}
+ "[3]": ${BFI_TAXRATE_3:V3}
+ "[6]": ${BFI_TAXRATE_6:V6}
+ "[9]": ${BFI_TAXRATE_9:V9}
+ "[13]": ${BFI_TAXRATE_13:V13}
# 付款申请推送配置(A103-3 付款申请保存)
payApply:
# 单据类型编码:ap_payapply_BT_S 采购付款申请、ap_payapply_oth_BT_S 其他付款申请
From 21cf57a144c14327b3d76d34871b721e7bfa5029 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Thu, 5 Nov 2026 00:39:02 +0800
Subject: [PATCH 08/11] =?UTF-8?q?docs:=20=E9=87=91=E8=9D=B6=EF=BC=88?=
=?UTF-8?q?=E6=98=9F=E7=80=9A=EF=BC=89BFI=E4=B8=8E=E5=90=88=E5=90=8C?=
=?UTF-8?q?=E5=90=88=E8=A7=84=E7=B3=BB=E7=BB=9F=EF=BC=88HCS=EF=BC=89?=
=?UTF-8?q?=E7=BB=84=E5=90=88=E6=93=8D=E4=BD=9C=E6=89=8B=E5=86=8C=E4=BF=AE?=
=?UTF-8?q?=E8=AE=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 合并 HCS 操作内容(项目立项/合同/特批/客商风险/履约四场景),项目与合同置于客商章节后
- 新增第 2 节全链路总览:12 条环节流程链(【系统】→步骤→▼,含落库表与接口号)与通用规则
- 场景分流/拦截提示原文/解决方法在 4.x 对应小节补齐
- 第 5 节新增 5.5 HCS 定时任务与六任务逐项运转逻辑
- 按 11-04/11-05 代码更新:应付单 preentry 预付抵扣分录、分录送税率、公司代码术语、已指定应付列范围、付款处理单内码回写、新增准备配置项(税率映射/推送内容开关/接口超时)
---
.../41-项目管理列表-推送合规.png | Bin 0 -> 262879 bytes
.../42-付款管理-特批审核当前节点.png | Bin 0 -> 262183 bytes
.../43-付款管理列表-已付款回写.png | Bin 0 -> 134463 bytes
.../image-20261030195438695.png | Bin 0 -> 99572 bytes
.../image-20261030203349665.png | Bin 0 -> 109207 bytes
.../image-20261103185134875.png | Bin 0 -> 374130 bytes
...-14-金蝶(星瀚)BFI对接操作手册(纯操作版).md | 23 +++++++++++++-----
7 files changed, 17 insertions(+), 6 deletions(-)
create mode 100644 doc/docs/业务流程/2026-10-14-金蝶(星瀚)BFI对接操作手册(纯操作版).assets/41-项目管理列表-推送合规.png
create mode 100644 doc/docs/业务流程/2026-10-14-金蝶(星瀚)BFI对接操作手册(纯操作版).assets/42-付款管理-特批审核当前节点.png
create mode 100644 doc/docs/业务流程/2026-10-14-金蝶(星瀚)BFI对接操作手册(纯操作版).assets/43-付款管理列表-已付款回写.png
create mode 100644 doc/docs/业务流程/2026-10-14-金蝶(星瀚)BFI对接操作手册(纯操作版).assets/image-20261030195438695.png
create mode 100644 doc/docs/业务流程/2026-10-14-金蝶(星瀚)BFI对接操作手册(纯操作版).assets/image-20261030203349665.png
create mode 100644 doc/docs/业务流程/2026-10-14-金蝶(星瀚)BFI对接操作手册(纯操作版).assets/image-20261103185134875.png
diff --git a/doc/docs/业务流程/2026-10-14-金蝶(星瀚)BFI对接操作手册(纯操作版).assets/41-项目管理列表-推送合规.png b/doc/docs/业务流程/2026-10-14-金蝶(星瀚)BFI对接操作手册(纯操作版).assets/41-项目管理列表-推送合规.png
new file mode 100644
index 0000000000000000000000000000000000000000..85164e8aaa09f3e883e89c7938e43245cbfd3958
GIT binary patch
literal 262879
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