docs: 新增预付转正式结算单与项目预付操作流程说明(分场景·前端后端)
This commit is contained in:
@@ -0,0 +1,363 @@
|
||||
# 预付转正式结算单与项目预付操作流程说明(分场景·前端后端)
|
||||
|
||||
> 整理日期:2026-10-18
|
||||
> 定位:面向操作者与实施/联调人员的**分场景操作手册 + 逻辑说明**。讲清「谁在哪个页面点什么 → 后端发生什么 → 数据表/金蝶变成什么 → 怎么校验成功」。
|
||||
> 依据代码现状梳理(`tms-api` / `tms-erp-web`)。关联文档(同目录):
|
||||
> - 《2026-10-18-预付完整流程梳理(进度预付-项目预付-正式结算单-付款-金蝶回写).md》——改造前现状
|
||||
> - 《2026-10-18-正式结算单预付整合设计(进度预付+项目预付核销·金额口径与记录流转).md》——v2 设计与决策
|
||||
> - 《2026-10-18-预付与正式结算单全链路逻辑梳理(进度预付-项目预付核销·前端到后端各环节).md》——改造后全链路
|
||||
> - 《2026-09-21-应收结算与开票申请同步金蝶全链路业务流程(A302-2保存-A302-4勾稽-A303-1新增-A303-4预检-A303-5回写).md》——开票链
|
||||
> - 《2026-09-29-预结算开票(预开票)金蝶推送方案.md》——预开票(**方案,尚未落地**)
|
||||
|
||||
---
|
||||
|
||||
## 〇、先看全局:两条预付线 + 一条开票线
|
||||
|
||||
### 0.1 术语
|
||||
|
||||
| 术语 | 含义 |
|
||||
|---|---|
|
||||
| 预结算单(PreSettlement) | 结算前的费用单据,审批通过后作为预付/尾款结算的依据。有 **应付(payable)/应收(receivable)** 两种。 |
|
||||
| 进度预付(progress_advance) | 挂在**预结算单**上的预付,属**应付**侧(我方付出去)。 |
|
||||
| 项目预付(project_advance) | 挂在**项目 + 承运商合同**上的预付,不挂结算单,属**应付**侧。 |
|
||||
| 核销 | 项目预付金在后续结算单上"抵扣",落 `SettlementProjectAdvanceWriteOff` 行。**仅金蝶已付款(paid)的项目预付可核销**。 |
|
||||
| 容纳 / 纳入 | 预结算单转正式结算单时,其**预付台账快照**(进度预付)与**核销行**(项目预付)被正式结算单继承,计入正式单的"已付/已申请/剩余可付"。 |
|
||||
| 尾款 | 正式结算单扣除已付(含预付、核销)后的剩余部分,走单独付款申请(settlement_payment)。 |
|
||||
| 开票 | **应收**侧动作:正式结算单 → 开票申请 → 金蝶开票单。**应付**侧对应的是**收票**,两者共用 `formal_settlement.invoice_status` 字段,名称按结算方向区分。 |
|
||||
|
||||
### 0.2 全景图
|
||||
|
||||
```
|
||||
【应付线 · 预付】 【应收线 · 开票】
|
||||
|
||||
预结算单(应付) approved 预结算单(应收) approved
|
||||
│ │
|
||||
├─ 预付申请(进度预付 progress_advance) └─ 尾款结算
|
||||
│ └ 审批 → A103-3 直推金蝶付款 → 回写 paid └→ 应收正式结算单
|
||||
│ └ 提前建档 PreSettlementAdvance ├ 审批 → 同步金蝶 A302-2 财务应收单
|
||||
│ └ 开票申请(选应收正式结算单)
|
||||
项目预付(project_advance) ← 付款申请页「预付申请」 └ 审批 → A303-1 开票申请单
|
||||
├ 选 项目 + 承运商合同(校验项目额度/客户额度) └ A303-5 回写发票 → 开票完成
|
||||
├ 审批 → A103-3 → 金蝶付款 → 回写 paid
|
||||
└ 后续在结算单上「项目预付核销」
|
||||
|
||||
▼ 双线在「正式结算单」汇合
|
||||
预结算单(应付) ──「尾款结算」──→ 应付正式结算单(容纳预付快照 + 核销行)
|
||||
├ 审批 → 同步金蝶 A102-2 财务应付单(全额 settlementAmount)
|
||||
└「付款申请」→ 尾款付款 → A103-1 应付下推
|
||||
```
|
||||
|
||||
### 0.3 金蝶接口速查
|
||||
|
||||
| 接口 | 用途 | 触发方 |
|
||||
|---|---|---|
|
||||
| A103-3 | 预付款直接保存金蝶付款申请单(不绑应付单) | 付款申请(progress_advance / project_advance)同步金蝶 |
|
||||
| A103-1 | 应付下推生成金蝶付款申请单 | 付款申请(settlement_payment)同步金蝶 |
|
||||
| A103-2 / A103-4 | 付款申请单查询 / 付款处理查询 | 推送前幂等预检、定时回写(每 10 分钟) |
|
||||
| A102-2 / A102-4 | 财务应付单保存 / 查询(防重预检) | 应付正式结算单「同步金蝶」 |
|
||||
| A302-2 / A302-4 | 财务应收单保存 / 查询(勾稽) | 应收正式结算单「同步金蝶」 |
|
||||
| A303-1 / A303-4 / A303-5 | 开票申请单保存 / 幂等预检 / 开票结果查询 | 开票申请「同步金蝶」与定时回写 |
|
||||
| lockBusiData | 金蝶单据锁定 | 推送成功事务提交后 |
|
||||
| A902 | 附件上传 | 主单推送成功后联带 |
|
||||
|
||||
---
|
||||
|
||||
## 一、应付侧:预付转正式结算单(被"容纳")
|
||||
|
||||
### 场景 A1:发起进度预付(挂预结算单)
|
||||
|
||||
**前提**:预结算单 `approvalStatus=approved`、`settlementType=payable`、未转正式结算(`formalSettlementNo` 为空)。
|
||||
|
||||
**前端操作**
|
||||
1. 菜单进「预结算单」列表 → 勾选 1 条或多条预结算单(**必须同一合同**)。
|
||||
2. 点工具栏「**预付申请**」。
|
||||
- 校验不通过时的提示:缺合同 ID / 多合同 / 非 payable / 非 approved / 已转正式。
|
||||
3. 跳转「付款申请」表单,页面类型已锁定为**进度预付**:结算单只读、结算金额与可付款金额自动带出。
|
||||
4. 填「申请付款金额」「付款方式」→「保存」→ 详情页「提交」→ 列表「通过」。
|
||||
|
||||
**后端动作**
|
||||
|
||||
| 步骤 | 接口/方法 | 结果 |
|
||||
|---|---|---|
|
||||
| 可付金额 | `GET /payment-application/reference-amount` | `可付 = 预结算金额 − 累计已申请 − 项目预付核销额` |
|
||||
| 保存 | `POST /payment-application/save` → `saveDraft` | 生成 `FKD+日期+序号` 单号;写 `PaymentApplicationSettlement` 关系表 |
|
||||
| 提交 | `POST /payment-application/submit` | `draft/returned → reviewing` |
|
||||
| 审批 | `POST /payment-application/approve` | `→ approved`,刷新预结算付款汇总,发布 `KingdeeBillApprovedEvent` |
|
||||
| 自动推送 | `KingdeeApprovalSyncListener`(AFTER_COMMIT,开关 `thirdParty.bfi.autoSync.payment`) | A103-3 直推金蝶付款申请单;**提前建档** `PreSettlementAdvance`(`advanceNo = FKD 单号`);刷新预结算预付汇总并联动正式结算单 |
|
||||
|
||||
> 说明:`PreSettlementController` 的 `/apply-advance`、`/update-advance-paid`、`/void-advance` 为**遗留接口**,前端已不再调用,台账改由付款申请流程联动维护。
|
||||
|
||||
**结果校验**:预结算单列表「申请预付金额 / 已预付金额」变化;付款申请 `kingdeeStatus` 从 `unsynced → synced`。
|
||||
|
||||
### 场景 A2:发起项目预付(挂项目 + 承运商合同)
|
||||
|
||||
**前提**:项目已建、承运商合同已建;不超过项目额度与客户额度。
|
||||
|
||||
**前端操作**
|
||||
1. 菜单进「付款申请」列表 → 点工具栏「**预付申请**」(注意:与 A1 的入口不同,本入口从付款申请页进)。
|
||||
2. 表单页类型为**项目预付**,填写:
|
||||
- **所属项目**(必选,下拉)
|
||||
- **合同名称**(必选,**仅承运商合同**,选项目后才可选)
|
||||
- 申请付款金额、付款方式、付款方/收款方等
|
||||
- 不挂结算单,不展示发票信息与付款记录
|
||||
3. 「保存」→「提交」→「通过」。
|
||||
|
||||
**后端动作**
|
||||
|
||||
| 步骤 | 接口/方法 | 结果 |
|
||||
|---|---|---|
|
||||
| 保存 | `saveDraft` → `validateQuota` | 项目额度、客户额度双重校验(见下) |
|
||||
| 提交/审批 | `submit` / `approve` | 同上,审批后发事件推 A103-3 |
|
||||
| 推送 | A103-3 | 金蝶生成付款申请单,`kingdeeStatus=synced` |
|
||||
| 回写 | `PaymentKingdeeResultTask`(A103-2/A103-4,每 10 分钟) | `synced → paying → paid`;回填实付金额与付款记录 |
|
||||
|
||||
**额度校验口径**(`PaymentApplicationServiceImpl.validateQuota`,悲观锁 `FOR UPDATE`)
|
||||
|
||||
```
|
||||
项目额度 = (项目 fundLimit + Σ有效期内 approved 临时额度) × 10000
|
||||
客户额度 = 客商 maxCreditLimit × 10000
|
||||
申请付款金额 > 额度 → 分别报"申请付款金额不能超过项目额度 / 客户额度"
|
||||
```
|
||||
|
||||
**结果校验**:付款申请列表 `kingdeeStatus=已付款(paid)`,金蝶单据号已回填。**只有 paid 才能进入后续核销**。
|
||||
|
||||
### 场景 A3:项目预付核销(在结算单上选单 + 录额)
|
||||
|
||||
**前提**:存在 `approvalStatus=approved` 且 `kingdeeStatus=paid` 的项目预付,与结算单**同一合同**,且有剩余可核销余额。
|
||||
|
||||
**前端操作**
|
||||
1. 打开**预结算单编辑器**(或后续的**正式结算单编辑器**)→「**项目预付核销**」分区 → 点「**选择**」。
|
||||
2. 弹窗「选择项目预付单」列出可核销单(同合同 + 已审批 + **已付款** + 有余额),已选行不可重复勾选。
|
||||
3. 勾选「确定」→ 默认按"可核销金额"预填「本次核销金额」,可手工改小。
|
||||
4. 「保存」(或保存草稿)。
|
||||
|
||||
**校验链(前端 → 后端一致)**
|
||||
|
||||
| 层级 | 规则 | 提示 |
|
||||
|---|---|---|
|
||||
| 前端 | 金额 > 0 | 预付单 X 本次核销金额必须大于 0 |
|
||||
| 前端 | 金额 ≤ 可核销金额 | 本次核销金额不能超过可核销金额 |
|
||||
| 前端 | 核销合计 ≤ 结算单金额 | 项目预付核销合计不能超过结算单金额 |
|
||||
| 后端 | 合同一致 | 项目预付单与结算单合同不一致 |
|
||||
| 后端 | 仅项目预付 | 仅可核销项目预付单 |
|
||||
| 后端 | approved | 仅可选择审核通过的项目预付单 |
|
||||
| 后端 | **paid**(本次新增) | 预付单 X 尚未付款,项目预付须金蝶付款完成后方可核销 |
|
||||
| 后端 | 同一预付单不重复 | 同一项目预付单不可重复核销 |
|
||||
| 后端 | 有余额 / 合计 ≤ 结算金额 | 超出可核销金额 / 核销合计不能超过结算单金额 |
|
||||
|
||||
**结果校验**:正式/预结算单「已付金额」立即包含核销额(核销行必对应已付款预付,计入实付口径),列表「申请付款金额(含预付)/已收已付合计(含预付)/剩余可付」同步变化。
|
||||
|
||||
### 场景 A4:预结算转正式结算单(容纳预付)
|
||||
|
||||
**前提**:预结算单 `approved`、**同一项目**;此时其预付(进度预付台账、项目预付核销行)将被正式单继承。
|
||||
|
||||
**前端操作(两条路径)**
|
||||
1. 「预结算单」列表勾选 → 工具栏「**尾款结算**」→ 跳「正式结算单」表单,来源预结算明细与费用项自动合并。
|
||||
2. 或在正式结算单表单里通过弹窗「追加来源预结算」。
|
||||
|
||||
**表单上的三处关键呈现(应付侧)**
|
||||
- **结算合计(原金额)**:Σ 费用项 = `settlementAmount`,**始终全额,不扣预付/核销**(开票匹配上限、金蝶应付单金额基线)。
|
||||
- **汇总栏**「已付金额(含预付、核销)/ 剩余未付金额」:
|
||||
- 编辑态实时算:`已付 = Σ来源预结算.advancePaidAmount + Σ核销行.writeOffAmount`;
|
||||
- 只读态取落库值 `form.paidAmount`(已含尾款 + 进度预付 + 核销)。
|
||||
- **项目预付核销**:从预结算来源带入的核销行会**自动预填**,可增删改。
|
||||
|
||||
**后端动作(`FormalSettlementServiceImpl.saveDraft`,同一事务)**
|
||||
1. 来源合并校验(同合同、同币种)→ 写 `FormalSettlementSource` 快照(含预付汇总 `advanceAppliedAmount / advancePaidAmount`)。
|
||||
2. `refreshSettlementAmount`:以费用项重算 `settlementAmount`,并刷一次汇总。
|
||||
3. **转移来源核销行**:`deleteBySettlementIds(PRE, 来源预结算ids)` —— 先释放来源占用,后续"不超可核销余额"校验才能通过预填金额。
|
||||
4. `replaceWriteOffs`:服务端复校验后落 **FORMAL** 核销行。
|
||||
5. `refreshPaymentSummary` 再刷一次(核销落库后必须再算,第 2 步覆盖不到核销行)。
|
||||
|
||||
> 原则:**同一笔预付的核销在链路上只存在一份** —— 预结算转正式 = 删源 PRE 行 + 落 FORMAL 行。
|
||||
> 轻量标记路径(`PreSettlementController /formal-settlement`):仅回写正式结算单号,无正式单实体,PRE 核销行原地保留,待真正建单时再转移。**前提:无在途预付申请**(存在 reviewing/approved 预付会拦截)。
|
||||
|
||||
**结果校验**:正式结算单「申请付款金额(含预付)」「已收已付合计(含预付)」「剩余可付」「收付款状态」四列直接反映预付与核销;同一预付在 PRE / FORMAL 侧无双份核销。
|
||||
|
||||
### 场景 A5:正式结算单同步金蝶(A102-2 财务应付单)
|
||||
|
||||
**前端操作**:正式结算单列表 → **应付** tab → 勾选 1 条(按钮要求单选)→ 工具栏「**同步金蝶**」。
|
||||
|
||||
**后端动作**:`POST /formal-settlement/sync-kingdee` → 按结算方向路由:
|
||||
- 应付 → **A102-2 财务应付单**(A102-4 幂等预检 / 反查,一张结算单一张应付单),金额 = **全额 settlementAmount**;
|
||||
- 成功后回写 `kingdeeSyncStatus=synced` + 金蝶单据号/内码 → `lockBusiData` 锁单 → A902 附件上传。
|
||||
|
||||
**结果校验**:列表「金蝶同步状态」= 已同步、「金蝶锁定状态」= 已锁定 / 锁定中;附件未全部上传时页面追加提示"可重推补传"。
|
||||
|
||||
**审批时自动推送**:正式结算单「通过」后也会 AFTER_COMMIT 自动推;若推送失败,审批结果为 `false` + 具体原因以 warning 提示,审批本身不失败,走「同步金蝶」手动兜底或定时重推。
|
||||
|
||||
### 场景 A6:尾款付款(正式结算单之后)
|
||||
|
||||
**前提**:正式结算单 `approved`、`payable`、同一合同、有剩余可付金额。
|
||||
|
||||
**前端操作**:正式结算单(应付)列表勾选 1 条或多条 → 工具栏「**付款申请**」→ 弹窗确认各单申请金额(默认 = 剩余可付,已扣核销)→「提交」。
|
||||
|
||||
**后端动作**
|
||||
1. `saveDraft`:可挂多张同合同正式结算单,按可付金额比例分摊;`submit` 时 `validateNoTailPayment` 防重复尾款申请。
|
||||
2. **推送路由不同**:尾款走 **A103-1 应付下推**,前置对每张正式结算单做 A102-4 预检——**未在金蝶生成财务应付单则拦截**(提示先在正式结算单页同步金蝶);下推生成金蝶付款申请单,随后锁单 + 附件。
|
||||
3. 回写 `paid` → 生成 `FormalSettlementPayment(paymentType=final)` → `refreshPaymentSummary` 重算 `appliedPaymentAmount / paidAmount / remainingPayableAmount / paymentStatus`(unpaid → partial → paid)。
|
||||
|
||||
**金额口径(全系统唯一定义)**
|
||||
|
||||
```
|
||||
settlementAmount = Σ 结算合计费用项(全额,不扣预付/核销)
|
||||
appliedPaymentAmount = 尾款申请中(reviewing) + Σ来源预结算 advanceAppliedAmount + Σ核销行
|
||||
paidAmount = 尾款已付(approved 实付) + Σ来源预结算 advancePaidAmount + Σ核销行
|
||||
remainingPayableAmount = max(settlementAmount − paidAmount, 0)
|
||||
paymentStatus = unpaid / partial / paid
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、应收侧:正式结算单推送开票
|
||||
|
||||
> 开票是**应收**方向:给客户开票 → 金蝶开票单。与应付侧的"收票"共用 `invoice_status` 字段,文案按方向区分(未开票 / 部分开票 / 已开票,未收票 / 部分收票 / 已收票)。
|
||||
|
||||
### 场景 B1:应收正式结算单同步金蝶(A302-2 财务应收单)
|
||||
|
||||
**前端操作**:正式结算单列表切到「**应收**」tab → 勾选 1 条 → 工具栏「**同步金蝶**」。
|
||||
|
||||
**后端动作**:`POST /formal-settlement/sync-kingdee` → **A302-2 财务应收单**(防重键 `正式结算单号_结算明细单据号`)→ 回写单据号/内码 + `synced` → 锁单 + A902 附件。
|
||||
另有定时勾稽 `syncKingdeeArResult`(A302-4):对已同步/生成失败的应收结算单批量反查金蝶应收单并纠偏回填,可手动触发 `POST /formal-settlement/sync-kingdee-ar-result`。
|
||||
|
||||
**结果校验**:应收正式结算单 `kingdeeSyncStatus=已同步`,列表可见金蝶单据号。
|
||||
|
||||
> **开票前置**:正式结算开票要求**先有财务应收单**。开票申请推送时按 A302-4 逐结算单预检,未生成则拦截并提示"请先在正式结算单页面同步金蝶"。
|
||||
|
||||
### 场景 B2:开票申请创建与推送(A303-1 / A303-5)
|
||||
|
||||
**前提**:存在 `approved`、未作废、**未收票/未开票(invoiceStatus=unreceived)** 的**应收**正式结算单。
|
||||
|
||||
**前端操作**
|
||||
1. 菜单进「**开票申请**」列表 → 点「**新增**」。
|
||||
2. 「开票基本信息」区点「结算单」右侧「**选择**」→ 弹窗「选择应收正式结算单」(可按结算单号、项目、合同搜索)→ 勾选 → 「确定」。
|
||||
- 项目、开票单位(= 结算单收款方)自动带出;「**可开票金额**」= Σ 各结算单剩余可开票额;受票方开票信息按受票方客商档案带出。
|
||||
3. 填「发票类型」(电子专票时纳税人识别号/开户行/开户账号/注册地址必填)、受票方、邮箱、「开票内容」(发票张次与商品行)→ 系统自动算「本次开票金额」= 行合计。
|
||||
4. 「结算信息」表中填各结算单的**分摊开票金额**(≤ 该单剩余可开票金额)。
|
||||
5. 「开票明细」勾选明细 → 「保存」(草稿)→ 「提交」→ 列表「通过」。
|
||||
|
||||
**后端动作**
|
||||
|
||||
| 步骤 | 接口/方法 | 规则 |
|
||||
|---|---|---|
|
||||
| 保存 | `POST /invoice-application/save` → `saveDraft` | ① 仅可选择**应收、审批通过、未作废、未收票**的正式结算单;② 结算单需兼容(同项目/开票方等);③ 分摊金额 ≤ 剩余可开票金额;④ 行合计 > 0;⑤ 受票方须有客商档案与有效开票信息;⑥ 电子专票四要素必填;⑦ 保存后刷新来源结算单开票状态,写变更记录 |
|
||||
| 提交 | `/invoice-application/submit` | `draft/returned → reviewing`,写申请日期 |
|
||||
| 审批 | `/invoice-application/approve` | `→ approved`,发布事件 → AFTER_COMMIT 推金蝶 |
|
||||
| 推送 | `syncKingdee` → `doSyncKingdee` | ① **必须关联正式结算单**;② 逐结算单 A302-4 预检应收单已生成;③ A303-4 幂等预检(已生成的张次跳过并回填);④ 按发票张次拆分 `billno = 单号-张次` 逐张推 A303-1;⑤ 成功后锁单 + A902 附件 |
|
||||
| 回写 | 定时 `syncKingdeeInvoiceResult`(A303-5,按 `serialNo=billno` 分批 ≤50)或手动 `POST /invoice-application/sync-kingdee-invoice-result` | 查到发票 → 落 `InvoiceApplicationInvoice` 发票记录并推进 `invoiced` 终态;同时刷新来源结算单 `invoice_status`(部分开票 → 已开票) |
|
||||
|
||||
**结果校验**:开票申请 `kingdeeStatus=已同步 / 开票完成`,详情页可见发票结果(发票号、开票日期、价税合计、文件);来源正式结算单「发票状态」从未开票 → 部分开票 → 已开票。
|
||||
|
||||
**边界与限制(现状)**
|
||||
- 已推送(`synced/invoiced`)**锁单不可改**;仅审批通过且未锁定时可「作废」。
|
||||
- 数电票已开出只能红冲(不走本系统作废)。
|
||||
- **预付/核销不影响开票**:开票按**全额 `settlementAmount`** 匹配,预付与核销只影响应付侧的已付/剩余可付。
|
||||
|
||||
### 场景 B3:预开票(预结算单直接开票)——**方案,尚未落地**
|
||||
|
||||
按《2026-09-29-预结算开票(预开票)金蝶推送方案》,预结算(应收)可**只推 A303-1 开票申请单**、不校验应收单,新增 `invoice_source=pre` 与预结算关联表区分。
|
||||
|
||||
**当前代码状态**:`InvoiceApplicationServiceImpl.doSyncKingdee` 仍硬校验"必须关联正式结算单",创建入口也只允许选应收正式结算单 ⇒ **预开票目前推不出去**,需按上述方案改造后才能操作。本文不列为可执行场景。
|
||||
|
||||
---
|
||||
|
||||
## 三、状态机与字段口径
|
||||
|
||||
### 3.1 付款申请(PaymentApplication)
|
||||
|
||||
| 字段 | 取值 | 说明 |
|
||||
|---|---|---|
|
||||
| `paymentType` | `progress_advance` / `project_advance` / `settlement_payment` | 进度预付 / 项目预付 / 尾款付款 |
|
||||
| `approvalStatus` | `draft / reviewing / approved / returned / voided` | 提交后 reviewing;仅 approved 可作废 |
|
||||
| `kingdeeStatus` | `unsynced / synced / paying / paid / closed / failed` | **paid 是项目预付可核销的前置** |
|
||||
| `kingdeeLockStatus` | `locked / …` | 已锁定的单据禁止编辑/作废 |
|
||||
|
||||
### 3.2 正式结算单(FormalSettlement)
|
||||
|
||||
| 字段 | 取值 |
|
||||
|---|---|
|
||||
| `approvalStatus` | `draft / reviewing / approved / returned / voided` |
|
||||
| `paymentStatus` | `unpaid / partial / paid` |
|
||||
| `kingdeeSyncStatus` | `unsynced / synced / failed` |
|
||||
| `invoiceStatus` | 应付=收票状态,应收=开票状态:`unreceived / partial / completed` |
|
||||
|
||||
### 3.3 预付记录单据状态名(`src/utils/settlementStatus.js`,两个编辑器共用)
|
||||
|
||||
| 值 | 名称 |
|
||||
|---|---|
|
||||
| `reviewing` | 审批中 |
|
||||
| `approved` | 审批通过 |
|
||||
| `paid` | 已付款 |
|
||||
| `returned` | 已驳回 |
|
||||
| `voided` | 已作废 |
|
||||
| `draft` | 草稿 |
|
||||
|
||||
### 3.4 正式结算单付款记录合并表(只读)
|
||||
|
||||
一张表三类型,按「付款类型」列区分:**进度预付**(来源预结算 `PreSettlementAdvance` 台账)/ **项目预付核销**(核销行,金额=本次核销额)/ **结算尾款**。列名统一为「**申请/核销金额**」;创建时间统一取**底层付款申请创建时间**。
|
||||
|
||||
---
|
||||
|
||||
## 四、逆向与异常场景
|
||||
|
||||
| 场景 | 触发 | 系统行为 |
|
||||
|---|---|---|
|
||||
| 付款申请作废(仅 approved) | 付款申请列表「作废」(非金蝶锁定) | 金蝶锁单中禁止作废;汇票付款释放票据余额;**联动作废未付预付记录 + 删除其核销行并刷新受影响正式结算单汇总**(已付事实不回退) |
|
||||
| 正式结算单作废 | 结算单列表「作废」 | 删本单 FORMAL 核销行,额度释放、详情无残留 |
|
||||
| 金蝶删单回调(`voidByKingdee`) | 金蝶侧反审核删除 | 同上,删本单核销行 |
|
||||
| 预结算单作废 | 预结算列表「作废」 | 存在关联预付申请需先作废预付;删 PRE 核销行 |
|
||||
| 预付记录作废 | 预付台账 | 已付款的不能作废 |
|
||||
| 金蝶反审核(解锁) | A103-2 连续两轮查不到已推单据 | 判定金蝶侧已删 → `unlockBill` 置 `failed`、清空金蝶单号/内码、**联动作废未付预付记录**(已付不回退);重推后重新建档。**此场景不删核销行**(预付申请仍 approved,核销继续计入),人工作废后才回落 |
|
||||
| 推送失败 | A103-2/A102-2/A302-2/A303-1 报错 | 落 `failed` → `KingdeeAutoSyncRetryTask` 每 10 分钟自动重推;页面「同步金蝶」/「批量同步」手动兜底;审批接口把失败原因带回前端 warning,审批结果不受影响 |
|
||||
| 结算调整(金额变更) | 「结算调整单」 | 调整落库前校验**核销合计 ≤ 新结算金额**,超出拒绝并提示先调减核销;落库后 `refreshPaymentSummary` 重算。调整重推:核销行**迁移到新单**(克隆 + 删原单行 + 批量刷新两单),原单作历史存档,收付口径以新单为准 |
|
||||
| 全额核销 / 已结清 | `paymentStatus=paid` | `isSettlementCompleted` 拦截,不允许再发起结算调整(已确认"全额抵扣即结清") |
|
||||
|
||||
---
|
||||
|
||||
## 五、接口与数据表索引
|
||||
|
||||
### 5.1 后端接口
|
||||
|
||||
| 模块 | 主要接口(`/blade-transport` 网关前缀) |
|
||||
|---|---|
|
||||
| 预结算单 | `GET /pre-settlement/list|detail`;`POST /pre-settlement/save|submit|approve|return|void`;`POST /pre-settlement/formal-settlement`(轻量标记转正式) |
|
||||
| 付款申请 | `GET /payment-application/list|detail|reference-amount|project-advance-write-off-options`;`POST /payment-application/save|submit|approve|return|void|sync-kingdee|sync-kingdee-batch|sync-kingdee-result` |
|
||||
| 正式结算单 | `GET /formal-settlement/list|detail|candidate-pre-settlements|contract-options`;`POST /formal-settlement/save|submit|approve|return|void|sync-kingdee|sync-kingdee-ar-result|retry-kingdee-bill-lock|apply-payment|apply-payments|claim-invoices` |
|
||||
| 开票申请 | `GET /invoice-application/list|detail|settlement-candidates|settlement-details|receiver-information`;`POST /invoice-application/save|remove|submit|approve|return|void|sync-kingdee|sync-kingdee-invoice-result` |
|
||||
|
||||
### 5.2 核心数据表
|
||||
|
||||
| 表/实体 | 作用 |
|
||||
|---|---|
|
||||
| `PreSettlement` | 预结算单;预付汇总 `advanceNo / advanceAppliedAmount / advancePaidAmount`、`formalSettlementNo` |
|
||||
| `PreSettlementAdvance` | 预结算预付台账;`advanceNo`(=FKD 单号)、`billStatus`、`kingdeeAdvanceNo` |
|
||||
| `PaymentApplication` | 付款申请(三种 paymentType) |
|
||||
| `PaymentApplicationSettlement` | 付款申请 ↔ 结算单关系及分摊 |
|
||||
| `PaymentApplicationRecord` | 付款记录(A103-4 回填,`voucherJson` 留档) |
|
||||
| `FormalSettlement` | 正式结算单;`settlementAmount / appliedPaymentAmount / paidAmount / remainingPayableAmount / paymentStatus / kingdeeSyncStatus / invoiceStatus` |
|
||||
| `FormalSettlementSource` | 来源预结算/明细快照,冗余预付汇总 |
|
||||
| `FormalSettlementPayment` | 正式结算单尾款付款记录(`paymentType=final`) |
|
||||
| `SettlementProjectAdvanceWriteOff` | 项目预付核销行(`settlementType`:PRE / FORMAL) |
|
||||
| `InvoiceApplication` / `InvoiceApplicationSettlement` / `InvoiceApplicationSheet` / `InvoiceApplicationLine` / `InvoiceApplicationInvoice` | 开票申请主单 / 结算单关联与分摊 / 发票张次 / 商品行 / 金蝶回写发票 |
|
||||
|
||||
### 5.3 前端页面
|
||||
|
||||
| 页面 | 路径 |
|
||||
|---|---|
|
||||
| 预结算单列表/表单 | `src/views/settlement/pre-settlement.vue`、`pre-settlement-form.vue`、`components/pre-settlement-editor.vue` |
|
||||
| 正式结算单列表/表单 | `src/views/settlement/formal-settlement.vue`、`formal-settlement-form.vue`、`components/formal-settlement-editor.vue` |
|
||||
| 项目预付核销组件 | `src/views/settlement/components/project-advance-write-off.vue` |
|
||||
| 付款申请列表/表单 | `src/views/payment/payment-application.vue`、`payment-application-form.vue` |
|
||||
| 开票申请列表/表单 | `src/views/payment/invoice-application.vue`、`invoice-application-form.vue` |
|
||||
| 状态名公共工具 | `src/utils/settlementStatus.js`、`src/option/settlement/formalSettlementSearch.js` |
|
||||
|
||||
---
|
||||
|
||||
## 六、已知口径与风险
|
||||
|
||||
1. **尾款默认可付额** = 结算金额 − 累计尾款申请 − 核销,**不扣进度预付已付部分**(既有口径)。进度预付占大头时默认额可能偏大,由审批环节把关。
|
||||
2. **正式结算单 `paidAmount` 现含核销**,下游消费该字段的报表/对账单口径随之变化(对账已确认接受)。
|
||||
3. **金蝶侧预付抵扣字段**(`y_billtype / y_billid / y_settleamt`)本期**不传**,金蝶报表与本系统"已付含核销"存在时间差(待业务确认后迭代)。
|
||||
4. **预开票未落地**:预结算直接开票需先按方案改造 `doSyncKingdee` 门禁与数据模型。
|
||||
5. 存量"approved 未 paid"的核销行未做数据修正(`replaceWriteOffs` 只约束新保存),如需清洗另出脚本。
|
||||
6. 应收侧预收/收款认领(ReceiptClaim)与收票流程未在本文展开。
|
||||
Reference in New Issue
Block a user