From e18c7dcfdabf7418eaf15cd7766e98b8edd0b675 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, 17 Sep 2026 10:39:08 +0800 Subject: [PATCH] =?UTF-8?q?:memo:=20=E6=96=B0=E5=A2=9E=E4=BB=98=E6=AC=BE?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=AD=A3=E5=BC=8F=E4=BB=98=E6=AC=BE=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E9=87=91=E8=9D=B6=E6=8A=80=E6=9C=AF=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...¼�付款同步金蝶(财务应付单+付款申请下推)技术文档.md | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 doc/docs/业务流程/2026-09-16-付款管理正式付款同步金蝶(财务应付单+付款申请下推)技术文档.md diff --git a/doc/docs/业务流程/2026-09-16-付款管理正式付款同步金蝶(财务应付单+付款申请下推)技术文档.md b/doc/docs/业务流程/2026-09-16-付款管理正式付款同步金蝶(财务应付单+付款申请下推)技术文档.md new file mode 100644 index 00000000..28d5410a --- /dev/null +++ b/doc/docs/业务流程/2026-09-16-付款管理正式付款同步金蝶(财务应付单+付款申请下推)技术文档.md @@ -0,0 +1,244 @@ +# 正式付款同步金蝶(星瀚)技术文档:财务应付单 + 付款申请下推 + +> 适用系统:TMS(BladeX 微服务平台,服务:blade-transport) +> 对接系统:金蝶云·星瀚(业财融合 BFI,经 iPaaS 网关) +> 关联文档:`doc/docs/TMS业财融合-集成流程图文字版与业务流程梳理.md`、`doc/docs/业财融合系统接口文档.xlsx`、`doc/docs/业务流程/付款申请同步金蝶(星瀚)技术文档.md`(A103-3 预付款路径) +> 最后更新:2026-09-16 + +--- + +## 1. 背景与范围 + +正式结算单发起付款申请后,付款管理(`blade_payment_application`,`paymentType = settlement_payment`)生成一条记录;审批通过后勾选点"批量同步",需**先推送财务应付单(A102-2),再由应付下推付款申请(A103-1)**,两步完成后才视为同步成功。 + +- 触发入口:付款管理页面(前端 `tms-erp-web/src/views/payment/payment-application.vue`)"批量同步"按钮,权限码 `payment_application_sync` +- 对接接口: + - **A102-2 财务应付单保存** `POST /ierp/kapi/v2/awrp/ap/ap/ap_finapbill/save` + - **A103-1 付款申请保存(应付下推)** `POST /ierp/kapi/v2/awrp/ap/ap/ap_finapbill/push` +- 路径划分:**正式付款**(settlement_payment)走本文档 A102-2 → A103-1 两步链路;**预付款**(project_advance / progress_advance)维持原 A103-3 直推付款申请单,见《付款申请同步金蝶(星瀚)技术文档》 +- 调用方式:前端 → TMS 后端转发 → 星瀚(OAuth2 凭证仅存后端,前端不持有) +- 落库结果:A103-1 返回的付款申请单 id 写入 `kingdee_bill_no`(既有字段);**A102-2 返回的应付单 id 不落库**,仅校验保存成功,后续如需可经 A102-4 按防重键(`awrp_src_sys` + `awrp_src_code`)查询(`BfiServiceImpl.queryApBill` 已封装),本次无表结构变更 + +--- + +## 2. 业务流程 + +### 2.1 整体链路(对应需求文档 4.3 步骤 4) + +``` +正式结算单发起付款申请 → 付款管理生成记录 → 审批通过(approved) + → 批量同步(本文档) + ① A102-2 财务应付单保存(防重键幂等) + ② A103-1 应付下推付款申请(分录关联①的 awrp_entry_code) + → 金蝶财务共享审批(黑盒) → 付款处理 → 付款完成 + → 后续(待建设):A103-2/A103-4 定时回写、A902 附件、B901 锁单 +``` + +### 2.2 批量同步时序 + +``` +前端 payment-application.vue blade-transport 后端 星瀚(BFI) + │ 勾选 approved 记录 │ │ + │ POST /payment-application/ │ │ + │ sync-kingdee-batch [id...] │ │ + │──────────────────────────────────────>│ 逐单循环(单条失败不中断批次) │ + │ │ FOR UPDATE 锁单 + approved 校验 │ + │ │ ① 组装 BfiApBillSaveDTO │ + │ │ POST ap_finapbill/save ──────────────>│ + │ │ <── result[]{id,...} ─────────────────│ + │ │ 仅校验保存成功(应付单id不落库) │ + │ │ ② 组装 BfiPayApplyPushDTO │ + │ │ entry.awrp_finapbill_entryid │ + │ │ = paymentNo + "-1" │ + │ │ POST ap_finapbill/push ──────────────>│ + │ │ <── result[]{id,...} ─────────────────│ + │ │ kingdeeBillNo = 付款申请单id │ + │ │ kingdeeStatus = synced │ + │ │ 下游台账联动(结算付款记录/预付台账) │ + │ <── R>(逐单结果)────────│ │ +``` + +### 2.3 前置条件与幂等约定 + +| 约定 | 说明 | +| --- | --- | +| 状态校验 | 仅 `approvalStatus = approved` 允许同步 | +| 幂等跳过 | `kingdeeStatus = synced` 的单据直接返回已存单据号,不重复推送 | +| ①防重键 | 星瀚应付单侧 `awrp_src_code`(=paymentNo)+ `awrp_src_sys`,②失败后重推时①走更新语义,不重复生成应付单 | +| ②防重键 | 付款申请单侧 `awrp_src_code`(=paymentNo)+ `awrp_src_sys`;分录行 `awrp_entry_code`(=paymentNo + "-1")不得重复 | +| ②关联键 | `awrp_finapbill_entryid` = ①明细的 `awrp_entry_code`(=paymentNo + "-1"),**不依赖①返回的内部 id** | +| 失败重推 | 任一步失败置 `kingdeeStatus = failed`,可重新勾选同步(①已成功的应付单按防重键走更新语义) | +| 前置校验 | ①推送前校验物料/计量单位常量非空(见 5.2);未关联合同、合同不存在、组织编码为空、结算币种为空时同步失败 | + +--- + +## 3. 接口定义 + +### 3.1 A102-2 财务应付单保存 + +- URL:`{thirdParty.bfi.baseUrl}/ierp/kapi/v2/awrp/ap/ap/ap_finapbill/save` +- Method:`POST`,请求体 `{"data": [ {主表字段, "detailentry":[明细]} ]}` +- 返回结构与 A103-3 一致:`data.result[].id` 为星瀚应付单内部主键,`billStatus=false` 时以 `errors` 抛出业务异常,`errorCode/message/status` 由 `BfiServiceImpl.commonCall` 统一校验。 + +### 3.2 A103-1 付款申请保存(应付下推) + +- URL:`{thirdParty.bfi.baseUrl}/ierp/kapi/v2/awrp/ap/ap/ap_finapbill/push` +- Method:`POST`,请求体 `{"data": [ {主表字段, "entry":[分录]} ]}` +- 返回 `result[].id` 为星瀚付款申请单内部主键(写入 `kingdee_bill_no`),`result[].number` 为星瀚单据编号(FKSQ-xxxx,暂不落库),`result[].type = Push`。 + +--- + +## 4. 字段映射关系 + +### 4.1 A102-2 主表(`BfiApBillSaveDTO` ← 付款申请实体 + 合同 + 常量) + +| 接口字段 | 含义 | 必填 | 来源 | 说明 | +| --- | --- | --- | --- | --- | +| billtypeid_number | 单据类型.编码 | 是 | 按映射字典转换:`KingdeeBfiConstant.BFI_AP_BILL_BILLTYPE_NAME`(默认"服务采购应付")经 `AP_BILL_BILLTYPE_MAP` 名称→编码 | 路由规则见 5.3;未维护名称报错 | +| org_number | 结算组织.编码 | 是 | **合同所属组织**:`contract.organizationId` → `dept.deptCode`,空回退组织名称(复用 `bfiOrgNumber`) | 缺失报错 | +| bizdate | 单据日期 | 是 | `applyDate`(空取当天) | 沿用 yyyyMMdd,**待确认是否需 yyyy-MM-dd** | +| asstacttype | 往来类型 | 是 | 常量 `bd_supplier` | 供应商 | +| asstact_number | 往来户.编码 | 是 | 复用 `bfiSupplierCode`:payeeName 匹配客商档案 `customerCode`,未命中回退 payeeName | | +| purmode | 付款方式 | 是 | 常量 `BFI_AP_BILL_PUR_MODE` | `CREDIT` 赊购(金蝶侧可调金额);`CASH` 会自动 100% 推付款 | +| currency_number | 结算币别.货币代码 | 是 | **合同结算币种** `contract.settlementCurrency`(复用 `bfiCurrency`) | 缺失报错 | +| payorg_number / purorg_number | 付款/采购组织.编码 | 是/否 | 同 org_number | | +| payproperty_number | 款项性质.编码 | 是 | 常量 `BFI_AP_BILL_PAY_PROPERTY` | 暂按 `2001`,**待金蝶确认** | +| isincludetax / ispricetotal | 录入含税价 / 录入总价 | 否 | `true` / `true` | 录入总价免单价数量换算 | +| exratetable_number / exratedate | 汇率表/汇率日期 | 否 | 复用配置 `thirdParty.bfi.payApply.exratetable`(默认 01)/ 同 bizdate | | +| asstactname | 往来单位名称 | 否 | `payeeName` | | +| remark | 备注 | 否 | `paymentNo + " " + settlementNo` | | +| awrp_src_sys / awrp_src_code | 外部系统编号/来源单据号 | 是 | 配置 `thirdParty.bfi.payApply.srcSys` / `paymentNo` | 应付单候选键 | +| awrp_src_bt / awrp_src_con_no | 来源单据/上游合同号 | 否 | `awrp_contract_info` / `contractNo` | 有合同即传 | +| awrp_src_type | 外部单据类型 | 是 | 常量 `BFI_AP_BILL_SRC_TYPE` | 暂按 `TMS财务应付单`,**待金蝶确认** | + +未传的可选字段:settlementtype_number(结算方式)、taxrateid_number(税率)、duedate、bookdate、department_number、preentry(预付信息)等。 + +### 4.2 A102-2 明细(`BfiApBillSaveEntryDTO`,单条申请固定 1 行) + +| 接口字段 | 含义 | 必填 | 来源 | 说明 | +| --- | --- | --- | --- | --- | +| material_number | 物料编码.编码 | 是 | 常量 `BFI_AP_BILL_MATERIAL` | **TMS 无物料档案,当前为空串,推送前校验拦截;待金蝶提供运输服务物料编码** | +| measureunit_number | 计量单位.编码 | 是 | 常量 `BFI_AP_BILL_MEASURE_UNIT` | **同上,待金蝶确认(如"吨")** | +| quantity | 明细.数量 | 是 | 固定 `1` | 结算单无吨位数据,配合 ispricetotal=true 录入总价 | +| e_pricetaxtotal | 明细.应付金额 | 是 | `appliedAmount`(2 位小数) | 含税应付金额 = 申请付款金额 | +| project_number | 项目.项目编码 | 是 | 复用 `bfiProjectNumber`:`projectId` → `ProjectApply.projectCode`,无项目传 `999` | | +| awrp_entry_code | 外部系统来源分录标识 | 是 | `paymentNo + "-1"` | 候选键;②下推时以 `awrp_finapbill_entryid` 关联此行 | +| e_remark | 明细.备注 | 否 | `remark` | | + +未传:planentity 付款计划(不传由金蝶按明细自动汇总)、e_amount/e_tax、taxrateid_number、awrp_src_con_eno。 + +### 4.3 A103-1 主表(`BfiPayApplyPushDTO`) + +| 接口字段 | 含义 | 必填 | 来源 | 说明 | +| --- | --- | --- | --- | --- | +| awrp_src_code / awrp_src_sys | 来源单据号/外部系统编号 | 是 | `paymentNo` / 配置 `payApply.srcSys` | 付款申请单候选键 | +| applydate | 申请日期 | 是 | `applyDate`(空取当天) | 同 bizdate 格式 | +| applycause | 请款事由 | 否 | 复用 `bfiApplyCause` | 结算付款 → `结算付款申请` | +| payorg_number / purorg_number | 付款/采购组织.编码 | 否 | 同 A102-2 合同组织编码 | 传值更稳,不传金蝶按应付单自动带出 | +| exratetable_number / exratedate | 汇率表/汇率日期 | 否 | 配置复用 / 同 applydate | 不传金蝶自动带出 | +| awrp_textfield1 | 付款渠道 | 否 | 复用 `bfiPaymentMethodLabel`:`paymentMethod` 经字典 `pay_method` 翻译为标签 | | +| creator_name | 申请人 | 否 | `applicantName` | | + +### 4.4 A103-1 分录(`BfiPayApplyPushEntryDTO`,固定 1 行) + +| 接口字段 | 含义 | 必填 | 来源 | 说明 | +| --- | --- | --- | --- | --- | +| e_paymenttype_number | 付款类型.编码 | 是 | 常量 `201` | 正式付款 | +| awrp_finapbill_entryid | 结算单分录id | 是 | `paymentNo + "-1"` | **对应 A102-2 明细 awrp_entry_code** | +| awrp_entry_code | 对方唯一行 id | 是 | `paymentNo + "-1"` | 不得重复 | +| e_assacct | 往来账户 | 是 | `bankAccount` | 收款账号(页面"收款账户") | +| e_bebank_number | 往来银行.编码 | 是 | `bankName` | **必填编码,当前暂传银行名称,待银行档案编码映射**(与 A103-3 遗留项一致) | +| e_applyamount | 申请金额 | 是 | `appliedAmount`(2 位小数) | | +| e_expaydate | 期望付款日 | 否 | 同 applydate | | +| project_number | 项目.项目编码 | 是 | 复用 `bfiProjectNumber` | 无项目传 `999` | +| awrp_src_type | 外部单据类型 | 是 | 复用配置 `payApply.srcType` | | +| e_remark | 备注 | 否 | `remark` | | + +未传:e_duedate、e_settlementtype_number、e_costcenter_number、awrp_splb_number。 + +--- + +## 5. 常量与待确认清单 + +### 5.1 设计约定 + +A102-2 所需的金蝶侧固定档案编码**不进 Nacos 配置**,统一定义在常量类 `org.springblade.transport.constant.KingdeeBfiConstant`;金蝶侧确认取值后**直接改常量重新发包**即可。 + +### 5.2 常量清单(`org.springblade.transport.constant.KingdeeBfiConstant`) + +| 常量 | 当前值 | 用途 | 状态 | +| --- | --- | --- | --- | +| BFI_AP_BILL_BILLTYPE_NAME | `服务采购应付` | A102-2 单据类型默认名称,经 `AP_BILL_BILLTYPE_MAP` 转换为编码(`ApFin_service_BT_S`) | 待金蝶确认 | +| AP_BILL_BILLTYPE_MAP | 9 项映射 | 财务应付单类型字典(借贷项调整/费用采购应付/其他应付/产品委外应付/标准采购应付/采购费用应付/销售费用应付/服务采购应付/资产采购应付) | 全量字典 | +| AR_BILL_BILLTYPE_MAP | 5 项映射 | 财务应收单类型字典(借贷项调整/其他应收/销售费用应收/服务销售应收/标准销售应收),当前付款链路未启用 | 全量字典 | +| PAY_APPLY_BILLTYPE_MAP | 2 项映射 | 付款申请单类型字典(采购付款申请/其他付款申请),使用规则待业务确认 | 全量字典 | +| BFI_AP_BILL_PAY_PROPERTY | `2001` | A102-2 款项性质 | 待金蝶确认 | +| BFI_AP_BILL_PUR_MODE | `CREDIT` | A102-2 付款方式(赊购) | 待业务确认(CASH=现购自动推付款) | +| BFI_AP_BILL_MATERIAL | 空串 | A102-2 明细物料编码 | **待金蝶提供,为空时推送前拦截报错** | +| BFI_AP_BILL_MEASURE_UNIT | 空串 | A102-2 明细计量单位 | **待金蝶确认,为空时推送前拦截报错** | +| BFI_AP_BILL_SRC_TYPE | `TMS财务应付单` | A102-2 外部单据类型 | 待金蝶确认 | + +### 5.3 单据类型路由与映射转换 + +| 正式结算单结算类型 | 对应金蝶单据 | 单据类型字典 | 当前状态 | +| --- | --- | --- | --- | +| 应付(payable) | 财务应付单(A102-2 `/ap_finapbill/save`) | `AP_BILL_BILLTYPE_MAP`(9 项) | **已启用**,默认"服务采购应付" | +| 应收(receivable) | 财务应收单(A302-2 `/ar_finarbill/save`) | `AR_BILL_BILLTYPE_MAP`(5 项) | 未启用,同步时拦截报错,推送规则待业务确认 | + +转换流程:同步时按 `settlementId` 查正式结算单 `settlementType` 路由;应付走 A102-2,billtype 由默认名称"服务采购应付"经映射字典转编码;查不到结算单(聚合多结算单场景)暂按应付处理。 + +### 5.4 其他待确认项(代码内以 TODO 注释标注) + +| 项 | 现状 | 待确认内容 | +| --- | --- | --- | +| 日期格式 | bizdate/applydate 沿用 A103-3 的 `yyyyMMdd` | 金蝶若校验 `yyyy-MM-dd` 需统一调整 | +| 结算方式/税率 | settlementtype_number、taxrateid_number 不传 | 金蝶是否强制、编码取值 | +| 预付抵扣 | preentry(y_billtype/y_billid/y_settleamt)不传 | 存在预付款抵扣时是否需传,本期不传、后续迭代 | +| 银行编码 | e_bebank_number 暂传银行名称 | 必填编码,待银行档案编码映射(与 A103-3 遗留项相同) | +| 付款申请单/收入确认单类型映射 | 字典已存 `PAY_APPLY_BILLTYPE_MAP`(2 项);收入确认单(ar_revcfmbill_*)字典未入库 | 付款申请单、收入确认单的映射使用规则待业务确认 | + +--- + +## 6. 数据库变更 + +**本次无表结构变更。** A103-1 返回的付款申请单 id 仍落既有字段 `blade_payment_application.kingdee_bill_no`;A102-2 返回的应付单 id 不落库(下推关联、幂等重推均不依赖该 id),后续 A102-4 勾稽、应付单附件上传、反审核删除等场景需要时,按防重键 `awrp_src_sys + awrp_src_code(=paymentNo)` 经 `queryApBill` 查询即可。前端列表也无新增列。 + +--- + +## 7. 异常处理与批量语义 + +| 场景 | 行为 | +| --- | --- | +| 单笔同步 `syncKingdee` | 校验失败/推送失败置 `failed` 并抛 `ServiceException`,前端提示原因(含金蝶 errors 明细) | +| ①成功②失败 | `kingdeeStatus = failed`;重推时①按防重键走更新语义,继续② | +| 批量同步 `syncKingdeeBatch` | 逐单循环,**单条失败不中断批次**;返回结果列表附 `付款申请[id]同步失败:原因` | +| 物料/计量单位常量为空 | 推送前拦截,报错提示待金蝶侧确认补常量 | +| 金蝶接口级失败 | `BfiServiceImpl.commonCall` 抛 `BfiException`,同上处理 | +| 重复点击同步 | 已 `synced` 单据跳过;`failed`/`unsynced` 允许重推 | + +--- + +## 8. 遗留事项 + +1. **物料/计量单位编码**:A102-2 明细必填,待金蝶侧提供后补充 `BFI_AP_BILL_MATERIAL` / `BFI_AP_BILL_MEASURE_UNIT` 常量,在此之前正式付款同步会主动拦截报错。 +2. **应付单 id 不落库**:A102-2 仅校验保存成功;后续 A102-4 勾稽、应付单附件、反审核删除等需要 id 的场景,按防重键经 `queryApBill` 二次查询。 +3. **银行编码映射**:e_bebank_number 暂传银行名称,待建立银行档案编码映射(与预付款路径遗留项相同)。 +4. **预付抵扣 preentry**:正式付款涉及预付款抵扣时是否传预付信息,本期不传、后续迭代。 +5. **付款完成模拟待拆除**:同步成功后仍保留 `paidAmount = 申请金额`、`mockPaymentRecords()` 模拟付款记录(单号前缀 `MOCK-PAY-`),真实流程应由 A103-2/A103-4 定时回写驱动,与预付款路径共用该遗留项。 +6. **正式结算单同步金蝶仍为 mock**:`FormalSettlementServiceImpl.syncKingdee` 当前仅生成 `K3AP+时间戳` 假单号,与本文档的应付单推送(A102-2)无关联,后续如需结算单直推应付单需另行设计。 +7. **单据编号 number**(AP/FKSQ-xxxx)暂未落库,如需展示可经 A102-4/A103-2 查询。 +8. **单据类型映射规则待确认**:付款申请单(采购/其他)、收入确认单(ar_revcfmbill_*)的类型使用规则待业务确认;应收结算单对应财务应收单(A302-2)的推送链路未启用,当前同步时拦截报错。 + +--- + +## 9. 涉及代码位置 + +| 内容 | 位置 | +| --- | --- | +| 同步入口/分支 | `blade-service/blade-transport/.../service/impl/PaymentApplicationServiceImpl.java`(syncKingdee / syncKingdeeBatch / pushBfiApBill / pushBfiPayApplyPush / pushBfiPayApply / requireBfiSaveSuccess / requireBfiBillId) | +| A102-2 常量 | `blade-service/blade-transport/.../constant/KingdeeBfiConstant.java` | +| Controller | `blade-service/blade-transport/.../controller/PaymentApplicationController.java`(/sync-kingdee、/sync-kingdee-batch,本次无改动) | +| BFI 客户端 | `blade-third-party-api/blade-bfi-api/.../feign/IBfiClient.java`(AP_BILL_SAVE_URL / PAY_APPLY_PUSH_URL) | +| BFI 服务封装 | `blade-third-party-api/blade-bfi-api/.../service/impl/BfiServiceImpl.java`(saveApBill / pushPayApply,本次无改动) | +| 请求/返回模型 | `blade-bfi-api/.../pojo/dto/BfiApBillSaveDTO.java`、`BfiApBillSaveEntryDTO.java`、`BfiPayApplyPushDTO.java`、`BfiPayApplyPushEntryDTO.java` | +| 前端页面 | `tms-erp-web/src/views/payment/payment-application.vue`(无逻辑改动);`src/option/payment/paymentApplication.js`(无改动) |