docs: 新增结算调整单接入金蝶设计文档
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
# 结算调整单接入金蝶设计(未推送自动推 · 已推送手工冲销后重推新单)
|
||||
|
||||
> 整理日期:2026-10-16
|
||||
> 目标:把「结算调整单」正式接入金蝶链路。核心约束——**原正式结算单一旦推送过金蝶,其本地数据一律冻结不动**;调整后的数据落在重推时新建的一张正式结算单上,用它向金蝶生成**全新**的财务应付/应收单。
|
||||
> 依据:`2026-09-20-应付单与付款申请同步金蝶全链路业务流程(A102-2保存-A102-4查询-A103-1下推-A103-2回写).md`、`2026-09-21-应收结算与开票申请同步金蝶全链路业务流程(A302-2保存-A302-4勾稽-A303-1新增-A303-4预检-A303-5回写).md`、`2026-10-05-审批通过自动同步金蝶设计(事件触发+定时重推+手动兜底).md`、`2026-10-09-金蝶单据锁定与解锁业务流程(...).md`、当前代码(探索核实)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
结算调整单(`blade_settlement_adjustment`)用于在正式结算单审批通过后调整其费用项目与金额。目前它只有本地审批与一个假的 `repush`(拼 `K3AP+时间戳`),并未真正接入金蝶。
|
||||
|
||||
需要落地的三段操作:
|
||||
|
||||
| 操作 | 内容 |
|
||||
|---|---|
|
||||
| 操作 1 新增调整单 | 只允许选**审核通过**且**未下推付款申请**的正式结算单;自动回带客商、调整类型、合同等 |
|
||||
| 操作 2 审批通过 | 回写/记录调整 → 按原结算单金蝶状态分流(未推送→推原单;已推送→不动金蝶,提示财务手工冲销) |
|
||||
| 操作 3 重新推送(高危) | 旧应付/应收单已在金蝶冲销后,把**调整后的数据**以**全新来源单据号**推成一张新的财务应付/应收单 |
|
||||
|
||||
> 全程交互使用中文。
|
||||
|
||||
## 2. 名词与接口速查
|
||||
|
||||
| 代号 | 含义 |
|
||||
|---|---|
|
||||
| A102-2 | 财务应付单**保存**(推送) |
|
||||
| A102-4 | 财务应付单**查询**(幂等预检;返回 `BfiApBillVO`,含 `iswrittenoff` / `hadwrittenoff`) |
|
||||
| A302-2 | 财务应收单**保存**(推送) |
|
||||
| A302-4 | 财务应收单**查询**(幂等预检,同上) |
|
||||
| 防重键 | 金蝶来源单据号 `awrp_src_code`,由 `ExternalSrcCodeSupport.buildSrcCode(mainCode, partCodes)` 下划线拼接,规则 `结算单号_明细单据号` |
|
||||
| 正式结算单 | `blade_formal_settlement`,单号 `FJS`(应付)/`SJS`(应收) + `yyyyMMdd` + 4 位流水(`nextNo`) |
|
||||
| 结算调整单 | `blade_settlement_adjustment` |
|
||||
|
||||
## 3. 现状与差距(代码核实)
|
||||
|
||||
| # | 位置 | 现状 | 差距 |
|
||||
|---|---|---|---|
|
||||
| 1 | `SettlementAdjustmentServiceImpl.approve()`(约 221-261) | 仅改本地:回写原结算单费用、写变更记录、置 `approved`;`setKingdeeSyncStatus(formal.getKingdeeSyncStatus())`(推送前快照) | 未触发金蝶推送;未回填推送后的真实状态,导致前端「重新推送」按钮(条件 `approved && kingdeeSyncStatus='synced'`)不出现 |
|
||||
| 2 | `SettlementAdjustmentServiceImpl.repush()`(约 207-217) | 假实现:拼 `K3AP+时间戳` 直接置 synced | 未校验冲销、未生成新单、未真正推送 |
|
||||
| 3 | `FormalSettlementServiceImpl.syncKingdee/doSyncKingdee`(640/805) | 真实推送 + 落锁 + 失败重推链路;`doSyncKingdee` 在 `synced` 时**幂等早退** | 重推前须重置状态,否则被早退 |
|
||||
| 4 | `KingdeeApBillSyncSupport.pushApBill`(220)/`queryApBillExistNos`(157) | A102-4 预检**不区分是否已冲销** | 冲销后同键重推会被预检判为"已存在"而跳过 |
|
||||
| 5 | `BfiApBillVO` | 已含 `iswrittenoff`(154)/`hadwrittenoff`(158) | 尚未用于冲销判定 |
|
||||
| 6 | `SettlementAdjustment` 实体 / `SettlementAdjustmentVO` | 实体无 `kingdeeBillNo`;VO 有(20) | 金蝶单号无处落库 |
|
||||
| 7 | `IKingdeeBillLockService` | `lockAfterPush` / `checkEditable`;**冲销不触发解锁回调** | 原单锁记录会一直停在 `locked` |
|
||||
| 8 | `IKingdeeBillLockService.checkEditable` | 仅开票申请、付款申请调用;**正式结算单未调用** | 正式结算单的编辑保护主要在前端 + `voidBill` 的 `synced` 拦截 |
|
||||
|
||||
## 4. 关键决策(已确认)
|
||||
|
||||
| 决策 | 结论 |
|
||||
|---|---|
|
||||
| **A 原单去向** | 已推送场景下**原单业务数据零改动**(费用/金额/状态全不动),只加 1 条变更记录 + 标记 + 解锁;新单是**全新独立单**,原单的下游关联(开票申请/收款认领/对账)**不迁移**,留在原单 |
|
||||
| **B 展示标记** | 原单标「已调整」;新单标「调整后单」并显示原单号 |
|
||||
| **B1 建单时机** | 「重新推送」时新建,审批阶段不动 |
|
||||
| **B2 新单编号** | 走 `nextNo` 正式流水(`FJS`/`SJS` + 日期 + 4 位),**不**加后缀 |
|
||||
| **B3 原单处理** | 保持原状,不做作废/删除 |
|
||||
| **B4 调整单挂载** | 重推后调整单**改挂新单** |
|
||||
| **B5 来源预结算** | 新单**重建** `FormalSettlementSource` 行(接续原单来源) |
|
||||
| **B6 范围** | 应付、**应收都要做**(应付 A102-2/A102-4,应收 A302-2/A302-4) |
|
||||
| **B7 列表** | 新旧两张单并存,带标识展示 |
|
||||
| **C 冲销判定** | 只认 `hadwrittenoff=true`;部分冲销也放行 |
|
||||
| **D 原单旧锁** | 重推时把原单旧锁标记为 `unlocked`,不改其它 |
|
||||
| **E 未推送场景** | 审批通过后**自动推**(复用既有 `KingdeeBillApprovedEvent` 机制) |
|
||||
| 新单状态 | 克隆后直接置 `approvalStatus=approved`,不再走审批 |
|
||||
| 原单变更记录/unlock 时机 | 变更记录审批时写;`unlock` + `已调整`标记在**重推时**执行(审批时财务可能还没冲销) |
|
||||
| **选单预检** | 操作 1 选定结算单后**预检**其金蝶冲销状态(软提示,不硬拦截);金蝶不可用时降级放行 |
|
||||
| **重推冲销闸门** | 真正的**硬拦截**保留在操作 3 重推;预检不替代闸门 |
|
||||
|
||||
## 5. 总体方案
|
||||
|
||||
### 5.1 流程图
|
||||
|
||||
> 操作 1 选单后会先做一次金蝶冲销**预检(软提示,不阻断)**,见第 6.2 节。
|
||||
|
||||
```
|
||||
┌── 原结算单 kingdeeSyncStatus ──┐
|
||||
操作2 调整单审批通过 ──────────┤ │
|
||||
▼ ▼
|
||||
未推送(unsynced) 已推送(synced)
|
||||
│ │
|
||||
① 回写原单费用/金额 ① 原单业务数据【零改动】
|
||||
② 原单写变更记录 ② 原单仅写 1 条变更记录
|
||||
③ 发布 KingdeeBillApprovedEvent ③ 调整单置 approved
|
||||
(formal-settlement, 原单id) ④ toast:原结算单已推送金蝶,
|
||||
④ AFTER_COMMIT → syncKingdee(原单) 请财务在金蝶手工完成旧应付单冲销处理
|
||||
⑤ 回填调整单 synced + kingdee_bill_no
|
||||
│ │
|
||||
│ 【财务在金蝶手工冲销旧应付/应收单】
|
||||
│ │
|
||||
│ 操作3 重新推送(高危)
|
||||
│ │
|
||||
│ ① 校验调整单 approved
|
||||
│ ② 旧键查 A102-4/A302-4 → 要求 hadwrittenoff=true
|
||||
│ ③ 克隆原单 → 新正式结算单(+应用调整明细、重建 source)
|
||||
│ ④ 新单号组新键推 A102-2/A302-2
|
||||
│ ⑤ 新单落锁 + 附件
|
||||
│ ⑥ 调整单改挂新单 + 回填 kingdee_bill_no/synced
|
||||
│ ⑦ 原单:标记「已调整」+ 旧锁 unlocked
|
||||
│ ⑧ 写变更记录;失败置 failed 可重试
|
||||
▼ ▼
|
||||
金蝶应付/应收单 金蝶【全新】应付/应收单
|
||||
(同原单号来源) (新单号来源,旧单已冲销)
|
||||
```
|
||||
|
||||
### 5.2 三条不变式
|
||||
|
||||
1. **原单一经推送金蝶即冻结**:已推送场景下原单除「变更记录 / 标记 / 解锁」外,任何业务字段与状态均不改。
|
||||
2. **调整后的金额只体现在新单**:未推送场景作用于原单;已推送场景作用于重推时克隆出的新单。两者共用同一段「应用调整到结算单」的逻辑。
|
||||
3. **重推必须锚定金蝶侧已冲销**:以 A102-4/A302-4 的 `hadwrittenoff=true` 为唯一放行条件,避免重复生成应付/应收单。
|
||||
|
||||
## 6. 操作 1|新增调整单
|
||||
|
||||
### 6.1 选单来源(保持现状)
|
||||
|
||||
选单来源 `candidateFormalSettlements`(`SettlementAdjustmentServiceImpl` 约 98)已符合要求,不改:
|
||||
|
||||
- 仅 `approvalStatus = approved` 的正式结算单;
|
||||
- 排除已下推付款申请的单(`tailPaymentSettlementIds`,约 324);
|
||||
- 排除收付完成/尾款等不可调整(`adjustableFormalSettlement`,约 295);
|
||||
- 保存时自动回带客商、调整类型、合同、原结算金额等。
|
||||
|
||||
### 6.2 选单后金蝶冲销预检(新增,软提示)
|
||||
|
||||
选定关联结算单号、回带信息后,前端调后端**预检接口**:
|
||||
|
||||
1. 若结算单**未推送金蝶**(`kingdeeSyncStatus != synced`)→ 返回"未推送",正常继续,后续按设计文档走审批自动推分支;
|
||||
2. 若**已推送**→ 按防重键(`正式结算单号_结算明细单据号`)批量调 A102-4(应付)/ A302-4(应收),读 `hadwrittenoff`:
|
||||
- `hadwrittenoff = true` → 返回"已推送·旧单已冲销",提示"旧应付/应收单已冲销,审批后可重新推送新单";
|
||||
- `hadwrittenoff != true`(含查询不到)→ 返回"已推送·旧单未冲销",给出**醒目提示**:"该结算单已推送金蝶且旧单尚未冲销,审批通过后需先由财务在金蝶完成冲销,才能重新推送"。
|
||||
|
||||
**口径**:
|
||||
|
||||
- 预检为**软提示**,不阻断建单(默认建议);是否升级为硬拦截由业务另行确认。
|
||||
- **降级**:金蝶查询超时/不可用/接口异常时,预检返回"未校验",**不阻断**建单与回带,由后续审批分流与重推闸门兜底。
|
||||
- 预检结果**只用于提示**,不作为后续环节的结论缓存:审批(操作 2)、重推(操作 3)各自按**当下**状态重新判定。
|
||||
|
||||
> 为什么不把硬拦截放在选单:冲销是金蝶侧**不可逆/需人工撤销**的对外操作,而审批只是 TMS 内部决策。若选单即要求已冲销,会出现"旧单已冲销、调整单却被驳回/删除"的**应付单空档**(详见第 13 节)。
|
||||
|
||||
## 7. 操作 2|审批通过
|
||||
|
||||
### 7.1 未推送场景(原单 `kingdeeSyncStatus != synced`)
|
||||
|
||||
沿用现有 `approve()` 逻辑并补推送:
|
||||
|
||||
1. `applyAdjustmentToSettlement(原单, 调整单)`:回写费用项目、明细、合计、重算结算金额(**抽成公共方法**);
|
||||
2. 原单追加变更记录、挂载调整单;
|
||||
3. 调整单置 `approved`;
|
||||
4. 事务提交后发布 `KingdeeBillApprovedEvent("formal-settlement", 原单id)`,由既有 `KingdeeApprovalSyncListener`(AFTER_COMMIT + 域开关 + 全量 try/catch)调 `formalSettlementService.syncKingdee(原单id)` 完成 A102-2/A302-2 推送 + 落锁;
|
||||
5. 推送成功回填调整单 `kingdeeSyncStatus=synced` + `kingdeeBillNo`;失败置 `failed`(不改「已审批」结果,进入重推循环)。
|
||||
|
||||
> 复用 `2026-10-05-审批通过自动同步金蝶设计` 的事件机制,不另写推送路径;自动推送失败不影响审批结果。
|
||||
|
||||
### 7.2 已推送场景(原单 `kingdeeSyncStatus = synced`)★ 关键约束
|
||||
|
||||
**原单业务数据一律不动**,只做:
|
||||
|
||||
1. 原单追加 1 条变更记录:`结算调整单XX审批通过,调整金额XX,待重推金蝶`;
|
||||
2. 调整单置 `approved`(`kingdeeSyncStatus` 保持 `synced` 快照,前端据状态显示「重新推送」入口);
|
||||
3. 返回前端 toast 提示:**「原结算单已推送金蝶,请财务人员在金蝶手工完成旧应付单冲销处理」**。
|
||||
|
||||
> 不做:不回写原单费用/金额、不修改旧应付、不自动推送新单、不作废原单。
|
||||
|
||||
## 8. 操作 3|重新推送(高危)
|
||||
|
||||
`repush(调整单id)` 重写为:
|
||||
|
||||
1. **前置校验**:调整单 `approvalStatus = approved`;原单存在。
|
||||
2. **冲销校验(硬闸门)**:取调整单号 + 原单号,按旧键(`原结算单号_明细单据号`)查 A102-4(应付)/ A302-4(应收);要求存在且 `hadwrittenoff = true`,否则抛出「原应付/应收单尚未在金蝶冲销,禁止重推」。
|
||||
3. **克隆新正式结算单**:`cloneFormalSettlement(原单, 调整单)`
|
||||
- 新号由 `nextNo` 取正式流水(`FJS`/`SJS`+日期+4 位);
|
||||
- 克隆明细、明细费项、汇总费项、发票、汇率等;
|
||||
- 调 `applyAdjustmentToSettlement(新单, 调整单)` 应用调整(金额 = 原单 + 调整);
|
||||
- **重建** `FormalSettlementSource`(接续原单来源预结算);
|
||||
- `approvalStatus = approved`、`kingdeeSyncStatus = unsynced`、`originFormalSettlementNo = 原单号`;
|
||||
- 附件复制/挂载。
|
||||
4. **推送新单**:新单号天然组成新防重键(`新结算单号_明细单据号`),调 `syncKingdee(新单id)`(内部 A102-2/A302-2),**推前把新单状态置 `unsynced`** 以免被 `doSyncKingdee` 的 `synced` 早退。
|
||||
5. **落锁**:新单 `lockAfterPush`(`TARGET_AP_BILL`/`TARGET_AR_BILL`)+ 附件上传。
|
||||
6. **改挂 + 回填**:调整单 `formalSettlementId/No` 改指新单,回填 `kingdeeBillNo` + `kingdeeSyncStatus=synced`。
|
||||
7. **原单收尾**:标记 `adjustStatus='已调整'` + 旧锁记录置 `unlocked`;追加重推变更记录。业务字段不动。
|
||||
8. **失败处理**:新单 `kingdeeSyncStatus=failed` + 失败原因,支持复用 `retryKingdeeFailed` 重试(重试即从第 4 步继续,克隆已存在则跳过,注意幂等)。
|
||||
|
||||
## 9. 关键机制
|
||||
|
||||
### 9.1 防重键与新单号
|
||||
|
||||
- 金蝶 `awrp_src_code = 结算单号_明细单据号`。因为重推**新建了真实结算单记录**(新 `FJS/SJS` 号),新键天然与原键不同,**无需再额外拼调整单号**——早期「拼调整单号改防重键」的方案已被「新建结算单」覆盖。
|
||||
- 旧键(原结算单号)用于查冲销;新键(新结算单号)用于生成全新应付/应收单。
|
||||
|
||||
### 9.2 冲销判定
|
||||
|
||||
- 只认 `hadwrittenoff = true`(`BfiApBillVO` 158 / `BfiArBillVO` 138)。部分冲销同样放行。
|
||||
- `iswrittenoff` 不单独作为放行依据。落地前需用 Apifox 实测 A102-4/A302-4 确实回传 `hadwrittenoff`。
|
||||
- **两处判定,用途不同**:操作 1 选单预检 = 软提示(第 6.2 节);操作 3 重推 = **硬闸门**(第 8 节)。预检不替代闸门——冲销在金蝶可被撤销,且建单到重推期间状态可能变化。
|
||||
|
||||
### 9.3 克隆新正式结算单
|
||||
|
||||
- 复用现有「保存/组装」逻辑而非另写:明细、费项、汇总、来源、附件、汇率、收付款单位等按原单快照复制。
|
||||
- 新单不再走审批流(直接 `approved`),因此不写审批变更记录以外的流程痕迹;是否补一条「由调整单XX生成」变更记录可选。
|
||||
|
||||
### 9.4 金蝶锁
|
||||
|
||||
- 新单推送成功 → `lockAfterPush` 落锁,状态与既有一致。
|
||||
- 原单旧锁:重推时置 `unlocked`(决策 D)。因正式结算单未调用 `checkEditable`,解锁主要影响前端标签,不构成后端编辑漏洞。
|
||||
|
||||
### 9.5 失败与重试
|
||||
|
||||
- 复用 `markKingdeeSyncFailed` / `retryKingdeeFailed` 模式:失败落 `failed` + 原因,可被定时重推任务扫描。
|
||||
- 克隆步骤需幂等:以 `originFormalSettlementNo + 调整单` 作为唯一判断,避免重试时重复建单。
|
||||
|
||||
### 9.6 展示标记
|
||||
|
||||
| 对象 | 标记 | 来源 |
|
||||
|---|---|---|
|
||||
| 新正式结算单 | 「调整后单」(并显示原单号) | `origin_formal_settlement_no` 非空 |
|
||||
| 原正式结算单 | 「已调整」 | `adjust_status = 'adjusted'` |
|
||||
| 结算调整单 | 金蝶状态 / 金蝶单据号 | `kingdee_sync_status` / `kingdee_bill_no` |
|
||||
|
||||
## 10. 数据模型改动(DDL)
|
||||
|
||||
新增脚本 `doc/sql/transport/blade_settlement_adjustment_kingdee_20261016.sql`(多数据库脚本同步,排序规则 `utf8mb4_general_ci`):
|
||||
|
||||
```sql
|
||||
-- 结算调整单:落金蝶单据号
|
||||
ALTER TABLE blade_settlement_adjustment ADD COLUMN kingdee_bill_no VARCHAR(64) NULL COMMENT '金蝶单据号';
|
||||
|
||||
-- 正式结算单:来源原单号(新单) + 调整标记(原单)
|
||||
ALTER TABLE blade_formal_settlement ADD COLUMN origin_formal_settlement_no VARCHAR(64) NULL COMMENT '来源原正式结算单号(结算调整重推生成)';
|
||||
ALTER TABLE blade_formal_settlement ADD COLUMN adjust_status VARCHAR(32) NULL COMMENT '调整状态:adjusted=已被结算调整';
|
||||
```
|
||||
|
||||
同时生成新增按钮(「推送金蝶」「重新推送」)的菜单插入 SQL。
|
||||
|
||||
## 11. 改动清单(文件级)
|
||||
|
||||
| # | 文件 | 改动 |
|
||||
|---|---|---|
|
||||
| 1 | `blade_service_api/.../pojo/entity/SettlementAdjustment.java` | 加 `kingdeeBillNo` |
|
||||
| 2 | `blade_service_api/.../pojo/entity/FormalSettlement.java` | 加 `originFormalSettlementNo`、`adjustStatus` |
|
||||
| 3 | `blade_service_api/.../pojo/vo/SettlementAdjustmentVO.java`、`FormalSettlementVO.java` | 补展示字段/翻译 |
|
||||
| 4 | `SettlementAdjustmentServiceImpl.approve()` | 未推送→发 `KingdeeBillApprovedEvent` + 回填;已推送→仅变更记录 |
|
||||
| 5 | `SettlementAdjustmentServiceImpl.repush()` | 重写:冲销校验 → 克隆新单 → 推 → 落锁 → 改挂 → 回填 → 原单标记/解锁 → 失败置 failed |
|
||||
| 6 | `SettlementAdjustmentServiceImpl` | 抽公共方法 `applyAdjustmentToSettlement(结算单, 调整单)` |
|
||||
| 7 | `FormalSettlementServiceImpl`(或新 support) | 新增 `cloneFormalSettlement(...)`(含重建 `FormalSettlementSource`) |
|
||||
| 8 | `FormalSettlementServiceImpl` / `KingdeeApBillSyncSupport` | 冲销查询(A102-4/A302-4 读 `hadwrittenoff`)封装 |
|
||||
| 9 | `FormalSettlementWrapper` / 列表 Mapper | 回填 `adjustStatus` / `originFormalSettlementNo` |
|
||||
| 10 | 前端 `settlement-adjustment.vue`、`settlementAdjustment.js` | 金蝶状态/单号列、「推送金蝶」「重新推送」按钮(重推前冲销预检);选单后调预检接口并展示软提示 |
|
||||
| 11 | 前端 `formal-settlement.vue` / `formal-settlement-table-panel.vue` / 详情 | 「调整后单 / 已调整」标识、查看弹窗补重推入口 |
|
||||
| 12 | `doc/sql/...` | DDL + 菜单 SQL |
|
||||
| 13 | `SettlementAdjustmentServiceImpl` + `SettlementAdjustmentController` | 新增选单预检接口(返回 未推送 / 已推送已冲销 / 已推送未冲销;金蝶异常降级返回未校验) |
|
||||
|
||||
## 12. 边界场景推演
|
||||
|
||||
| 场景 | 行为 |
|
||||
|---|---|
|
||||
| 调整单未审批就重推 | 前置校验拒绝(要求 approved) |
|
||||
| 旧应付单未冲销 | A102-4 返回 `hadwrittenoff=false`/不存在 → 拒绝,提示先冲销 |
|
||||
| 部分冲销 | `hadwrittenoff=true` → 放行 |
|
||||
| 旧应付单被删除(非冲销) | 查询不到 → 拒绝(不满足 `hadwrittenoff=true`) |
|
||||
| 已推送场景审批后财务未冲销 | 重推被拦;原单与新单均未产生重复应付单 |
|
||||
| 重推推送失败 | 新单置 `failed` + 原因;原单已标「已调整」+ 解锁;重试从推送步骤续上 |
|
||||
| 重推成功但落库前崩溃 | 重试时幂等判断:已存在同一来源新单则跳过克隆,仅补推/补回填 |
|
||||
| 应收结算单(A302-2/A302-4) | 走同一套逻辑,应收侧下游关联不迁移(决策 A) |
|
||||
| 原单锁残留 | 重推时统一置 `unlocked` |
|
||||
| 未推送场景自动推失败 | 审批仍成功;调整单 `failed`,走重推循环 |
|
||||
| 选单时结算单已推送且旧单未冲销 | 预检返回"未冲销"并**软提示**(不阻断建单);审批后需先冲销再重推 |
|
||||
| 选单时金蝶超时/不可用 | 预检**降级为"未校验"**,不阻断建单;由审批分流与重推闸门判定 |
|
||||
| 建单时未推送、审批时已被推送到金蝶 | 审批按**当下**状态走"已推送"分支:不自动推、提示财务冲销;预检结论不沿用 |
|
||||
| 选单时已冲销、重推前被金蝶撤销冲销 | 重推硬闸门重新查询 `hadwrittenoff` → 拦截,提示先冲销 |
|
||||
|
||||
## 13. 风险与待验证
|
||||
|
||||
1. **A102-4/A302-4 的 `hadwrittenoff` 实际回传**:必须先用 Apifox 实测,否则整套冲销判定可能推翻。
|
||||
2. **克隆新单**:`FormalSettlementSource` 重建会牵动预结算占用(`PreSettlement.formalSettlementNo`),是最易产生脏数据的一步,需单独小步验证。
|
||||
3. **原单下游关联不迁移**(开票申请/收款认领/对账):新单为全新独立单,应收场景下新单将显示「未开票/未收款」,属已确认口径,但需业务知悉。
|
||||
4. **重推幂等**:克隆需以来源唯一键保证不重复建单,验证重试与并发(同一调整单重复点击)。
|
||||
5. **正式结算单无 `checkEditable`**:解锁不构成后端漏洞,但需确认前端在 `approved` 下仍不暴露编辑入口,避免原单被改。
|
||||
6. **冲销前置到选单的风险(故不做硬拦截)**:冲销是金蝶侧不可逆/需人工撤销的对外操作,审批是 TMS 内部决策。若选单即硬拦截(要求已冲销),会出现"旧单已冲销、调整单却被驳回/删除"的**应付单空档**,需人工在金蝶恢复冲销。故预检仅作软提示,硬闸门留在重推。
|
||||
7. **预检接口不可成为单点**:金蝶不可用时必须降级放行,否则远程依赖会阻断调整单的建单与回带。
|
||||
|
||||
---
|
||||
|
||||
## 14. 落地实现备注(2026-10-16)
|
||||
|
||||
1. **未推送场景回填**:推送成功/失败分别由 `FormalSettlementServiceImpl.doSyncKingdee` / `markKingdeeSyncFailed` 按 `formal_settlement_id + approval_status=approved` 回填调整单 `kingdee_sync_status`(synced/failed)与 `kingdee_bill_no`,复用 §7.1 的事件自动推送链路,未新增推送路径。
|
||||
2. **重推为「非事务编排 + 段内事务」**:`repush` 依次执行 —— 冲销硬闸门(旧键查 A102-4/A302-4,`hadwrittenoff=true`)→ 自代理事务 `cloneAndApplyForRepush`(克隆新单 + 应用调整,原子)→ `syncKingdee(新单)` 推送 → 成功后调整单改挂新单 + 原单标记「已调整」+ 旧锁解锁。推送失败**不回滚已克隆新单**,重试按 `origin_formal_settlement_no = 调整单当前关联单号` 幂等复用,从推送步骤续上(§8.8、§9.5)。
|
||||
3. **改挂时机**:调整单改挂新单在**推送成功之后**,故成功后再点重推会被冲销闸门拦截(无副作用);如需彻底隐藏,前端按「关联单是否克隆单」判断。
|
||||
4. **新单不克隆发票**:遵循决策 A「下游关联不迁移」,新单 `invoiceStatus=unreceived`、`paymentStatus=unpaid`,`invoiceAmount/paidAmount/appliedPaymentAmount` 归零,发票不复制。
|
||||
5. **菜单**:新增按钮 `settlement_adjustment_sync`(推送金蝶);`settlement_adjustment_repush`(重新推送)复用既有菜单,不重复插入。
|
||||
6. **待实测**:A102-4/A302-4 的 `hadwrittenoff` 实际回传(§13.1);克隆新单对 `PreSettlement` 占用的影响(§13.2)。
|
||||
|
||||
Reference in New Issue
Block a user