tangweijie d8b2416f12 docs: 补齐 REV-005 作废红冲设计与任务
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 12:36:50 +08:00

203 lines
11 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.

# Feature Specification: REV-005 发票业务流实现
**Feature Branch**: `002-rev005-invoice-flow`
**Created**: 2026-03-16
**Status**: Verification Pending
**Input**: 实现 REV-005 发票业务流核心功能:发票申请、开票校验、调用 SYS-008 发票服务、接收开票结果回写、更新发票与账单关联状态。
---
## Document Scope & Sources
- **Target documents**:
- `docs/design/02_Detailed_Design/12_REV_Detailed.md`REV-005 章节补充)
- `docs/design/03_Technical_Design/03_Interface_Design.md`IF-REV-008 发票申请接口、IF-REV-009 发票查询接口定义)
- Backend: `backend/sw-business/sw-business-server` 新增 Service/Controller
- **Primary source of truth**:
- `docs/design/02_Detailed_Design/12_REV_Detailed.md` 中 REV-005 定义
- `docs/guides/BACKEND_CURRENT_STATUS.md`
- `docs/guides/BACKEND_TABLE_MAPPING.md`
- **Reference sources**:
- Archive: `docs/design/04_Appendix/Archive/03_Design_Docs/营业收费管理系统-概要设计说明书20250912.md`
- Existing: `InvoiceController.java`, `InvoiceServiceImpl.java`
- **Scope decision**: 在已有基础数据层(开票配置、客户开票信息、税率配置)之上,补齐发票申请、开具、结果回写的完整业务流程。
---
## User Scenarios & Testing
### User Story 1 - 发票申请与校验 (Priority: P1)
营业收费员或财务人员通过后台系统提交发票申请,系统校验账单状态、开票信息完整性和开票限额,生成发票申请记录。客户侧一期不直接发起开票申请,仅支持查询、下载、推送已开具的电子发票。
**Why this priority**: 发票申请是业务流程入口,必须优先实现。
**Independent Test**: 验证发票申请接口可接收申请,校验规则生效,申请记录正确落库。
**Acceptance Scenarios**:
1. **Given** 账单已缴费且未开票,客户开票信息完整,**When** 提交发票申请,**Then** 生成发票申请记录,返回申请单号
2. **Given** 账单未缴费,**When** 提交发票申请,**Then** 拒绝申请,提示"账单未缴费不可开票"
3. **Given** 账单已开票,**When** 提交发票申请,**Then** 拒绝申请,提示"账单已开票"
4. **Given** 开票金额超过限额,**When** 提交发票申请,**Then** 拒绝申请,提示"超过开票限额"
5. **Given** 同一原始账单被要求直接拆分为多次部分开票,**When** 提交发票申请,**Then** 拒绝直接部分开票,并提示需先按老系统口径完成拆账/分账后再分别开票
---
### User Story 2 - 调用发票服务开票 (Priority: P1)
系统根据申请记录调用 SYS-008 发票服务完成开票,采用“异步申请 + 查询兜底”模式记录受理结果并主动查询最终状态。
**Why this priority**: 核心开票能力,必须实现与外部系统的对接。
**Independent Test**: 验证系统可正确组装开票参数,调用外部服务,处理返回结果。
**Acceptance Scenarios**:
1. **Given** 发票申请已校验通过,**When** 调用 SYS-008 开票接口,**Then** 正确传递账单、客户、税率信息
2. **Given** 外部服务返回开票成功,**When** 系统通过查询获取结果并回写状态,**Then** 更新发票状态为"已开票",记录发票代码号码
3. **Given** 外部服务返回开票失败,**When** 系统通过查询获取结果并回写状态,**Then** 更新发票状态为"开票失败",记录失败原因
4. **Given** 外部服务超时,**When** 发起查询,**Then** 可查询开票结果状态
---
### User Story 3 - 发票结果回写与关联 (Priority: P2)
开票成功后更新账单发票状态,建立发票与账单关联,支持电子发票推送。
**Why this priority**: 保证账单与发票数据一致性,支持后续查询和下载。
**Independent Test**: 验证开票结果正确回写账单状态,关联关系可查。
**Acceptance Scenarios**:
1. **Given** 开票成功,**When** 回写结果,**Then** 账单发票状态更新,建立 invoice-charge 关联
2. **Given** 电子发票生成,**When** 客户请求下载,**Then** 返回电子发票文件或下载链接
3. **Given** 发票已关联账单,**When** 查询账单详情,**Then** 显示关联的发票信息
---
### User Story 4 - 发票作废与红冲 (Priority: P3)
对已成功开具的发票提供后台作废与红冲入口,由 `SYS-008` 承接税控侧处理,`SYS-002` 负责发起申请、校验状态、查询补偿、结果回写与账单关联状态同步;客户侧仍仅消费有效电子发票结果,不直接发起作废或红冲。
**Why this priority**: 作废与红冲属于已开票后的后处理能力,依赖正常开票闭环,但必须在本轮二期中形成正式设计与 backend 实现入口。
**Independent Test**: 验证后台可对满足条件的成功发票发起作废或红冲;`SYS-008` 返回结果后,发票状态正确更新为 `INVALID``RED_INK`,并保留原票关联、失败原因与操作日志。
**Acceptance Scenarios**:
1. **Given** 发票状态为 `SUCCESS` 且未作废、未红冲,**When** 后台发起作废申请,**Then** 系统校验通过并调用 `SYS-008`,成功后将发票状态更新为 `INVALID`
2. **Given** 发票状态为 `SUCCESS` 且业务要求通过红字发票冲销,**When** 后台发起红冲申请,**Then** 系统校验通过并调用 `SYS-008`,成功后将发票状态更新为 `RED_INK`
3. **Given** 发票已处于 `INVALID``RED_INK`**When** 再次发起作废或红冲,**Then** 系统拒绝重复处理并返回明确原因
4. **Given** `SYS-008` 未立即返回终态,**When** 系统执行主动查询或补偿查询,**Then** 保持处理中上下文并在取得终态后统一落账
---
### Edge Cases
- 外部发票服务不可用时的降级处理
- 重复提交同一账单的发票申请(幂等控制)
- 开票过程中账单状态发生变化
- 拆账/分账后的多账单分别开票与原始单账单直接部分开票的边界判定
---
## Requirements
### Functional Requirements
- **FR-001**: 系统 MUST 提供后台发票申请接口接收账单ID、开票类型普票/专票)等参数,并支持单笔或批量选择已收费账单发起开票
- **FR-002**: 系统 MUST 校验账单状态(已缴费、未开票)
- **FR-003**: 系统 MUST 校验客户开票信息完整性
- **FR-004**: 系统 MUST 校验开票限额
- **FR-005**: 系统 MUST 生成发票申请记录,包含申请单号、状态、时间戳
- **FR-006**: 系统 MUST 调用 SYS-008 发票服务完成开票
- **FR-007**: 系统 MUST 支持通过定时查询获取异步开票结果(轮询 SYS-008 查询接口)
- **FR-008**: 系统 MUST 更新发票状态(申请中/已开票/开票失败)
- **FR-009**: 系统 MUST 建立发票与账单的关联关系,并保留兼容老系统拆账/分账后分别开票及后续合并开票扩展的映射能力
- **FR-010**: 系统 MUST 支持客户侧查询、下载、推送已开具的电子发票,但一期不开放客户侧直接申请开票
- **FR-011**: 系统 MUST 记录关键操作日志(申请、查询、开票、结果回写、客户侧查询/下载/推送、作废、红冲),并保留触发来源、状态前后值与失败原因
- **FR-012**: 系统 MUST 提供后台发票作废入口,仅允许对已开票成功且未作废、未红冲的发票发起作废
- **FR-013**: 系统 MUST 提供后台发票红冲入口,仅允许对已开票成功且未红冲的发票发起红字冲销,并保留原票关联信息
- **FR-014**: 系统 MUST 通过查询补偿或结果回写统一落账作废/红冲终态,并同步更新发票状态、失败原因和账单发票关联状态
### Key Entities
- **发票申请单** (InvoiceApplication): 申请单号、账单ID、客户ID、申请金额、开票类型、状态
- **发票记录** (InvoiceRecord): 发票ID、申请单号、发票代码、发票号码、开票日期、金额、状态
- **账单发票关联** (ChargeInvoiceRelation): 账单ID、发票ID、关联类型全额/拆账后分别开票/后续合并扩展)
- **开票查询记录** (InvoiceQueryLog): 查询ID、申请单号、查询时间、查询结果、处理状态
---
## Success Criteria
### Measurable Outcomes
- **SC-001**: 发票申请接口响应时间 < 500ms不包含外部服务调用
- **SC-002**: 发票申请校验通过率 > 95%(正常业务场景)
- **SC-003**: 开票结果回写成功率 > 99%
- **SC-004**: 电子发票下载成功率 > 99%
- **SC-005**: 操作日志完整率 100%(所有关键操作均有日志)
### Business Outcomes
- 营业收费员可通过系统完成发票申请到开票的全流程
- 客户可通过渠道查询和下载电子发票
- 财务人员可追溯发票开具全过程
---
## Dependencies & Assumptions
### Dependencies
- SYS-008 发票服务接口已定义IF-REV-008
- 基础数据层已实现biz_invoice, biz_cust_invoice, biz_invoice_taxrate
- 账单系统REV-003已实现
### Assumptions
- SYS-008 提供标准 REST 接口供调用
- 电子发票文件由 SYS-008 生成并提供下载链接
- 开票限额在配置中预定义
### Scope Exclusions
- 不实现发票的物理打印功能
- 不实现与税务局的直接对接(由 SYS-008 承接)
- 不实现复杂的发票拆分合并逻辑MVP 版本)
---
## Risks & Mitigation
| 风险 | 影响 | 缓解措施 |
|-----|-----|---------|
| SYS-008 接口未就绪 | 无法联调 | 先实现 Mock 接口,定义好契约 |
| 发票状态同步异常 | 数据不一致 | 实现补偿机制,支持对账查询 |
| 并发开票冲突 | 重复开票 | 幂等控制,唯一申请单号 |
---
## Clarifications
### Session 2026-03-16
- **Q1**: SYS-008 发票服务结果获取方式 → **A**: 采用"异步+查询兜底"模式。提交开票申请后返回受理号,系统通过定时轮询查询结果接口获取开票状态(航信发票接口不支持回调,需主动查询)。
- **Q2**: 一期是否支持一张原始账单直接分多次部分开票 → **A**: 不支持对原始单账单直接任意部分金额开票;如需多张发票,沿用老系统口径,通过拆账/分账后的账单分别开票,并保留批量开票能力。
- **Q3**: 一期开放给哪些使用入口 → **A**: 采用“后台开票 + 客户侧查询下载”模式。后台营业收费员/财务人员负责申请和开具,客户侧仅支持查看、下载、推送已开票结果,不直接发起开票申请。
---
## Next Steps
1. 在可用测试或联调环境中补充 SC-001 的响应时延采样记录样本量、平均值、P95 与“排除外部调用”的统计口径。
2. 为 SC-002 ~ SC-004 准备样本集与统计表,将申请通过率、回写成功率、查询/下载/推送成功率沉淀到 `specs/002-rev005-invoice-flow/verification.md`
3. 抽取 SC-005 运行态日志样本,核对操作人、客户、状态与日志内容是否与实现态矩阵一致。
4. 继续跟踪 `biz_invoice` 物理 DDL / migration 来源,并在提测前明确联调、落库与批量后处理风险。