✨ 合并收款认领合规推送,金蝶实际付款后再同步履约

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-11-04 16:44:46 +08:00
47 changed files with 2262 additions and 1038 deletions
@@ -0,0 +1,289 @@
# 履约计划与履约记录业务说明(付款 / 开票 / 收票 / 收款)
> 适用对象:合同、结算、付款、开票、收票相关业务人员
> 更新日期:2026-10-29
> 用途:说明 TMS 与合同合规系统之间「履约计划」「履约记录」是怎么产生、什么时候产生、先后顺序和注意事项。
---
## 一、先看懂三个概念
| 概念 | 通俗理解 | 举例 |
| --- | --- | --- |
| **合同** | 业务发生的前提 | 与承运商签的运输合同、与客户签的运输服务合同 |
| **履约计划** | 合同约定的**收付款计划台账**(打算收/付多少钱、什么时候收/付) | 合同约定进度款 100 万,分几次结算 |
| **履约记录** | 计划实际执行的**流水**(真正付了、收了、开了票、收了票) | 本次实际付款 30 万、本次认领收款 20 万 |
一句话记住:**计划是“打算”,记录是“实际发生”**。先有计划,才有记录;记录必须挂在某一条计划下面。
---
## 二、总体流程
```
合同审批通过
↓
生成 / 确认履约计划(付款计划、收款计划)
↓
合同与计划推送到合规系统(合规侧生成对应的计划编号)
↓
业务实际发生:付款 / 收款 / 开票 / 收票
↓
系统自动生成履约记录,回传合规系统
```
关键顺序:
1. **合同先推合规**;
2. **履约计划再推合规**;
3. **计划推送成功后,履约记录才能生成**。
如果合同还没推合规,或者计划还没推成功,记录会暂时生成不了,等前面的步骤完成后自动补上(收款场景除外,见第六节)。
---
## 三、履约计划是怎么来的
### 3.1 计划从哪来
| 来源 | 说明 |
| --- | --- |
| 合同里维护「履约规则」 | 业务人员在合同页签里填写付款/收款计划行 |
| 合同审批通过自动生成 | 合同没有维护计划行时,系统自动补一条默认计划:承运商合同生成付款计划,客户合同生成收款计划 |
| 业务发生自动累加 | 付款审批通过、收款认领后,计划金额自动累加 |
### 3.2 计划金额什么时候变
| 业务动作 | 计划金额变化 |
| --- | --- |
| 付款申请**审批通过** | 对应付款计划的金额 += 本次申请金额(本地记账,**金蝶实际付款后**才同步到合规) |
| 收款流水**认领完成** | 对应收款计划的金额 += 本次认领分摊金额 |
请注意:
- 计划金额是**“已批准 / 已认领”的口径**,不是实际到账/实付口径;
- 实际付了多少、收了多少,看履约记录;
- 付款计划只在款项性质一致时累加(预付款不会加到进度款计划上);
- 同一合同多次付款、多次认领,计划金额会持续累加。
### 3.3 计划的修改
- 合同审批通过后,已推送成功的计划行再修改,系统会自动重新推送合规;
- 删除已推送的计划行,会在合规侧同步删除(不能直接物理删除);
- 新增的计划行随下一次推送一起补到合规。
---
## 四、四个场景的履约记录
### 4.1 付款履约记录
**什么时候产生:金蝶实际付款之后。**
业务过程:
```
付款申请审批通过
→ 本地累加计划金额(暂不同步合规),不产生履约付款记录
→ 推送金蝶付款申请
金蝶完成实际付款
→ 系统回写实付金额
→ 计划金额同步到合规 + 生成履约付款记录
```
业务要点:
| 项目 | 说明 |
| --- | --- |
| 生成条数 | 一张付款申请对应一条;**分次付款不新增,只更新同一条的实际金额** |
| 金额 | 申请金额 + 实际付款金额 |
| 日期 | 付款申请日期 |
| 附件 | 付款场景会把付款附件一并传到合规 |
| 特批 | 需要特批的付款,特批通过后也不会立刻生成记录,仍要等金蝶实际付款 |
> 常见误区:付款审批通过后就去合规找履约付款记录——此时还没有,属于正常现象,金蝶付款后才会出现(付款计划金额的累加同样是金蝶实际付款后才同步到合规)。
---
### 4.2 收款履约记录
**什么时候产生:收款流水认领完成之后。**
业务过程:
```
收款流水到账并同步到 TMS
→ 业务人员做认领(分摊到应收结算单)
→ 认领提交后,系统自动:
① 更新该合同的收款计划金额
② 推送认领记录到合规
③ 生成收款履约记录
```
业务要点:
| 项目 | 说明 |
| --- | --- |
| 生成条数 | 每完成一次认领,按涉及的合同各生成一条 |
| 金额 | **本次认领分摊到该合同的金额**(不是合同累计认领金额) |
| 日期 | 认领日期 |
| 作废 | 认领作废只会在合规侧把认领记录置为作废,**不会冲回计划金额,也不会冲回已生成的履约记录** |
> 注意:收款链路的推送失败**不会自动重试**,如合规侧没有数据,请联系系统管理员排查。
---
### 4.3 开票履约记录
**什么时候产生:金蝶开票完成、发票回到 TMS 之后。**
业务过程:
```
开票申请审批通过
→ 推送金蝶开票
→ 推送合规开票登记(此时还没有发票日期)
金蝶完成开票
→ 系统回写发票信息(每张发票一条)
→ 按每张发票生成履约开票记录
```
业务要点:
| 项目 | 说明 |
| --- | --- |
| 生成条数 | **每张发票一条**;一张开票申请开多张发票,就会生成多条 |
| 金额 | 发票价税合计 |
| 日期 | 发票的开票日期 |
| 标题 | `开票履约-发票号`,可在合规侧按此检索 |
| 失败处理 | 合同或计划条件不满足时暂不生成,系统自动重试,条件满足后补上 |
---
### 4.4 收票履约记录
**什么时候产生:收票单成功推送合规之后。**
业务过程:
```
收票登记审批通过
→ 推送金蝶收票单
→ 推送合规收票单(C109)
→ 推送成功后,按收票单里的每条结算信息生成履约收票记录
```
业务要点:
| 项目 | 说明 |
| --- | --- |
| 生成条数 | **每条结算信息(分摊行)一条**;一张收票单分摊到多张结算单就会生成多条 |
| 金额 | 分摊到该结算单的收票金额 |
| 日期 | 收票单的发票日期 |
| 标题 | `收票履约-发票号-结算单号` |
| 失败处理 | 收票单还没成功推合规时暂不生成,等收票单推送成功后自动补上 |
---
### 4.5 四场景速查
| 场景 | 什么时候出现 | 生成条数 | 金额口径 | 日期口径 |
| --- | --- | --- | --- | --- |
| 付款 | 金蝶实际付款后 | 一张付款申请一条(分期更新同一条) | 申请金额 / 实付金额 | 申请日期 |
| 收款 | 认领提交后 | 每次认领 × 每个合同一条 | 本次认领分摊金额 | 认领日期 |
| 开票 | 金蝶开票完成后 | 每张发票一条 | 发票价税合计 | 发票开票日期 |
| 收票 | 收票单推合规成功后 | 每条结算分摊行一条 | 分摊收票金额 | 发票日期 |
---
## 五、合规侧怎么核对
在合规系统履约记录列表中,按标题前缀检索最快:
| 场景 | 标题前缀 |
| --- | --- |
| 付款 | `付款履约-` |
| 收款 | `收款履约-` |
| 开票 | `开票履约-` |
| 收票 | `收票履约-` |
核对时重点看四项:**合同是否正确、金额是否正确、日期口径是否符合上表、条数是否与业务动作匹配**。
---
## 六、异常与重试
| 场景 | 推送失败后是否自动重试 | 业务需要做什么 |
| --- | --- | --- |
| 付款 | 是,系统定时自动重试 | 一般无需处理;长期失败联系管理员 |
| 开票 | 是,系统定时自动重试 | 确认金蝶是否已开票完成;长期失败联系管理员 |
| 收票 | 是,系统定时自动重试 | 先确认收票单是否已成功推送合规 |
| 收款 | **否** | 联系系统管理员手动排查处理 |
常见“暂时生成不了”的原因:
1. 合同还没推送合规;
2. 履约计划还没推送成功(没有可关联的计划);
3. 对应单据还没审批通过;
4. 收票单还没成功推送合规;
5. 金蝶还没实际付款 / 还没完成开票。
前四类在条件满足后会自动补推,不需要重复操作单据。
---
## 七、作废、驳回与变更
| 业务动作 | 对合规履约数据的影响 |
| --- | --- |
| 付款审批驳回 | 不产生履约付款记录 |
| 付款需要特批 | 特批期间不产生履约数据;特批通过后也要等金蝶实际付款 |
| 付款申请作废 | 当前**不会冲回**已累加的计划金额,也不会冲回履约付款记录 |
| 收款认领作废 | 合规侧认领记录作废;**计划金额与收款履约记录不冲回** |
| 合同变更审批通过 | 计划行随变更重新推送合规,已生成的履约记录不受影响 |
> 如业务上需要“作废后金额必须回退”,请单独提需求或在合规侧人工调整,不能依赖当前自动链路。
---
## 八、常见问题(FAQ)
**1. 合同刚审批通过,合规为什么没有履约记录?**
正常。此时只有履约计划,记录要等业务实际发生(付款、收款、开票、收票)后才生成。
**2. 付款已经审批通过了,合规为什么没有付款履约记录?**
正常。付款履约记录以**金蝶实际付款**为准,审批通过只更新计划金额。
**3. 同一笔付款分两次支付,合规会出现两条记录吗?**
不会。一张付款申请对应一条记录,第二次付款更新实际金额。
**4. 同一笔收款分多次认领,合规会出现几条?**
每次认领都会生成一条(按涉及合同分别生成),金额为本次分摊金额。
**5. 一张开票申请开了多张发票,合规有几条?**
每张发票一条。
**6. 收票单有多条结算信息,合规有几条?**
每条结算信息一条。
**7. 合规侧一条记录都没有,先查什么?**
按顺序确认:合同是否已推合规 → 履约计划是否已推成功 → 单据是否已审批通过 →(开票)金蝶是否已开票完成 →(收票)收票单是否已推合规。收款链路不会自动重试,需联系管理员。
**8. 计划金额和履约记录金额为什么对不上?**
两者口径不同:计划金额是“已批准/已认领”的累计口径,履约记录是“本次实际发生”的口径。付款场景下,计划看申请金额,记录看实付金额。
**9. 作废后合规金额为什么没变?**
当前作废不回冲计划金额和履约记录,需要在合规侧人工处理或单独提需求。
---
## 附录:业务名称与合规接口对照(供对接同学参考)
| 业务名称 | 合规接口 |
| --- | --- |
| 合同推送 | C103-1 / C103-11 |
| 履约计划推送 | C103-9 |
| 付款履约记录 新建 / 更新 | C108-1 / C108-2 |
| 收款认领记录 新增 / 作废 | C107-1 / C107-3 |
| 开票登记 | C111 |
| 收票单推送 | C109 |
@@ -0,0 +1,317 @@
# 履约计划与履约记录四场景实现逻辑(付款 / 开票 / 收票 / 收款)
> 日期:2026-10-29
> 范围:`tms-api` blade-transport 中 TMS ↔ 合同合规系统(HCS)的「履约计划」(C103-9)与「履约记录」(C108-1/2)。
> 目标:只讲清**逻辑、流程、先后顺序**,不展开代码细节。
---
## 0. 总览
一句话:**履约计划是合同资金的“计划行”,履约记录是这些计划行的“实际发生流水”**。计划先行(先拿到 HCS 阶段ID),记录才能引用它;四个业务场景(付款/收款/开票/收票)各自在“业务真正发生”的时点产生一条或多条履约记录。
### 0.1 全景顺序
```
合同审批通过
└─ 建默认履约计划行 → 推合同 C103-1(拿合同 hcs_fd_id)
└─ 推履约计划 C103-9(拿计划 hcs_exeplan_id + 每行 hcs_stage_fd_id)
├─ 付款:审批通过 → 计划金额本地累加(不推合规) → 金蝶实际付款 → C103-9 重推 + C108-1/C108-2
├─ 收款:认领提交 → 计划金额累加 → C107-1 → C108-1
├─ 开票:金蝶开票完成、发票落库 → C111 登记 → 每张发票 C108-1
└─ 收票:收票单推合规 C109 成功 → 每条结算分摊行 C108-1
```
### 0.2 四条链的关键先后关系
| 场景 | 前一条链必须先完成 | 履约记录产生时点 | 记录粒度 |
| --- | --- | --- | --- |
| 付款 | C103-1 拿到 `hcs_fd_id`;C103-9 计划行拿到 `hcs_stage_fd_id` | **金蝶实际付款后**(`paidAmount>0` 且金额推进) | 付款申请单(1 张单 1 条,分期走更新) |
| 收款 | 同上,且收款计划行已同步 | **认领事务提交后** | 认领主单 × 合同(每次认领各 1 条) |
| 开票 | 合同/收款计划行已同步;金蝶 A303-5 发票已落库 | **金蝶开票完成后** | 每张发票 1 条 |
| 收票 | 合同/付款计划行已同步;**C109 收票单已推合规成功** | **C109 推送成功后** | 每条结算分摊行 1 条 |
---
## 1. 两个对象与 ID 链
| 对象 | TMS 落点 | HCS 接口 | 作用 |
| --- | --- | --- | --- |
| 履约计划行 | `blade_contract_exe_stage`(`HcsContractExeStage`) | C103-9 行级 add/update/delete | 合同维度的付款/收款资金计划 |
| 履约记录 | 各业务表上的 `hcs_perf_fd_id` | C108-1 新建 / C108-2 更新 | 计划的实际执行流水 |
必须持久化的 ID 链(后面所有推送都依赖它):
```
blade_contract_manage.hcs_fd_id 合规合同ID(C103-1)
blade_contract_manage.hcs_exeplan_id 合规履约计划ID(C103-9)
blade_contract_exe_stage.hcs_stage_fd_id 合规阶段ID(C103-9 按行回填,= C108 的 fd_plan_id)
blade_payment_application.hcs_perf_fd_id 付款履约记录ID(C108-1 返回)
blade_invoice_application_invoice.hcs_perf_fd_id 开票履约记录ID
blade_invoice_receipt_settlement.hcs_perf_fd_id 收票履约记录ID
blade_receipt_claim_hcs_record.hcs_claim_record_fd_id C107-1 认领记录ID(供 C107-3 作废)
```
`fd_plan_id` 在 C108 接口中**必填**,只能取 HCS 自己返回的 `hcs_stage_fd_id`。因此没有已同步计划行时,履约记录一律推不出去,只能失败重试,等合同链把计划补推成功后自愈。
---
## 2. 履约计划(C103-9)
### 2.1 计划行从哪来
| 入口 | 行为 |
| --- | --- |
| 合同表单「履约规则」页签维护(`ContractExeStageServiceImpl#submitRows/removeRow`) | 新行 → `row_op=add`;已同步行编辑 → `update`;已同步行删除 → 软删 + `delete` 标记(不能物理删,delete 要凭阶段ID 上报) |
| 合同审批通过(`createDefaultRowOnApprove`) | 无任何计划行时自动建默认行:承运商合同=付款/进度款,客户合同=收款/进度款;同时把该合同所有未拿到阶段ID 的行统一置 `add` |
| 付款审批通过(`accumulatePaidAmountOnApprove`) | 按付款类型映射款项性质(正式结算=进度款,其余=预付款),对**精确匹配**该款项性质的已同步付款行,原子累加 `fund_amount += 申请金额`,并置 `update + unsynced` |
| 收款认领(`accumulateClaimedAmountOnPush`) | 取收款/进度款计划行(无进度款则兜底首条已同步收款行),累加本次分摊到该合同的认领金额,置 `update + unsynced` |
要点:
- 金额累加只发生在“审批通过/认领提交”,**不是**在实际收付款时;因此计划金额反映的是“已批准/已认领的计划口径”,履约记录才反映实际发生额。
- 付款累加严格要求款项性质一致,匹配不到就跳过,避免预付款计进进度款;收款累加允许兜底行。
- 已同步行靠 `hcs_stage_fd_id` 重推;未同步行保持 `add`,随合同链首推(首次推送即携带累加后的金额)。
### 2.2 同步逻辑(`HcsExeStageSyncSupport#syncExeStages`)
1. 前置:合同必须有 `hcs_fd_id`。
2. 取该合同所有 `row_op <> 'none'` 的行;删除行已软删,用原生 SQL 绕过逻辑删除才能取到。
3. 整体操作类型:`hcs_exeplan_id` 为空 → `add`(首次),否则 `update`。
4. 行级:`add` 行带 `fdUniqueId=TMS行ID`(重试稳定);`update/delete` 行必须带 `fdId=hcs_stage_fd_id`。
5. 响应回填:回填 `hcs_exeplan_id`、逐行回填 `hcs_stage_fd_id`,清 `row_op`、置 `synced`;`add` 行没匹配到阶段ID → 置 `failed`,下轮重试。
### 2.3 三个触发入口(谁调 C103-9)
| 入口 | 位置 | 门禁 | 说明 |
| --- | --- | --- | --- |
| 合同链 | `HcsContractSyncSupport#pushContract` 第⑤步 | `exe-stage.sync-enabled` | 合同起草/更新成功后、特批挂起前同步计划 |
| 付款链 | `HcsPaymentSyncSupport#pushPayment` 第③步 | `exe-stage.sync-enabled` | **金蝶实际付款门禁通过后**重推计划(审批通过仅本地累加金额不推送),再推履约记录 |
| 收款链 | `HcsClaimSyncSupport#pushOneContract` 第①步 | `exe-stage.sync-enabled` | 先累加并重推计划,再推 C107-1/C108-1 |
> 合同还没推合规时,计划行只做本地标记/累加,不报错,等合同链首推时一并带上。
---
## 3. 履约记录(C108)
### 3.1 公共前置与公共字段
所有场景的 C108-1 都要求:
- 合同已推合规(`hcs_fd_id` 非空);
- 存在已同步计划行(`hcs_stage_fd_id` 非空):付款/收票取**付款**计划行,收款/开票取**收款**计划行;
- `perf-record.sync-enabled` 开启;
- `fd_plan_id`/`fd_id` = 计划行 `hcs_stage_fd_id`,`fd_property` = 计划行款项性质。
四个场景的差异主要在:**触发时点、粒度、金额、履约日期、类型、幂等键**。
### 3.2 付款(`HcsPaymentSyncSupport` + `HcsPerfRecordSyncSupport`)
```
付款申请审批通过
→ hcs_sync_status=unsynced;计划金额本地累加(row_op=update,不推合规)
→ 即时推送/扫描:paidAmount=0 → 履约计划与履约记录均不推送
(提示“金蝶未实际付款”),整体仍置 synced
金蝶实际付款 → A103-2 回写(applyPayApplyResult)
→ paidAmount 首次>0 或金额变化 → hcs_sync_status=unsynced
→ 扫描付款任务:先 C103-9 重推累加金额的计划行
无 hcs_perf_fd_id → C108-1 新建,返回 fdId 立即落库
有 hcs_perf_fd_id → C108-2 更新(分期付款推进实际金额)
```
- 金额:申请金额=`appliedAmount`,实际金额=`paidAmount`。
- 日期:申请日期(`applyDate`)。
- 类型:`付款`。
- 幂等:单据粒度,`hcs_perf_fd_id` 决定新建还是更新;金额不变不会重复触发。
- 附件:仅付款场景保留附件转传(C103-2 → `fd_plan_att`),其余场景传空列表。
- 特批:`need` 发起 C106-3 后挂起;特批通过后**不补推任何履约数据**,只恢复审批并补推金蝶;驳回不产生履约数据。
### 3.3 收款(`HcsClaimSyncSupport`)
```
认领登记(只登记本地,不推金蝶)
→ 事务提交后 afterCommit → pushClaimToHcs(claimId)
① 按“本次分摊到该合同”的金额累加收款计划行 → C103-9 重推
② C107-1 认领记录(认领主单 × 合同一条,金额=本次分摊额)
③ C108-1 履约流水(同一粒度:认领主单 × 合同一条)
```
- 触发点:**认领事务提交后**,不是金蝶回调。
- 前置:`exe-stage.sync-enabled` 为整条链总门禁;C108-1 另受 `perf-record.sync-enabled` 门禁。
- 定位合规流水:C104-2 按明细流水号查出合规收款流水ID;查不到只跳过 C107-1,不影响计划更新。
- 金额:本次认领分摊到该合同的金额(申请金额=实际金额)。
- 日期:认领日期(当前代码 `claim.claimDate`)。
- 类型:当前代码传的是 `collection`(见第 6 节差异说明)。
- 幂等/重试:事件驱动、**无定时重试**;C108-1 返回的 fdId 未落库(无 C108-2 场景),失败只记日志。
- 作废:只推 C107-3 把 C107-1 记录置为已作废;**不回冲计划金额、不回冲履约记录**。
### 3.4 开票(`HcsInvoicePerfSyncSupport`)
```
开票申请审批通过 → 推金蝶 A303-1 → 推合规 C111 开票登记(票据日期为空)
金蝶开票完成 → A303-5 回写:发票逐张落库;申请单置 invoiced + hcs_sync_status=unsynced
扫描开票任务(同一轮):
① C111 推送/回填票据日期
② 履约开票记录:扫描 hcs_perf_fd_id 为空且未超重试上限的发票
申请单须审批通过
合同回溯:开票申请 → 应收结算关联 → 正式结算单 → 合同
每张发票一条 C108-1
```
- 金额:发票价税合计 `invoiceAmount`。
- 日期:发票完成开票日期 `invoiceDate`。
- 类型:`开票`。
- 申请编号:发票号;标题:`开票履约-{发票号}`。
- 幂等:发票粒度,`hcs_perf_fd_id` 非空即跳过;失败 `retry+1` + 原因,下轮补偿,超上限人工处理。
- 合同回溯不到、无已同步收款计划行 → 记失败原因,等条件满足后自愈。
### 3.5 收票(`HcsReceiptPerfSyncSupport`)
```
收票单审批通过 → 推金蝶收票单(A303-2 + A302-6)
扫描收票任务(同一轮):
① C109 收票单推送合规 → 成功置 hcs_sync_status=synced
② 履约收票记录:扫描 hcs_perf_fd_id 为空且未超重试上限的分摊行
所属收票单须审批通过且 hcs_sync_status=synced(C109 必须先成功)
合同回溯:分摊行 → 正式结算单 → 合同
每条结算分摊行一条 C108-1
```
- 金额:分摊收票金额 `allocatedInvoiceAmount`,为空兜底结算金额。
- 日期:收票单发票日期 `invoiceDate`。
- 类型:`收票`;关联**付款**计划行。
- 申请编号:`{发票号}-{结算单号}`;标题:`收票履约-{申请编号}`。
- 幂等:分摊行粒度,`hcs_perf_fd_id` 非空跳过;C109 未成功时记“尚未推送合规”,成功后下轮自动补偿。
### 3.6 四场景对照
| 维度 | 付款 | 收款 | 开票 | 收票 |
| --- | --- | --- | --- | --- |
| 触发时点 | 金蝶实际付款回写后 | 认领事务提交后 | 金蝶开票完成、发票落库后 | C109 推送成功后 |
| 粒度 | 付款申请单 | 认领主单 × 合同 | 每张发票 | 每条结算分摊行 |
| 申请金额 | 申请金额 | 本次分摊金额 | 发票价税合计 | 分摊收票金额 |
| 实际金额 | 实付金额 | 同申请金额 | 同申请金额 | 同申请金额 |
| 履约日期 | 申请日期 | 认领日期 | 发票开票日期 | 发票日期 |
| 类型 | 付款 | collection(现状) | 开票 | 收票 |
| 计划行 | 付款(按款项性质) | 收款(进度款优先) | 收款(进度款优先) | 付款(进度款优先) |
| 幂等键 | `hcs_perf_fd_id`(可更新) | 无(每次认领新建) | `hcs_perf_fd_id` | `hcs_perf_fd_id` |
| 失败重试 | 定时扫描 | 无 | 定时扫描 | 定时扫描 |
| 更新接口 | C108-2 支持 | 不支持 | 不支持 | 不支持 |
---
## 4. 端到端时序(先后顺序)
### 4.1 计划必须先于记录
```mermaid
sequenceDiagram
participant C as 合同
participant H as HCS
participant B as 业务单据(付款/认领/发票/收票)
C->>H: C103-1 合同起草
H-->>C: hcs_fd_id
C->>H: C103-9 履约计划(add)
H-->>C: hcs_exeplan_id + 每行 hcs_stage_fd_id
Note over C,H: 阶段ID 落库后,下面四条链才有 fd_plan_id
B->>H: C108-1 履约记录(fd_plan_id=阶段ID)
```
### 4.2 付款链
```mermaid
sequenceDiagram
participant P as 付款申请
participant H as HCS
participant K as 金蝶
P->>P: 审批通过:计划金额+=申请金额
P->>H: C103-9 重推计划
P->>P: paidAmount=0,跳过 C108
K-->>P: 实际付款回写(paidAmount 变化)
P->>H: C108-1(首次)/ C108-2(分期)
```
### 4.3 收款链
```mermaid
sequenceDiagram
participant U as 认领
participant H as HCS
U->>U: 认领登记(本地)
U->>H: ① C103-9 累加收款计划并重推
U->>H: ② C104-2 定位合规流水 → C107-1 认领记录
U->>H: ③ C108-1 履约流水(本次分摊金额)
```
### 4.4 开票 / 收票(任务内顺序)
```
开票任务:C111 开票登记 → 发票逐张 C108-1(同一轮)
收票任务:C109 收票单 → 分摊行逐条 C108-1(同一轮,C109 必须先成功)
```
---
## 5. 定时任务与开关
| 任务 | 默认 cron | 内容 |
| --- | --- | --- |
| contract | `0 1/5 * * * ?` | C103-1/C103-11 → C103-9 |
| payment | `0 2/5 * * * ?` | C106 特批 →(金蝶实际付款后)C103-9 → C108-1/2 |
| invoice-application | `0 3/5 * * * ?` | C111 → 履约开票 C108-1 |
| invoice-receipt | `0 4/5 * * * ?` | C109 → 履约收票 C108-1 |
| 收款 | 无独立任务 | 认领事务提交后事件驱动 |
| 配置(`thirdParty.hcs.*`) | 作用 | 默认 |
| --- | --- | --- |
| `exe-stage.sync-enabled` | C103-9 总开关;同时门禁整条收款链 | true |
| `perf-record.sync-enabled` | 四场景履约记录总开关 | false |
| `perf-record.xform-id` | C108 表单模板ID | 空 |
| `push.payment/invoice-application/invoice-receipt.sync-enabled` | 各任务开关 | false |
| `push.max-retry` / `push.batch-size` | 重试上限 / 单轮批量 | 5 / 配置值 |
| `attachment.transfer-enabled` | 付款履约记录附件转传 | true |
手动入口:`POST /hcs/sync/{bizType}` 批量扫描一轮(开票/收票为组合动作,含履约记录);`POST /hcs/sync/{bizType}/{id}` 单条重推(仅主单据,不覆盖发票/分摊行粒度)。
---
## 6. 当前实现与设计文档的差异(重要)
以下为代码实际情况,与《2026-10-27 履约计划与履约记录逻辑与流程梳理》《2026-10-28 C108 履约记录四场景推送改造流程梳理》存在出入,落地时以本节为准:
| 点 | 设计文档口径 | 当前代码 |
| --- | --- | --- |
| 收款触发 | 金蝶认领推送 A301-3 成功后 | **认领事务提交后**(认领只登记本地,不推金蝶) |
| 收款履约日期 | 收款流水交易日期 `transaction_time` | **认领日期 `claimDate`**(提交 `4a76e65b` 回退了该调整) |
| 收款履约类型 | 中文「收款」 | **`collection`**(`PERFORM_TYPE_COLLECTION`,未使用 `PERF_TYPE_COLLECTION`) |
| 收款金额 | 该合同累计认领金额 | **本次认领分摊到该合同的金额** |
| 收款组装 | 复用 `HcsPerfRecordAddSupport` | **仍为 `HcsClaimSyncSupport` 内部独立组装** |
| 付款链 C103-9 门禁 | 不受 `exe-stage` 开关限制 | **受 `exe-stage.sync-enabled` 控制** |
| 收款链 fdId | 需落库以支持后续更新 | **未落库**(无 C108-2 场景) |
| 付款作废 / 认领作废 | — | 均不回冲计划金额与履约记录(认领仅 C107-3 作废) |
建议:若确认收款需按「交易日期 + 中文类型 + 通用组件」口径,应把 `HcsClaimSyncSupport#pushPerfRecord` 切到 `HcsPerfRecordAddSupport`,并同步修正日期与类型常量;否则应同步更新设计文档,避免联调口径不一致。
---
## 7. 代码索引
| 职责 | 类 / 方法 |
| --- | --- |
| 计划行维护、差异标记、金额累加、默认行 | `ContractExeStageServiceImpl`:`submitRows` / `removeRow` / `accumulatePaidAmountOnApprove` / `accumulateClaimedAmountOnPush` / `createDefaultRowOnApprove` / `findPaymentStageRow` / `findCollectionStageRow` |
| C103-9 同步与回填 | `HcsExeStageSyncSupport#syncExeStages` |
| 付款链编排 | `HcsPaymentSyncSupport#pushPayment` |
| 付款履约记录 C108-1/2 | `HcsPerfRecordSyncSupport#pushPerfRecord` |
| 收款链编排 | `HcsClaimSyncSupport#pushClaimToHcs` / `#pushOneContract` / `#pushPerfRecord` / `#voidClaimToHcs` |
| C108-1 通用组件(开票/收票共用) | `HcsPerfRecordAddSupport#pushPerfRecordAdd` |
| 开票履约记录 | `HcsInvoicePerfSyncSupport#pushUnsyncedInvoicePerfRecords` |
| 收票履约记录 | `HcsReceiptPerfSyncSupport#pushUnsyncedReceiptPerfRecords` |
| 定时任务编排 | `HcsPushTask`:`pushHcsPayment` / `syncHcsInvoiceApplications` / `syncHcsInvoiceReceipts` |
| 审批即时推送 | `HcsImmediatePushSupport#pushPaymentAndWait / pushPaymentAfterCommit` |
| 金蝶实付回写触发 | `PaymentApplicationServiceImpl#applyPayApplyResult` |
| 认领事务提交触发 | `ReceiptFlowServiceImpl`(`afterCommit` → `pushClaimToHcs`) |
| 常量与映射 | `HcsSyncConstant`(`PERF_TYPE_*`、`PERFORM_TYPE_*`、`FUND_NATURE_*`、`fundNatureOfPayment`) |
@@ -2,6 +2,11 @@
> 日期:2026-10-16
> 范围:`tms-api` blade-transport 收款流水认领、认领记录模块;`tms-erp-web` 认领记录页面
>
> **口径变更提示(2026-10-29)**:文中"公告未认领金额 `unclaimed_amount` / A301-2 口径"已废止,见
> [2026-10-29-收款流水菜单改造](./2026-10-29-收款流水菜单改造(数据源A301-2改A301-1-认领只登记本地并推送合规C107-1与C107-3作废同步).md)。
> 现认领上限为**收款金额 `receipt_amount`(A301-1 `actrecamt`)**,`remaining_amount = max(收款金额 − 累计认领金额, 0)`;
> 金蝶未匹配金额 `unmatch_amount_rec` 仅作参考展示,不参与额度控制。认领/作废/多次认领的其余口径不变。
---
@@ -45,10 +50,10 @@ blade_kingdee_receipt_flow(收款流水 / 认领通知单,1)
1. 锁定流水(通知单)与所选结算单。
2. 校验两条累计上限:
- 每张结算单:已有累计认领 + 本次分摊 ≤ 结算总应收含税金额;
- 流水:已有累计认领(`flowClaimedAmount`,只算未作废记录)+ 本次总额 ≤ 公告未认领金额(`unclaimed_amount`,A301-2 口径)。
- 流水:已有累计认领(`flowClaimedAmount`,只算未作废记录)+ 本次总额 ≤ 收款金额(`receipt_amount`,A301-1 口径;2026-10-29 前为公告未认领金额)。
3. **插入一条** `ReceiptClaim` 主单:`claim_amount` = 本次分摊总额,`claim_status = claimed`。
4. 按所选结算单逐张**插入 N 条** `ReceiptClaimSettlement` 分摊明细。
5. 累加流水 `claimed_amount`,按累计值重算流水状态(< 未认领金额 → partial,= → claimed)。
5. 累加流水 `claimed_amount`,按累计值重算流水状态(< 收款金额 → partial,≥ 收款金额 → claimed)。
6. 只登记本地,不推送金蝶;推送由定时任务/手动按钮触发。
所以:**同一通知单第二次认领是再插一条新主单**,不存在"找已有主单合并金额"的逻辑;校验全部按"未作废记录累计"实时计算,天然支持多次认领。
@@ -69,17 +74,17 @@ canClaim(row) {
2. **剩余可认领金额 > 0**:`remainingAmount` 由后端 `ReceiptFlowWrapper` 统一计算:
```
remainingAmount = max(公告未认领金额 unclaimed_amount − 累计认领金额 claimed_amount, 0)
remainingAmount = max(收款金额 receipt_amount − 累计认领金额 claimed_amount, 0)
```
按认领状态换算:
| 流水认领状态 | remainingAmount | 认领按钮 |
| --- | --- | --- |
| unclaimed 未认领(公告金额 > 0) | = 公告未认领金额 > 0 | 显示 |
| unclaimed 未认领(收款金额 > 0) | = 收款金额 > 0 | 显示 |
| partial 部分认领 | > 0 | 显示 |
| claimed 认领完成 | = 0(累计 ≥ 公告金额) | **不显示** |
| 公告未认领金额为 0 的流水 | = 0 | **不显示** |
| claimed 认领完成 | = 0(累计 ≥ 收款金额) | **不显示** |
| 收款金额为 0 或缺失的流水 | = 0 | **不显示** |
| 无 `receipt_flow_claim` 权限 | — | **不显示** |
即:**按钮显隐只看金额余额与权限,不看认领状态字段本身**;`claimed` 状态的行因为剩余额度为 0 自然不显示按钮。按钮不显示且不满足"推送金蝶"条件时,操作列显示"-"。
@@ -20,6 +20,8 @@
> 全程交互使用中文。
![结算调整单列表:审批通过的调整单统一一个入口,未同步显示「推送金蝶」、已同步显示「重新推送(高危)」;列表带「金蝶单据状态 / 金蝶单据号」列](./2026-10-16-结算调整单接入金蝶设计(未推送自动推-已推送冲销后重推新单).assets/01-结算调整单列表-金蝶状态与推送入口.png)
## 2. 名词与接口速查
| 代号 | 含义 |
@@ -119,6 +121,8 @@
- 排除收付完成/尾款等不可调整(`adjustableFormalSettlement`,约 295);
- 保存时自动回带客商、调整类型、合同、原结算金额等。
![新增结算调整单:选定关联结算单后自动回带客商、结算单类型、合同、原结算金额,并带出原单费用明细供录入调整金额](./2026-10-16-结算调整单接入金蝶设计(未推送自动推-已推送冲销后重推新单).assets/02-新增调整单-回带结算单信息与费用明细.png)
### 6.2 选单后金蝶冲销预检(新增,软提示)
选定关联结算单号、回带信息后,前端调后端**预检接口**:
@@ -134,6 +138,8 @@
- **降级**:金蝶查询超时/不可用/接口异常时,预检返回"未校验",**不阻断**建单与回带,由后续审批分流与重推闸门兜底。
- 预检结果**只用于提示**,不作为后续环节的结论缓存:审批(操作 2)、重推(操作 3)各自按**当下**状态重新判定。
![选单后金蝶冲销预检:该结算单已推送金蝶且旧单尚未冲销时的醒目提示,仅为软提示,不阻断建单](./2026-10-16-结算调整单接入金蝶设计(未推送自动推-已推送冲销后重推新单).assets/03-新增调整单-选单后金蝶冲销预检提示.png)
> 为什么不把硬拦截放在选单:冲销是金蝶侧**不可逆/需人工撤销**的对外操作,而审批只是 TMS 内部决策。若选单即要求已冲销,会出现"旧单已冲销、调整单却被驳回/删除"的**应付单空档**(详见第 13 节)。
## 7. 操作 2|审批通过
@@ -179,6 +185,8 @@
7. **原单收尾**:标记 `adjustStatus='已调整'` + 旧锁记录置 `unlocked`;追加重推变更记录。业务字段不动。
8. **失败处理**:新单 `kingdeeSyncStatus=failed` + 失败原因,支持复用 `retryKingdeeFailed` 重试(重试即从第 4 步继续,克隆已存在则跳过,注意幂等)。
![重新推送(高危):点击后先弹高危二次确认,确认金蝶旧应付/应收单已由财务手工冲销后才真正生成新单](./2026-10-16-结算调整单接入金蝶设计(未推送自动推-已推送冲销后重推新单).assets/04-重新推送-高危二次确认.png)
## 9. 关键机制
### 9.1 防重键与新单号
@@ -34,7 +34,34 @@
- 审批中:只能"通过"或"驳回"。
- 审批通过:终态,只剩金蝶推送相关操作。
### 2.2 各状态下的按钮
### 2.2 总体流程图
```
调整单审批通过
│
原结算单金蝶状态
┌───────────────────┴────────────────────┐
▼ ▼
未推送(场景 A) 已推送(场景 B)
① 调整回写原结算单 ① 原结算单业务数据【零改动】
② 原单追加变更记录 ② 原单仅追加 1 条变更记录
③ 调整单 → 审批通过 ③ 调整单 → 审批通过
④ 自动推送金蝶 ④ 提示:请财务在金蝶手工冲销旧单
(应付/应收单 + 落锁 + 附件) 【财务在金蝶手工冲销旧单】
⑤ 回填「已同步 + 金蝶单据号」 点「重新推送(高危)」并二次确认
↓ ① 校验调整单已审批通过
金蝶应付/应收单(含调整金额) ② 旧单必须已冲销,否则拒绝
③ 克隆新正式结算单(应用调整)
④ 用新单号推金蝶 → 全新应付/应收单
⑤ 新单落锁 + 附件
⑥ 调整单改挂新单 + 回填金蝶单据号
⑦ 原单标「已调整」+ 旧锁解锁
⑧ 推送失败置「生成失败」,可重试
↓
金蝶【全新】应付/应收单(旧单已冲销)
```
### 2.3 各状态下的按钮
| 状态 | 可用操作 | 说明 |
|---|---|---|
@@ -43,7 +70,9 @@
| 审批中 | 通过 / 驳回 | 审批人操作 |
| 审批通过 | 推送金蝶 / 重新推送(合一按钮)| 按金蝶状态自动分流,高危确认 |
### 2.3 金蝶同步状态(调整单上的展示字段)
![结算调整单列表:草稿行显示「查看 / 编辑 / 删除 / 提交」,审批通过行只剩「查看」与推送类操作;金蝶状态为「已同步」时按钮变为红色的「重新推送(高危)」,未同步时为「推送金蝶」](./2026-10-17-结算调整单操作流程说明(分场景).assets/01-结算调整单列表-各状态操作入口.png)
### 2.4 金蝶同步状态(调整单上的展示字段)
| 状态 | 含义 |
|---|---|
@@ -67,6 +96,10 @@
> 预检只是提示,不拦人;真正的拦截在"重新推送"那一步。填单时必须至少录入一条调整费用,否则无法提交。
![新增调整单:选定关联正式结算单后自动回带客商、结算单类型、合同、原结算金额,并带出原单费用明细供录入调整金额](./2026-10-17-结算调整单操作流程说明(分场景).assets/02-新增调整单-选单回带与费用录入.png)
![选单后的金蝶冲销预检:该结算单已推送金蝶且旧单未冲销时,顶部弹出醒目提示"审批通过后需先由财务在金蝶完成冲销,才能重新推送",但建单不受影响](./2026-10-17-结算调整单操作流程说明(分场景).assets/03-新增调整单-金蝶冲销预检提示.png)
### 3.2 保存草稿 / 编辑 / 删除
- 草稿和已驳回的单可反复编辑;删除仅限草稿,删除后单号作废、不留痕迹。
@@ -77,6 +110,8 @@
- 草稿 / 已驳回 → 审批中,进入审批人的待办。
- 提交后单据锁定,提交人不能再改。
![提交审批:草稿行点「提交」后需二次确认,确认后单据进入审批中并锁定](./2026-10-17-结算调整单操作流程说明(分场景).assets/04-提交审批二次确认.png)
### 3.4 审批通过 ★ 核心分流点
审批人点"通过"后,系统按**原结算单是否推送过金蝶**自动走两条完全不同的路(见第四、五节场景 A / B):
@@ -102,6 +137,8 @@
按钮点击均有高危二次确认弹窗。
![重新推送(高危):确认金蝶旧应付/应收单已由财务手工冲销后才继续,系统将克隆新单并生成全新应付/应收单](./2026-10-17-结算调整单操作流程说明(分场景).assets/05-重新推送-高危二次确认.png)
---
## 四、分场景流程
@@ -0,0 +1,201 @@
# 收款流水菜单改造:数据源 A301-2 改 A301-1,认领只登记本地并推送合同合规(C107-1 / C107-3)
> 日期:2026-10-29
> 范围:tms-api(blade-transport、blade-hcs-api、blade-transport-api)+ tms-erp-web(收款流水 / 认领记录页面)
> 关联文档:
> - [2026-09-24-收款认领金蝶全链路业务流程(A301-2公告同步-A301-3认领推送-A301-1收款单回写)](./2026-09-24-收款认领金蝶全链路业务流程(A301-2公告同步-A301-3认领推送-A301-1收款单回写).md)(本改造后 A301-3 链路整体下线)
> - [2026-10-22-收款认领推送金蝶完成后同步合同合规系统(C103-9履约计划-C107-1认领记录-C108-1履约流水)业务流程梳理](../hcs合同/2026-10-22-收款认领推送金蝶完成后同步合同合规系统(C103-9履约计划-C107-1认领记录-C108-1履约流水)业务流程梳理.md)(触发点由 A301-3 成功后改为认领事务提交后)
---
## 1. 需求与决策结论
收款流水菜单做两点改造:
1. **数据源改为 A301-1 收款单查询**(原 A301-2 收款认领公告查询下线);
2. **认领动作只做本地认领记录 + 推送合同合规系统**(原 A301-3 推送金蝶链路整体下线,合规推送链保持 C103-9 + C107-1 + C108-1 全链)。
已确认的业务决策:
| # | 决策点 | 结论 |
| --- | --- | --- |
| 1 | 认领上限口径 | **收款金额 `receipt_amount`(A301-1 `actrecamt`)**。原定 `unmatchamountrec` 与收款金额取 min,因金蝶侧财务先核销导致大量收款单未匹配金额为 0、TMS 永久无法认领,2026-10-29 修正:认领只登记本地,额度由本地累计认领控制,`unmatchamountrec` 仅参考展示 |
| 2 | 合规推送范围 | **C103-9(履约计划金额累加)、C107-1(认领记录)、C108-1(履约流水)全保留** |
| 3 | C107-1 推送失败补偿 | **不做定时重试,只落推送标记**(blade_receipt_claim_hcs_record.push_status = failed + 失败原因) |
| 4 | 认领作废 | **需要 C107-3 作废同步**(fdStatus=1),C107-1 返回的合规 fdId 必须落库 |
| 5 | 同步可见范围 | A301-1 无认领人维度,**全公司流水均进入页面,可接受** |
---
## 2. 现状与目标链路对比
```
【现状】
A301-2 认领公告同步(按认领人姓名拉取)
→ blade_kingdee_receipt_flow 落库(幂等键 detail_serial_no)
→ 页面认领(只登记本地)
→ A301-3 推送金蝶(手动按钮 + 10分钟定时任务,推送前重查 A301-2 对账)
→ A301-3 成功后推合规链(C103-9 → C107-1 → C108-1)
→ A301-1 按 awrp_src_code 回写金蝶单据状态(refreshKingdeeResult)
【目标】
A301-1 收款单查询(业务日期窗口取 `thirdParty.bfi.recBillSync.days`,默认 60 天,全量)
→ blade_kingdee_receipt_flow 落库(幂等键 detail_serial_no,金蝶单号/状态随同步刷新)
→ 页面认领(只登记本地)
→ 认领事务提交后按认领主单推合规链(C103-9 → C107-1 → C108-1,C107-1 结果落库标记)
→ 认领作废事务提交后推 C107-3(fdStatus=1 已作废)
→ (A301-3 推送、awrp_src_code、A301-1 回写、定时任务、推送按钮全部下线)
```
关键变化:
- 金蝶收款单在认领前就已存在(A301-1 即金蝶收款处理单),因此**金蝶收款单号 / 单据状态随同步直接落库**,不再依赖推送回填与回写推进;
- 合规推送触发点从「A301-3 推送成功后(流水级)」改为「认领事务提交后(认领主单级)」,继续认领时每次认领各自推送一次,累计金额口径不变。
---
## 3. 后端改造明细(tms-api)
### 3.1 HCS Feign(blade-third-party-api/blade-hcs-api)
| 文件 | 改动 |
| --- | --- |
| `IHcsClient` | 新增 `CLAIM_RECORD_UPDATE_URL`(`/openapi/eop-data/eopDataCollectionFlowClaimRecordOpen/update`)与 `claimRecordUpdate` 方法(C107-3 修改认领记录) |
| `HcsClaimRecordAddDTO` | 新增 `fdId` 字段:C107-1 新增不传,C107-3 修改必填(作废传 fdStatus=1),一个 DTO 复用两个接口 |
### 3.2 收款流水同步:A301-2 → A301-1
`ReceiptFlowServiceImpl#sync()` 重写,`BfiUtil.queryAllPagesByTotal`(按 totalCount 推导总页数,兜底 500 页)+ `bfiService.queryRecBill` 全量翻页(pageSize 200),请求参数 `begin_bizdate` / `end_bizdate`(窗口天数取 Nacos `thirdParty.bfi.recBillSync.days`,默认 60)。
**字段映射(A301-1 → blade_kingdee_receipt_flow)**:
| 流水表字段 | A301-1 来源 | 说明 |
| --- | --- | --- |
| receipt_notice_no / kingdee_bill_no | `billno` | 金蝶收款单号(两处同值) |
| kingdee_bill_status | `billstatus` 映射 | A/B已提交→pushed、C已审核→approved、D已收款→received、其余(含G退单)→failed |
| detail_serial_no | 主单 `billno` | 明细流水号=收款单号,**幂等键**;主单粒度,一张收款单一条流水,不展开流水分录 |
| receipt_amount | 主单 `actrecamt` | 收款金额(金蝶收款金额口径) |
| unmatch_amount_rec | `unmatchamountrec` | 未匹配收款金额(金蝶参考展示,**不参与认领额度**;原列名 unclaimed_amount 已改名) |
| match_amount_rec | `matchamountrec` | 已匹配收款金额 |
| match_amount_pay | `matchamountpay` | 已匹配付款金额 |
| unmatch_amount_pay | `unmatchamountpay` | 未匹配付款金额 |
| settle_amount | `settleamount` | 已结算金额 |
| unsettle_amount | `unsettleamount` | 未结算金额 |
| payer_name / counterparty_name | `payername` | 付款人名称 |
| payee_name | `org_name` | 收款人(收款公司名称) |
| org_number | `org_number` | 收款人(公司).编码 |
| open_org_number | `openorg_number` | 核算组织.编码 |
| counterparty_account | `payeracctbanknum` | 付款账户 |
| counterparty_bank | `payerbankname` | 付款银行 |
| summary | `txt_description` | 摘要 |
| transaction_time | `bizdate` | 业务日期 |
| fee | `fee` | 手续费 |
| source_updated_time | 同步时间 | — |
| bill_id / payer_id / kingdee_claim_status / claim_me | — | **废弃不再写入**(历史 A301-2 专属字段,列保留兼容存量) |
| push_status / push_fail_reason / pushed_time / awrp_src_code | — | **不再写入**(A301-3 下线;存量已推送数据保留展示) |
同步保持原有框架:明细流水号重复抛异常、金额 ≤0 跳过、FOR UPDATE 批量防并发、按幂等键 upsert、批量操作日志;本地认领字段(claimed_amount / claim_status)不被同步覆盖,认领后状态按「累计认领 vs 收款金额」重算。
### 3.3 认领与合规推送链
`ReceiptFlowServiceImpl#claim()`:
- 删除「认领公告id缺失」「公告未认领金额缺失」拦截(A301-1 无公告概念);
- 认领上限:`claimCeiling = receipt_amount`(收款金额 `actrecamt`,金蝶未匹配金额不参与额度控制);
- 认领主单冗余展示字段直取流水:`kingdeeBillNo` / `kingdeeBillStatus`(金蝶单据认领前已存在);
- 事务提交后(`TransactionSynchronizationManager.afterCommit`)按**认领主单**触发 `HcsClaimSyncSupport#pushClaimToHcs(claimId)`,失败仅落标记不影响认领。
`HcsClaimSyncSupport` 重写(编排顺序不变、触发维度改变):
1. 归集**本认领主单**有效分摊行 → 按合同分组金额;
2. C104-2 按明细流水号定位合规侧收款流水 ID(一次定位全部合同共用);
3. 逐合同:C103-9 履约计划金额累加重推 → C107-1 认领记录(返回 fdId)→ C108-1 履约流水;
4. **C107-1 结果落库** `blade_receipt_claim_hcs_record`(认领主单×合同一条):成功持久化合规 fdId(供 C107-3 引用),失败落 failed + 原因(只记标记,无定时重试);
5. C108-1 的申请编号兜底、金蝶单据号(fd_jd_doc_no)取流水 `kingdee_bill_no`(A301-1 同步落库),金额改为本次认领分摊金额。
开关复用既有配置:`exe-stage.sync-enabled` 门禁 C103-9/C107-1,`perf-record.sync-enabled` 门禁 C108-1。
### 3.4 认领作废:C107-3 同步
`ReceiptClaimRecordServiceImpl#voidClaim()`:
- 删除「已推送金蝶不允许作废」拦截(不再有 TMS→金蝶推送,作废只回退本地 + 同步合规);
- 事务提交后按认领主单推 C107-3:查 `blade_receipt_claim_hcs_record` 中 push_status=success 的记录,逐条 `claimRecordUpdate(fdId, fdStatus=1)`,成功后本地记录置 voided;单条失败独立记日志不回滚作废,合规侧需人工处置。
### 3.5 A301-3 链路整体下线
| 项 | 处置 |
| --- | --- |
| `pushClaimToKingdee` / `pushClaimByTask` / `executeReceiptClaimPush` / `pushClaimLocked` / `doPushClaimToKingdee` / `buildClaimPushDTO` / `extractClaimPushBillNo` / `applyClaimPushSuccess` / `applyClaimPushFailure` | 删除(ReceiptFlowServiceImpl) |
| `ReceiptClaimPushTask`(10 分钟定时推送) | 文件删除 |
| `ReceiptFlowController` `/push-kingdee` 端点 | 删除 |
| `refreshKingdeeResult`(A301-1 按 awrp_src_code 回写)+ `/receipt-claim-record/query-kingdee-result` 端点 | 删除(A301-1 已是数据源,状态随同步刷新) |
| `awrpSrcCode` 生成逻辑 | 删除 |
| `BfiProperties` | `claimAnnounce` / `receiptClaimPush` 配置类删除,新增 `RecBillSync`(`days` 默认 30) |
| `KingdeeReceiptFlow` 实体 | 字段注释更新为 A301-1 口径(bill_id 等标注废弃) |
### 3.6 新增表
`blade_receipt_claim_hcs_record`(收款认领合规推送记录,DDL 见 `doc/sql/transport/lqj/20261102/01_blade_receipt_claim_hcs_record_20261028.sql`):
| 字段 | 说明 |
| --- | --- |
| receipt_claim_id / receipt_flow_id | 认领主单 / 收款流水 |
| contract_id / contract_no | 合同 |
| claim_amount | 本认领主单分摊到本合同的金额 |
| hcs_claim_record_fd_id | 合规侧认领记录 fdId(C107-1 返回,C107-3 必填引用) |
| push_status | success 推送成功 / failed 推送失败 / voided 已作废 |
| fail_reason / pushed_time | 失败原因 / 成功时间 |
---
## 4. 前端改造明细(tms-erp-web)
| 页面 / 文件 | 改动 |
| --- | --- |
| `views/payment/receipt-flow.vue` | 删「推送金蝶」操作按钮及 `canPush`/`handlePush`;删搜索「推送状态」;详情删「推送状态」「推送失败原因」,「金蝶未认领金额」→「未匹配金额」;同步提示改为"收款流水" |
| `views/payment/receipt-claim-record.vue` | 删「查询金蝶认领结果」按钮;删搜索「推送状态」;作废按钮去掉 `pushStatus !== 'pushed'` 限制;作废确认提示增加"同步作废合同合规系统认领记录" |
| `views/payment/receipt-flow-form.vue` / `receipt-flow-batch-form.vue` | 「认领通知单」→「收款单号」;「金蝶未认领金额」→「未匹配金额」;校验提示"公告未认领金额"→"未匹配金额" |
| `views/payment/receipt-claim-record-form.vue` | 「认领通知单」→「收款单号」 |
| `views/settlement/components/formal-settlement-editor.vue` | 认领列表列「认领通知单」→「收款单号」 |
| `api/payment/receiptFlow.js` | 删 `pushKingdee`、`pushStatusOptions` |
| `api/payment/receiptClaimRecord.js` | 删 `queryKingdeeResult`、`pushStatusOptions` |
| `option/payment/receiptFlow.js` | 删「公告状态」「推送状态」「推送失败原因」「金蝶收款单号」(与单号列重复)列;「认领通知单」→「收款单号」、「付款金额」→「收款金额」、「金蝶未认领金额」→「未匹配金额」 |
| `option/payment/receiptClaimRecord.js` | 「认领通知单」→「收款单号」、「付款金额」→「收款金额」 |
菜单按钮权限提示:`receipt_flow_push` 权限码随按钮下线,可在菜单配置中清理。
---
## 5. 配置与存量数据
**Nacos(thirdParty.bfi.*)**:
- 新增(可选):`recBillSync.days`,默认 60(A301-1 业务日期窗口天数);
- 可清理:`claimAnnounce.*`、`receiptClaimPush.*`(代码已不再读取)。
**存量数据**:
- A301-2 时代同步的流水(bill_id、kingdee_claim_status、claim_me 有值)与新口径并存,页面不再展示这些列;历史 push_status=pushed / awrp_src_code 仅保留展示,不再参与任何闸门;
- 明细流水号为全链唯一衔接键:A301-1 `bei_detailid` ≈ A301-2 `detailid` ≈ 合规 C104-2 `fdDetailSerialNumber`,同源同值时新旧数据 upsert 自然衔接。
---
## 6. 风险与待验证项
| # | 项 | 说明 | 等级 |
| --- | --- | --- | --- |
| 1 | **明细流水号同源性** | A301-1 `bei_detailid` 必须与原 A301-2 `detailid`、合规侧 `fdDetailSerialNumber` 同值,否则 C104-2 定位失败 → C107-1 全部跳过(仅记日志/落失败标记)。需联调拿真实报文核对 | 高 |
| 2 | 认领额度与金蝶匹配解耦 | 上限改用收款金额后,金蝶侧已匹配(核销)的收款单同样可认领并推合规;金蝶匹配状态变化不影响 TMS 已认领额度(按 `claimed_amount` 本地累计)。原 `unmatchamountrec` 口径下 797 条流水有 704 条额度为 0,需求无法闭环 | 中 |
| 3 | 合规履约计划金额不回退 | C103-9 认领时累加,作废仅同步 C107-3,不回退履约计划行金额(与改造前口径一致,未新增回退逻辑) | 中 |
| 4 | 全公司可见范围 | A301-1 按组织/日期拉全量,不再按认领人过滤,页面数据范围扩大(业务已确认可接受) | 低 |
| 5 | C107-1 失败无自动重试 | 仅落 failed 标记与原因,需人工在合规侧核对补录(业务已确认) | 低 |
## 7. 验证清单(交由测试/联调执行)
1. 手动同步:A301-1 拉取、流水按 infoentry 展开、重复明细流水号拦截、金额/单号/状态落库正确;
2. 认领:上限按收款金额控制、认领完成状态判定、合规链推送成功后 `blade_receipt_claim_hcs_record` 有 success 记录且 fdId 非空;
3. 继续认领:第二次认领各自推送一次 C107-1/C108-1,C103-9 累计金额正确;
4. 作废:本地回退 + C107-3 同步、记录置 voided;无合规记录(推送失败)时作废静默跳过;
5. 合规开关关闭(exe-stage/perf-record sync-enabled=false)时认领/作废主流程不受影响;
6. 回归:认领记录页、结算单收款汇总刷新、认领人筛选。
@@ -0,0 +1,254 @@
# 收款流水认领操作流程(收款金额本地额度 · 单条/批量/作废)
> 日期:2026-10-29
> 范围:`tms-api` blade-transport 收款流水(同步、认领、认领记录)+ `tms-erp-web` 收款流水 / 认领记录页面
> 关联文档:
> - [2026-10-29-收款流水菜单改造(数据源A301-2改A301-1-认领只登记本地并推送合规C107-1与C107-3作废同步)](./2026-10-29-收款流水菜单改造(数据源A301-2改A301-1-认领只登记本地并推送合规C107-1与C107-3作废同步).md)(改造设计与字段映射)
> - [2026-10-16-收款流水多次认领与作废口径梳理](./2026-10-16-收款流水多次认领与作废口径梳理.md)(多次认领、逐条作废口径)
---
## 0. 一页速览
| 项 | 内容 |
| --- | --- |
| 菜单入口 | 首付款管理 → **收款流水**(`/payment/receipt-flow`)、**认领记录**(`/payment/receipt-claim-record`) |
| 数据来源 | 金蝶 A301-1 收款单查询(收款处理单),**手动同步**触发,无定时任务 |
| 流水粒度 | 一张金蝶收款单 = 一条流水(`detail_serial_no` = 收款单号,幂等键) |
| 可认领上限 | **收款金额 `receipt_amount`(金蝶 `actrecamt`)** |
| 剩余可认领 | `max(收款金额 − 已认领金额 claimed_amount, 0)` |
| 未匹配金额 | 金蝶 `unmatchamountrec`,**仅参考展示,不参与额度控制** |
| 认领动作 | 只登记本地(认领主单 + 结算单分摊),**不推金蝶** |
| 合规推送 | 认领事务提交后推 C103-9 → C107-1 → C108-1;作废推 C107-3 |
| 状态 | `unclaimed` 未认领 / `partial` 部分认领 / `claimed` 认领完成 |
---
## 1. 角色与权限
| 操作 | 权限码 | 说明 |
| --- | --- | --- |
| 查看收款流水 | `receipt_flow_view` | 菜单权限 `receipt_flow` |
| 认领 / 批量认领 | `receipt_flow_claim` | 无此权限时操作列显示 `-`,顶部无「批量认领」按钮 |
| 手动同步流水 | `receipt_flow_sync` | 无此权限时顶部无「手动同步流水」按钮 |
| 查看认领记录 | `receipt_claim_record` | **只显示当前登录人自己的认领记录** |
| 作废认领记录 | `receipt_claim_record_void` | 仅本人、且状态为「已认领」的记录可作废 |
管理员(`admin`)默认直通按钮权限判断;认领记录页的数据范围仍按当前登录人过滤,管理员也只能看到自己做的认领。
---
## 2. 流程总览
```
【金蝶】A301-1 收款单
│ ① 手动同步(可按窗口重复执行,幂等)
▼
【TMS】收款流水列表(blade_kingdee_receipt_flow)
│ ② 勾选/单条 → 选择应收正式结算单 → 填分摊金额
▼
【TMS】认领(blade_receipt_claim + blade_receipt_claim_settlement)
│ ③ 更新流水累计认领金额/状态、刷新结算单收款汇总
│ ④ 事务提交后推合规:C103-9 → C107-1 → C108-1(失败只落标记)
▼
合规侧认领记录(C107-1 返回 fdId 落库)
│ ⑤ 需要撤销时在「认领记录」页作废
▼
本地回退金额 + 推 C107-3(fdStatus=1 已作废)
```
---
## 3. 场景一:同步收款流水
**入口**:收款流水页顶部「手动同步流水」。
**前置条件**:组织管理中已维护“是否平台公司 = 是”且已填金蝶编码的组织,否则直接报错「组织管理中未维护平台公司金蝶编码,无法同步金蝶收款流水,请先检查组织数据」。
**动作**:
1. 按业务日期窗口取数:结束日期 = 当天,开始日期 = 当天 − `thirdParty.bfi.recBillSync.days`(默认 60 天),起止时间格式 `yyyy-MM-dd HH:mm:ss`;
2. 按上述组织编码过滤,全量翻页拉取(pageSize 200,兜底 500 页,结束条件为末页/不满一页);
3. 以收款单号去重,按幂等键 upsert:新增初始化 `claimed_amount = 0`、`claim_status = unclaimed`;已存在只更新金蝶来源字段,**不覆盖本地认领金额与状态**;
4. 收款金额 ≤ 0 的收款单跳过;
5. 每批 5000 条独立事务入库,并写同步操作日志。
**结果提示**:「流水同步完成,共同步 N 条收款流水」,列表自动刷新。
**注意**:
- 同步窗口从今天倒推,历史更早的单据不会进入;需要更早数据时调整 Nacos `thirdParty.bfi.recBillSync.days` 后重新同步(该配置支持热更新)。
- 金蝶侧改动(金额、状态、匹配/结算金额)每次同步都会刷新;**TMS 已认领金额与状态不受影响**,但状态会按新的收款金额重算。
---
## 4. 场景二:单条认领
### 4.1 入口与显示条件
列表操作列「认领」需同时满足:
1. 有 `receipt_flow_claim` 权限(admin 直通);
2. 剩余可认领金额 > 0(即收款金额 > 累计已认领金额)。
不满足时操作列显示 `-`。列表列「未匹配金额」为金蝶口径参考值,**该列为 0 不影响认领**。
### 4.2 操作步骤
1. 点「认领」进入认领页面,顶部只读展示:收款单号、付款人、收款金额、交易时间、对方户名/开户行/账号、明细流水号、已认领金额、未匹配金额(金蝶参考)、剩余可认领金额、摘要、认领人、认领日期、认领人部门;
2. 点「关联结算单」选择器,弹窗按结算单号/项目/合同搜索:
- 候选范围:应收类型 + 已审批通过 + 有效状态 + 该结算单自身仍有剩余可认领金额;
- 多选时必须**同一项目、同一组织、同付款方、同收款方**,否则提示「关联结算单必须属于同一项目、组织及收付款方」;
3. 在「结算信息」明细中逐张填写「分摊收款金额」:
- 单张结算单分摊上限 = 结算总金额 − 已认领收款金额;
- 本次分摊合计必须 ≤ 当前页面的「剩余可认领金额」;
4. 维护附件(可选)、备注(≤200 字);
5. 点「确认」。
### 4.3 确认后系统做了什么
| 步骤 | 内容 |
| --- | --- |
| 1 | 行锁流水与所选结算单,防止并发超额 |
| 2 | 校验:每张结算单「已认领 + 本次分摊 ≤ 结算总金额」;流水「已认领 + 本次分摊 ≤ 收款金额」 |
| 3 | 插入 1 条认领主单 `blade_receipt_claim`(`claim_amount` = 本次分摊合计) |
| 4 | 按结算单插入 N 条分摊 `blade_receipt_claim_settlement`(记录认领前已认领金额、本次分摊金额) |
| 5 | 刷新各结算单收款汇总;流水 `claimed_amount` 累加,重算 `claim_status`(0 → unclaimed,< 收款金额 → partial,≥ 收款金额 → claimed) |
| 6 | 写流水操作记录(认领动作、金额、关联结算单数) |
| 7 | **事务提交后**按认领主单推合规:C103-9(履约计划金额累加)→ C107-1(认领记录,返回 fdId 落库)→ C108-1(履约流水);任一步失败只落 `blade_receipt_claim_hcs_record` 失败标记,不回滚认领 |
| 8 | 返回收款流水列表,提示「认领成功」 |
> 合规开关关闭(`exe-stage.sync-enabled` / `perf-record.sync-enabled`)时,认领主流程不受影响,只是不推合规。
---
## 5. 场景三:批量认领
**入口**:列表勾选多条流水 → 顶部「批量认领」(需 `receipt_flow_claim` 权限)。
**前置校验**:所选流水的**付款人 + 对方账号必须完全一致**,否则提示「批量认领所选流水的付款人、对方账号必须一致」。
**操作步骤**:
1. 进入「批量认领收款流水」页面,顶部明细列出所选流水(收款单号、收款金额、已认领金额、未匹配金额、剩余可认领金额、摘要);
2. 选择关联应收结算单(候选规则同单条认领,多选同样要求同项目/组织/收付款方);
3. 在「结算单 × 流水」分摊矩阵中逐格填写金额:
- 单格上限 = min(该结算单剩余可认领 − 该结算单其它格已填, 该流水剩余可认领 − 该流水其它格已填);
4. 附件、备注同单条认领;
5. 点「确认」。
**提交逻辑**:
- 先校验结算单维度(累计分摊 ≤ 结算单剩余)与流水维度(累计分摊 ≤ 流水剩余可认领);
- 按流水逐条提交认领:**每条流水生成一条认领主单**,各自推一次合规(C103-9 累计金额按各次认领累加);
- 分摊为 0 的格子不提交;全部为 0 时提示「没有需要入库的分摊收款金额」;
- 全部成功提示「批量认领成功,共 N 条流水」并返回列表。
> 批量提交是逐条循环调用认领接口,非单一事务:中途某条失败时,之前的流水已认领成功,需要按提示逐条核查(可在「认领记录」页确认已成功的部分)。
---
## 6. 场景四:部分认领与继续认领
1. 首次分摊合计小于收款金额 → 流水状态变「部分认领」(`partial`),剩余可认领金额 = 收款金额 − 累计已认领;
2. 再次点「认领」进入页面时,会**自动预填本流水历史关联且仍有剩余可认领金额的结算单**(分摊金额默认 0,需重新填写);
3. 每次认领都是一条新的认领主单,合规侧每次各推一次 C107-1/C108-1,C103-9 按合同累计;
4. 累计达到收款金额 → 状态「认领完成」,操作列不再显示「认领」。
---
## 7. 场景五:作废认领记录
**入口**:认领记录页(仅本人记录)→ 操作列「作废」(需 `receipt_claim_record_void`,且记录状态为「已认领」)。
**操作**:点击后二次确认,提示「作废后将回退本次认领金额,并同步作废合同合规系统认领记录」。
**作废后系统做了什么**:
| 步骤 | 内容 |
| --- | --- |
| 1 | 行锁认领主单、收款流水、关联结算单 |
| 2 | 本次认领的分摊行批量置为无效(`status = 0`) |
| 3 | 刷新关联结算单收款汇总 |
| 4 | 流水 `claimed_amount` 回退本次认领金额(不小于 0),并按收款金额重算状态(可能回到 unclaimed / partial) |
| 5 | 认领主单置「已作废」,记录作废人、作废时间与操作日志 |
| 6 | 事务提交后逐条推 C107-3(按落库 fdId 传 `fdStatus=1`),成功记录置 `voided`;单条失败只记日志,**不回滚作废**,需人工在合规侧处置 |
**注意**:
- 已作废记录不可重复作废;
- 作废不生成金蝶冲销单,金蝶收款单本身不受影响(金蝶侧红冲由财务人工处置);
- 认领记录允许本人维护附件(`/receipt-claim-record/attachments`)。
---
## 8. 状态与金额口径
### 8.1 流水认领状态
| 状态 | 含义 | 判定 |
| --- | --- | --- |
| `unclaimed` 未认领 | 尚未认领 | 累计认领金额 = 0 |
| `partial` 部分认领 | 已认领一部分 | 0 < 累计认领金额 < 收款金额 |
| `claimed` 认领完成 | 额度用尽 | 累计认领金额 ≥ 收款金额 |
### 8.2 关键金额
| 金额 | 来源/公式 | 用途 |
| --- | --- | --- |
| 收款金额 `receipt_amount` | A301-1 `actrecamt` | 认领上限 |
| 已认领金额 `claimed_amount` | 本地认领累加(作废回退) | 已用额度 |
| 剩余可认领金额 `remainingAmount` | `max(收款金额 − 已认领金额, 0)` | 按钮显隐、前置校验 |
| 未匹配金额 `unmatch_amount_rec` | A301-1 `unmatchamountrec` | 金蝶参考展示,**不参与校验** |
| 结算单剩余可认领 | 结算总金额 − 该结算单已认领收款金额 | 分摊上限(结算单维度) |
### 8.3 金蝶单据状态(随同步刷新)
| `billstatus` | 本地 `kingdee_bill_status` | 页面展示 |
| --- | --- | --- |
| A 暂存 / B 已提交 | `pushed` | 已推送 |
| C 已审核 | `approved` | 审核通过 |
| D 已收款 | `received` | 已收款 |
| G 已退单 / E 变更中 / 其它 | `failed` | 处理失败(需人工在金蝶核查) |
---
## 9. 常见提示与处置
| 提示 | 原因 | 处置 |
| --- | --- | --- |
| 操作列显示 `-` | 无 `receipt_flow_claim` 权限,或已认领完成(剩余可认领 = 0) | 配权限;或确认是否已全额认领 |
| 「该流水可认领金额为0,无需认领」 | 收款金额 ≤ 0(数据异常,正常同步已跳过此类单据) | 核查金蝶收款单金额 |
| 「累计认领金额不能超过可认领上限,剩余可认领 X」 | 分摊合计超过剩余可认领 | 按提示减少分摊 |
| 前端「累计认领金额不能超过剩余可认领金额」 | 同上,前端预校验拦截 | 同上 |
| 「结算单XXX的累计认领金额不能超过结算总应收含税金额」 | 单张结算单分摊超过其剩余 | 调整该结算单分摊 |
| 「关联结算单必须属于同一项目、组织及收付款方」 | 多选结算单不一致 | 重新选择同项目同收付款方的结算单 |
| 「批量认领所选流水的付款人、对方账号必须一致」 | 勾选流水不属于同一付款账户 | 拆分批次 |
| 「组织管理中未维护平台公司金蝶编码…」 | 同步前置缺失 | 维护组织金蝶编码后再同步 |
| 未匹配金额为 0 但可以认领 | 金蝶侧财务已核销,属正常 | 忽略该列,按剩余可认领操作 |
| 认领记录页看不到某条记录 | 只显示当前登录人自己的记录 | 由本人查看/作废,或到结算单认领明细核查 |
| 合规推送失败 | C103-9/C107-1/C108-1 返回异常 | 查 `blade_receipt_claim_hcs_record` 失败原因,人工在合规侧补录(无自动重试) |
---
## 10. 与 2026-10-29 之前的差异
| 项 | 改造前 | 现在 |
| --- | --- | --- |
| 数据源 | A301-2 收款认领公告 | A301-1 收款单查询 |
| 认领上限 | `min(未匹配收款金额, 收款金额)` | **收款金额** |
| 未匹配金额的作用 | 决定是否可认领(大量单据为 0 → 无法认领) | 仅参考展示 |
| 认领后 | A301-3 推金蝶(手动/定时) | 只登记本地 + 推合规,金蝶不写 |
| 推送失败 | 定时重试 | 只落失败标记,人工处理 |
---
## 11. 操作自查清单
1. 同步后列表条数、收款单号、收款金额、金蝶状态与金蝶一致;
2. 剩余可认领金额 = 收款金额 − 已认领金额,且列表/详情/认领页三处一致;
3. 单条认领:分摊合计 = 收款金额 → 状态「认领完成」,按钮消失;小于 → 「部分认领」;
4. 继续认领:剩余额度正确、历史结算单预填、合规侧新增一条认领记录;
5. 批量认领:同一付款账户多流水一次提交,各自生成认领记录;
6. 作废:金额回退、状态回退、合规侧记录变为已作废(`blade_receipt_claim_hcs_record.push_status = voided`);
7. 超额场景(流水维度、结算单维度)均被拦截并给出可读提示。
+6
View File
@@ -188,12 +188,18 @@ thirdParty:
exratetable: ${BFI_PAY_APPLY_EXRATE_TABLE:01}
# 外部单据类型
srcType: ${BFI_PAY_APPLY_SRC_TYPE:0KzXs}
# 收款流水同步配置(A301-1 收款单查询)
recBillSync:
# 业务日期窗口天数
days: ${BFI_RECBILL_SYNC_DAYS:60}
# 金蝶付款结果定时回写(A103-2 付款申请单查询 / A103-4 付款处理查询)
payResult:
# 回写任务开关
syncEnabled: ${BFI_PAY_RESULT_SYNC_ENABLED:true}
# 调度 cron,默认每10分钟
cron: ${BFI_PAY_RESULT_CRON:0 */10 * * * ?}
# A103-4 付款处理查询业务日期窗口天数
queryWindowDays: ${BFI_PAY_RESULT_QUERY_WINDOW_DAYS:60}
# 收款认领公告查询配置(A301-2)
claimAnnounce:
# 查询时间窗口(月数)
+6
View File
@@ -137,12 +137,18 @@ thirdParty:
exratetable: ${BFI_PAY_APPLY_EXRATE_TABLE:01}
# 外部单据类型
srcType: ${BFI_PAY_APPLY_SRC_TYPE:0KzXs}
# 收款流水同步配置(A301-1 收款单查询)
recBillSync:
# 业务日期窗口天数
days: ${BFI_RECBILL_SYNC_DAYS:60}
# 金蝶付款结果定时回写(A103-2 付款申请单查询 / A103-4 付款处理查询)
payResult:
# 回写任务开关
syncEnabled: ${BFI_PAY_RESULT_SYNC_ENABLED:true}
# 调度 cron,默认每10分钟
cron: ${BFI_PAY_RESULT_CRON:0 */10 * * * ?}
# A103-4 付款处理查询业务日期窗口天数
queryWindowDays: ${BFI_PAY_RESULT_QUERY_WINDOW_DAYS:60}
# 收款认领推送金蝶定时任务(A301-3 收款认领结果推送)
receiptClaimPush:
# 推送任务开关,默认关闭(联调稳定后开启)
+6
View File
@@ -90,12 +90,18 @@ thirdParty:
exratetable: ${BFI_PAY_APPLY_EXRATE_TABLE:01}
# 外部单据类型
srcType: ${BFI_PAY_APPLY_SRC_TYPE:0KzXs}
# 收款流水同步配置(A301-1 收款单查询)
recBillSync:
# 业务日期窗口天数
days: ${BFI_RECBILL_SYNC_DAYS:60}
# 金蝶付款结果定时回写(A103-2 付款申请单查询 / A103-4 付款处理查询)
payResult:
# 回写任务开关
syncEnabled: ${BFI_PAY_RESULT_SYNC_ENABLED:false}
# 调度 cron,默认每10分钟
cron: ${BFI_PAY_RESULT_CRON:0 1/10 * * * ?}
# A103-4 付款处理查询业务日期窗口天数
queryWindowDays: ${BFI_PAY_RESULT_QUERY_WINDOW_DAYS:60}
# 金蝶收票单结果定时回写(A801-3 异常回收/指定补偿/单号补登)
receivedInvoiceResult:
@@ -0,0 +1,28 @@
-- 收款流水表增加金蝶收款单组织/公司编码字段(A301-1 收款单查询同步落库)
-- openorg_number 核算组织.编码、org_number 收款人(公司).编码;org_name 已由 payee_name 承载不加列
SET @ddl_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `blade_kingdee_receipt_flow` ADD COLUMN `org_number` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ''收款人(公司).编码(A301-1 org_number)'' AFTER `payee_name`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_kingdee_receipt_flow'
AND COLUMN_NAME = 'org_number'
);
PREPARE ddl_stmt FROM @ddl_sql;
EXECUTE ddl_stmt;
DEALLOCATE PREPARE ddl_stmt;
SET @ddl_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `blade_kingdee_receipt_flow` ADD COLUMN `open_org_number` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ''核算组织.编码(A301-1 openorg_number)'' AFTER `org_number`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_kingdee_receipt_flow'
AND COLUMN_NAME = 'open_org_number'
);
PREPARE ddl_stmt FROM @ddl_sql;
EXECUTE ddl_stmt;
DEALLOCATE PREPARE ddl_stmt;
@@ -0,0 +1,67 @@
-- 收款流水表增加金蝶收款单匹配/结算金额字段(A301-1 收款单查询同步落库)
-- unmatchamountrec 未匹配收款金额已由 unclaimed_amount 承载,不重复加列
SET @ddl_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `blade_kingdee_receipt_flow` ADD COLUMN `match_amount_rec` decimal(19, 2) DEFAULT NULL COMMENT ''已匹配收款金额(A301-1 matchamountrec)'' AFTER `unclaimed_amount`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_kingdee_receipt_flow'
AND COLUMN_NAME = 'match_amount_rec'
);
PREPARE ddl_stmt FROM @ddl_sql;
EXECUTE ddl_stmt;
DEALLOCATE PREPARE ddl_stmt;
SET @ddl_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `blade_kingdee_receipt_flow` ADD COLUMN `match_amount_pay` decimal(19, 2) DEFAULT NULL COMMENT ''已匹配付款金额(A301-1 matchamountpay)'' AFTER `match_amount_rec`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_kingdee_receipt_flow'
AND COLUMN_NAME = 'match_amount_pay'
);
PREPARE ddl_stmt FROM @ddl_sql;
EXECUTE ddl_stmt;
DEALLOCATE PREPARE ddl_stmt;
SET @ddl_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `blade_kingdee_receipt_flow` ADD COLUMN `unmatch_amount_pay` decimal(19, 2) DEFAULT NULL COMMENT ''未匹配付款金额(A301-1 unmatchamountpay)'' AFTER `match_amount_pay`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_kingdee_receipt_flow'
AND COLUMN_NAME = 'unmatch_amount_pay'
);
PREPARE ddl_stmt FROM @ddl_sql;
EXECUTE ddl_stmt;
DEALLOCATE PREPARE ddl_stmt;
SET @ddl_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `blade_kingdee_receipt_flow` ADD COLUMN `settle_amount` decimal(19, 2) DEFAULT NULL COMMENT ''已结算金额(A301-1 settleamount)'' AFTER `unmatch_amount_pay`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_kingdee_receipt_flow'
AND COLUMN_NAME = 'settle_amount'
);
PREPARE ddl_stmt FROM @ddl_sql;
EXECUTE ddl_stmt;
DEALLOCATE PREPARE ddl_stmt;
SET @ddl_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `blade_kingdee_receipt_flow` ADD COLUMN `unsettle_amount` decimal(19, 2) DEFAULT NULL COMMENT ''未结算金额(A301-1 unsettleamount)'' AFTER `settle_amount`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_kingdee_receipt_flow'
AND COLUMN_NAME = 'unsettle_amount'
);
PREPARE ddl_stmt FROM @ddl_sql;
EXECUTE ddl_stmt;
DEALLOCATE PREPARE ddl_stmt;
@@ -0,0 +1,15 @@
-- 收款流水表未匹配收款金额列改名:unclaimed_amount(A301-2 公告未认领金额遗留列名)
-- → unmatch_amount_rec(与 A301-1 字段口径及其他匹配金额列命名统一)
SET @ddl_sql = (
SELECT IF(COUNT(*) = 1,
'ALTER TABLE `blade_kingdee_receipt_flow` RENAME COLUMN `unclaimed_amount` TO `unmatch_amount_rec`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_kingdee_receipt_flow'
AND COLUMN_NAME = 'unclaimed_amount'
);
PREPARE ddl_stmt FROM @ddl_sql;
EXECUTE ddl_stmt;
DEALLOCATE PREPARE ddl_stmt;
@@ -0,0 +1,27 @@
-- 收款认领合规推送记录表:C107-1 认领记录推送结果落库(认领主单 × 合同一条)
-- 成功持久化合规侧 fdId 供认领作废 C107-3 引用;失败落推送标记与原因(仅记标记,不做定时重试)
-- 配套改造:收款流水菜单数据源 A301-2 → A301-1,认领事务提交后推送合规链(C103-9/C107-1/C108-1)
CREATE TABLE IF NOT EXISTS `blade_receipt_claim_hcs_record` (
`id` bigint NOT NULL COMMENT '主键',
`tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '000000' COMMENT '租户ID',
`receipt_claim_id` bigint NOT NULL COMMENT '认领主单id',
`receipt_flow_id` bigint NOT NULL COMMENT '收款流水id',
`contract_id` bigint DEFAULT NULL COMMENT '合同id',
`contract_no` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '合同编号',
`claim_amount` decimal(19, 2) DEFAULT NULL COMMENT '该认领主单分摊到本合同的认领金额',
`hcs_claim_record_fd_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '合规侧认领记录fdId(C107-1返回,C107-3作废必填引用)',
`push_status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '推送状态(success推送成功/failed推送失败/voided已作废)',
`fail_reason` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '推送失败原因(成功后清空)',
`pushed_time` datetime DEFAULT NULL COMMENT '推送成功时间',
`create_user` bigint DEFAULT NULL COMMENT '创建人',
`create_dept` bigint DEFAULT NULL COMMENT '创建部门',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_user` bigint DEFAULT NULL COMMENT '修改人',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`status` int DEFAULT NULL COMMENT '状态',
`is_deleted` int DEFAULT 0 COMMENT '是否已删除',
PRIMARY KEY (`id`),
KEY `idx_receipt_claim_id` (`receipt_claim_id`),
KEY `idx_receipt_flow_id` (`receipt_flow_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='收款认领合规推送记录表';