|
|
@@ -0,0 +1,131 @@
|
|
|
+# 报销提交允许发票夹余额为负 — 设计文档
|
|
|
+
|
|
|
+> **日期**: 2026-08-12
|
|
|
+> **状态**: 待实现
|
|
|
+> **仓库**: shanxia2.0(`backend/` + `web-admin/` + `bx-mobile/`)
|
|
|
+> **前置 / 修订**:
|
|
|
+> - `docs/superpowers/specs/2026-07-25-invoice-wallet-reimburse-design.md`(原规则:余额不足不可提交)
|
|
|
+> - `docs/business-inventory/03-报销业务明细.md`
|
|
|
+
|
|
|
+## 背景与问题
|
|
|
+
|
|
|
+发票夹上线后,报销「提交审批」要求申请人发票夹余额 ≥ 报销合计;不足则前后端均拦截。业务方希望:额度不足也可提交,因为申请人会**后续独立在发票夹补票**。
|
|
|
+
|
|
|
+## 已确认决策
|
|
|
+
|
|
|
+| # | 决策 | 说明 |
|
|
|
+|---|------|------|
|
|
|
+| D1 | **仍全额占用** | 提交时照常写 `debit_reimburse`;允许 `balance` 变为负 |
|
|
|
+| D2 | **全端一致** | 后端 + Web 报销申请 + `bx-mobile` 统一放开;小程序当前无此校验,本期不改 |
|
|
|
+| D3 | **弱提示、不拦截** | 保留「当前余额 / 本次合计」;不足时提示「余额不足,提交后余额将为负,请后续补发票」 |
|
|
|
+| D4 | **删票保护不变** | 删票冲减后余额不得为负(`assert_can_delete_invoice`) |
|
|
|
+| D5 | **不做** | 审批/发放页负余额二次提醒;提交部分占用;延后扣账;关联发票金额覆盖校验 |
|
|
|
+
|
|
|
+相对 `2026-07-25-invoice-wallet-reimburse-design`:**硬门槛「余额 ≥ 申请金额」废止**;扣/退时机与流水类型不变。冲突时以本文为准。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 一、目标与范围
|
|
|
+
|
|
|
+### 目标
|
|
|
+
|
|
|
+报销提交审批不再因发票夹余额不足失败。提交仍按合计全额占用;申请人后续补票使余额回升。
|
|
|
+
|
|
|
+### 范围内
|
|
|
+
|
|
|
+- 后端:`InvoiceLedgerService.debit_reimburse` 去掉余额不足拦截
|
|
|
+- Web:`web-admin/src/views/bx/reimburse/apply/index.vue` 去掉提交拦截与强警告文案
|
|
|
+- 移动:`bx-mobile/src/views/reimburse/ReimburseApplyPage.vue` 同上
|
|
|
+- 文档:业务清单与相关表述同步
|
|
|
+
|
|
|
+### 范围外
|
|
|
+
|
|
|
+- 不改扣账时机(仍在 submit)
|
|
|
+- 不改驳回/撤回释放、submit 幂等
|
|
|
+- 不加审批/发放提醒
|
|
|
+- 不改 miniprogram
|
|
|
+- 不做补票后差额自动核销等新能力
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 二、行为规则
|
|
|
+
|
|
|
+### 2.1 提交占用
|
|
|
+
|
|
|
+1. 业务校验通过后,按报销合计写全额 `debit_reimburse`。
|
|
|
+2. **不再**因 `balance < amount` 抛错或前端拦截。
|
|
|
+3. 驳回 / 撤回仍写 `credit_release`(现有逻辑)。
|
|
|
+4. 同一单已有有效占用则跳过再扣(现有幂等)。
|
|
|
+
|
|
|
+### 2.2 余额语义
|
|
|
+
|
|
|
+```
|
|
|
+balance = Σ(credit_upload) − Σ(debit_delete) − Σ(debit_reimburse) + Σ(credit_release)
|
|
|
+```
|
|
|
+
|
|
|
+- 允许 `balance < 0`。
|
|
|
+- 负余额含义:已提交占用超过已上传发票总额;补票(`credit_upload`)后回升。
|
|
|
+- 删票:若冲减后余额将 < 0,仍拒绝(防止用删票抵消占用)。
|
|
|
+
|
|
|
+### 2.3 关联发票
|
|
|
+
|
|
|
+仍为可选;不要求关联票面金额覆盖报销合计。
|
|
|
+
|
|
|
+### 2.4 并发
|
|
|
+
|
|
|
+仍对 `BxInvoiceWalletSummary` 使用 `with_for_update()`;仅取消「余额不足拒绝」条件。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 三、改动点
|
|
|
+
|
|
|
+### 3.1 后端
|
|
|
+
|
|
|
+| 位置 | 改动 |
|
|
|
+|------|------|
|
|
|
+| `backend/app/services/bx/invoice_ledger.py` → `debit_reimburse` | 删除 `if balance < amt: raise HTTPException(...)` |
|
|
|
+| `release_reimburse` / `assert_can_delete_invoice` / `calc_summary` | 不改 |
|
|
|
+
|
|
|
+### 3.2 Web(`web-admin`)
|
|
|
+
|
|
|
+| 位置 | 改动 |
|
|
|
+|------|------|
|
|
|
+| 申请弹窗余额区 | 保留余额与合计;不足时弱提示改为「余额不足,提交后余额将为负,请后续补发票」;删除「提交时将被拦截」 |
|
|
|
+| `handleToolbarSubmit` / `handleSubmit` | 删除提交前余额不足 `return` |
|
|
|
+| `submitAdd`(存草稿) | 本就不拦,无需改逻辑 |
|
|
|
+
|
|
|
+### 3.3 bx-mobile
|
|
|
+
|
|
|
+| 位置 | 改动 |
|
|
|
+|------|------|
|
|
|
+| 申请页余额提示 | 去掉「无法提交」类文案;改为与 Web 一致的弱提示 |
|
|
|
+| 保存成功对话框 | 去掉「请先充值发票夹后再提交」;不足时仍可点「提交审批」 |
|
|
|
+| 确认提交分支 | 删除 `balanceInsufficient` 时 toast「余额不足,无法提交」并 return |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 四、验收标准
|
|
|
+
|
|
|
+1. 余额 < 报销合计时,Web 与 bx-mobile 均可成功提交审批。
|
|
|
+2. 提交后余额减少(可为负);流水存在对应 `debit_reimburse`。
|
|
|
+3. 申请页仍展示余额与合计;不足仅弱提示,无拦截文案。
|
|
|
+4. 余额充足时行为与现网一致。
|
|
|
+5. 驳回 / 撤回后占用释放,余额回升。
|
|
|
+6. 删票在冲减后余额将 < 0 时仍拒绝。
|
|
|
+7. 后续补票可使负余额回到 ≥ 0。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 五、文档同步(实现时)
|
|
|
+
|
|
|
+- 更新 `docs/business-inventory/03-报销业务明细.md` 额度规则:「提交全额占用,余额可为负;不足不拦截」。
|
|
|
+- 实现计划另见 `docs/superpowers/plans/`(实现前由 writing-plans 产出)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 六、非目标
|
|
|
+
|
|
|
+- 审批/发放页负余额提醒
|
|
|
+- 部分占用或延后扣账
|
|
|
+- 关联发票必填 / 金额覆盖硬校验
|
|
|
+- miniprogram 改造
|