tangweijie 82d307bda6 docs: 补齐 REV-005 发票闭环设计与任务台账
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 00:45:21 +08:00

171 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Data Model: REV-005 发票业务流实现
## 建模原则
- 以“逻辑实体 + 现有在线主表承接 + 历史关系快照”三层表达,避免把旧系统全部 IV_* 细表误写为当前已落地在线表。
- 后台开票、客户侧查询下载、`SYS-008` 查询兜底、结果回写统一围绕单一发票申请主线建模。
- 一期不支持原始单账单直接任意部分开票,但关系模型需兼容拆账/分账后的多账单、多发票映射扩展。
## 实体一InvoiceApplication发票申请单
### 作用
统一承接后台单笔/批量已收费账单的发票申请输入,是 `IF-REV-008` 的主业务对象。
### 核心字段
| 字段 | 类型 | 说明 |
|------|------|------|
| applicationNo | String | 发票申请单号 / 协同请求号 |
| chargeIds | Array<Long> | 关联账单 ID 列表 |
| custId | Long | 客户 ID |
| invoiceType | Enum | `ELECTRONIC` / `PAPER` |
| invoiceTitle | String | 发票抬头 |
| taxNo | String | 纳税人识别号 |
| invoiceAmount | Decimal | 本次申请开票总金额 |
| receiverEmail | String | 电子票接收邮箱 |
| receiverMobile | String | 电子票接收手机号 |
| sourceChannel | Enum | `COUNTER` / `FINANCE_BACKOFFICE` |
| applyStatus | Enum | `SUBMITTED` / `ACCEPTED` / `REJECTED` |
| appliedAt | DateTime | 申请时间 |
### 校验规则
- `chargeIds``custId``invoiceType``invoiceTitle` 必填。
- 账单必须满足“已收费、未开票、未作废”。
- 原始单账单不允许直接任意部分金额开票;如需多张发票应来源于拆账/分账后的账单集合。
- 对同一账单组合的重复申请需按 `applicationNo``custId + chargeIds` 做幂等控制。
### 物理承接
- 主承接:`biz_invoice`
- 关联输入:`biz_cust_invoice``biz_charge*`
## 实体二InvoiceRecord发票记录
### 作用
描述发票服务受理、开具成功/失败、票号回写、电子票文件地址等结果信息。
### 核心字段
| 字段 | 类型 | 说明 |
|------|------|------|
| invoiceId | Long | 发票记录 ID |
| applicationNo | String | 对应申请单号 |
| sysRequestNo | String | `SYS-008` 受理号 / 外部请求号 |
| invoiceStatus | Enum | `PENDING` / `SUCCESS` / `FAIL` / `INVALID` / `RED_INK` |
| invoiceCode | String | 发票代码 |
| invoiceNumber | String | 发票号码 |
| invoiceDate | DateTime | 开票日期 |
| fileUrl | String | 电子发票下载地址 |
| failReason | String | 开票失败原因 |
| pushStatus | Enum | `NONE` / `PUSHED` / `FAIL` |
| updatedAt | DateTime | 最近状态更新时间 |
### 状态关系
- `PENDING` 表示已提交给 `SYS-008` 但尚未确认最终结果。
- `SUCCESS` 后允许客户侧查询、下载、推送电子发票。
- `FAIL` 记录失败原因并进入异常核查或人工重试。
### 物理承接
- 主承接:`biz_invoice`
- 历史参照:旧 `IV_INVOICE_INFOS`
## 实体三ChargeInvoiceRelation账单-发票关联)
### 作用
承接账单与发票的映射关系,支持单票对应多账单、拆账后分别开票和后续合并开票扩展。
### 核心字段
| 字段 | 类型 | 说明 |
|------|------|------|
| relationId | Long | 关联记录 ID |
| chargeId | Long | 账单 ID |
| invoiceId | Long | 发票 ID |
| applicationNo | String | 申请单号 |
| relationType | Enum | `FULL_AMOUNT` / `SPLIT_BILL` / `MERGED_BILL` |
| invoiceAmount | Decimal | 当前账单对应开票金额 |
| relationStatus | Enum | `PENDING` / `BOUND` / `FAILED` |
| snapshotVersion | String | 开票配置/税率快照版本 |
### 关键规则
- 一期默认 `relationType=FULL_AMOUNT``SPLIT_BILL`(来自拆账后的账单),不支持对原始单账单直接自由部分金额开票。
- 发票成功后必须把关系状态更新为 `BOUND`,并可供账单详情查询。
### 物理承接
- 在线主承接:`biz_invoice` + 历史关系快照
- 历史参照:旧 `IV_CHARGE_INVOICES``IV_CHARGE_INVOICE_MAPPINGS`
## 实体四InvoiceQueryTask开票查询补偿任务
### 作用
支持异步申请后的轮询查询、超时补偿和人工兜底查询,是“查询兜底”模式的核心对象。
### 核心字段
| 字段 | 类型 | 说明 |
|------|------|------|
| queryTaskId | Long | 查询任务 ID |
| applicationNo | String | 申请单号 |
| sysRequestNo | String | 外部受理号 |
| lastTryTime | DateTime | 最后一次查询时间 |
| nextTryTime | DateTime | 下一次查询时间 |
| tryCount | Integer | 已查询次数 |
| queryStatus | Enum | `WAITING` / `RUNNING` / `DONE` / `FAILED` |
| latestResult | String | 最近一次查询结果摘要 |
| latestError | String | 最近一次查询错误 |
### 关键规则
- 申请成功后默认生成查询任务。
- 查询到终态后任务进入 `DONE`
- 查询异常不应覆盖已成功开票状态,只记录异常并等待人工或系统补偿。
### 物理承接
- 主承接:`biz_invoice` 扩展字段或关联查询日志对象
- 历史参照:旧发票表中的 `last_try_time``next_try_time``try_count`
## 实体五InvoiceResultWriteBack结果回写
### 作用
统一描述 `SYS-008` 查询结果或主动回传结果进入营收域后的状态变更、幂等控制和操作留痕。
### 核心字段
| 字段 | 类型 | 说明 |
|------|------|------|
| writeBackNo | String | 回写流水号 |
| applicationNo | String | 申请单号 |
| invoiceStatus | Enum | 发票状态 |
| writeBackStatus | Enum | `SUCCESS` / `IGNORE_REPEAT` / `FAIL` |
| invoiceCode | String | 发票代码 |
| invoiceNumber | String | 发票号码 |
| fileUrl | String | 下载地址 |
| rawPayload | String | 原始回写/查询响应 |
| processedAt | DateTime | 处理时间 |
| processedBy | String | 系统任务 / 人工处理人 |
### 关键规则
-`applicationNo + invoiceStatus` 做幂等控制。
- 已成功开票后收到失败结果,不覆盖成功状态,转入异常核查。
- 所有回写处理必须记录到操作留痕对象。
### 物理承接
- 主承接:`biz_invoice` + `biz_operat_log*`
## 关系总览
```text
InvoiceApplication --> InvoiceRecord
InvoiceApplication --> ChargeInvoiceRelation
InvoiceApplication --> InvoiceQueryTask
InvoiceRecord --> InvoiceResultWriteBack
ChargeInvoiceRelation --> biz_charge* (N:1)
InvoiceApplication --> biz_cust_invoice
InvoiceApplication --> biz_invoice_taxrate
InvoiceResultWriteBack --> biz_operat_log*
```
## 状态与边界说明
- 一期默认后台申请、客户侧结果消费,不定义客户侧直接申请状态机。
- 作废、红冲作为 REV-005 后续能力保留在数据模型中,但 implement 时优先保证正常开票闭环。
- 旧发票明细、营业账开票关系、配置快照对象在当前阶段仅作为历史参照和追溯来源,不表述为已确认新增在线独立表。