Files
docs/头程到尾程/正式申报与海关结果接入设计.md
T

129 lines
7.8 KiB
Markdown

# 正式申报与海关结果接入设计
本文只补 F22.7、F22.8 的业务对象和交互边界,不改变已经验收的退税报关基础闭环:客户上传退税资料 → 平台发送报关行 → 报关行回执 → 客户确认或打回 → 平台发送确认结果给报关行 → 平台上传真实报关完税文件。
## 一、先冻结现有边界
```text
LOADED
↓
客户退税资料齐全
↓ 平台开始报关,冻结资料范围和版本
DECLARING
↓ 报关行回执
客户确认整份回执 / 打回
↓ 平台发送客户确认结果给报关行
等待真实报关完税文件
↓ 每个退税客户均有完成文件
COMPLETED(平台已收到本轮完税文件)
↓
WAITING_FOR_LOADING(进入待发区)
```
`COMPLETED` 只表示平台收到本轮真实完税文件,不能解释为海关放行、正式申报成功或船舶已开航。正式申报批次可以在报关行执行后、完税文件回传前建立;PDA 只在上游产出 `LOADED`;待发区、送港、甩柜、改配和船舶实际开航属于运输线,不能由正式申报对象反向改写。
## 二、F22.7 正式申报批次
正式申报批次是平台授权人员人工提交后形成的独立事实,粒度为整柜一次申报批次。它引用当前柜级报关聚合和已冻结的客户资料/回执快照,不复制文件内容。
建议对象:`customs_declaration_batch`
| 字段 | 说明 |
|---|---|
| `id` | 平台长 ID,前端按字符串传输 |
| `customsContainerId` / `loadingPlanId` | 绑定整柜报关聚合和装柜计划,创建后不可换柜 |
| `batchNo` | 平台生成的批次号,人工提交前为空或草稿号 |
| `status` | `READY`、`SUBMITTED`、`ACKNOWLEDGED`、`RESULT_PENDING`、`CLOSED`、`CANCELLED` |
| `sourceVersion` | 提交时整柜报关聚合版本,防止提交后资料范围漂移 |
| `receiptSnapshot` | 提交时客户资料、回执、确认结果的客户范围和文件版本快照 |
| `customsEntryNo` | 报关单号,平台人工回填;同一有效批次唯一 |
| `submittedBy/submittedAt` | 平台提交人和时间 |
| `acknowledgedBy/acknowledgedAt` | 报关行或平台确认受理人和时间 |
| `remark` | 提交说明,长度受服务端限制 |
创建或提交门禁:
1. 柜级报关已进入 `DECLARING`,且整柜退税资料已覆盖实际装柜退税票;批次也允许在完税文件上传后的 `COMPLETED` 阶段补建。
2. 所有退税客户的当前回执均为 `CONFIRMED`。
3. 已执行发送动作,`brokerSubmittedAt` 已存在。
4. 提交使用版本号和幂等键;相同请求重放返回同一批次,不同载荷返回冲突。
5. 提交后禁止修改客户资料范围、回执和确认结果;补资料必须通过新批次或明确的退回重提动作产生新版本,不能覆盖历史批次。
建议平台接口:
- `GET /api/platform/v1/customs/loading-plans/{planId}/declaration-batches`
- `POST /api/platform/v1/customs/loading-plans/{planId}/declaration-batches`
- `POST /api/platform/v1/customs/loading-plans/declaration-batches/{batchId}/submit`
- 提交时在请求体回填 `customsEntryNo`,不另设独立改单接口。
客户端只读当前批次的可见投影,不提供提交和修改入口;客户只能看到自己资料覆盖的结果。
## 三、F22.8 海关结果事实
海关结果不是柜级状态字段,而是批次下的不可变事实记录。一次正式申报可以先产生“待结果”,之后根据实际回执追加查验、补资料、放行、扣货或其他结果;修正不能覆盖历史记录。
建议对象:`customs_clearance_result`
| 字段 | 说明 |
|---|---|
| `id` | 结果事实长 ID |
| `declarationBatchId` | 所属正式申报批次 |
| `resultType` | `INSPECTION`、`SUPPLEMENT_REQUIRED`、`RELEASED`、`DETAINED`、`OTHER` |
| `resultStatus` | `OPEN`、`RESOLVED`、`CANCELLED` |
| `customsEntryNo` | 报关单号快照,必须与批次一致 |
| `occurredAt` | 海关事实发生时间 |
| `recordedAt/recordedBy` | 平台录入时间和操作人 |
| `resolution` | 处理结果、补资料说明或扣货原因 |
| `evidenceFileId` | 可选结果凭证,文件由 File 保存,归属由 Firstleg 校验 |
| `previousResultId` | 更正或追加结果的前序事实,不能原地覆盖 |
结果门禁:
- `INSPECTION` 和 `SUPPLEMENT_REQUIRED` 未解决时,客户看到处理中/待补资料,平台不能显示放行。
- `RELEASED` 只表示海关放行事实,不自动写入送港、进港或实际开航。
- `DETAINED` 进入扣货/异常处理,保留原因和凭证,不自动删除报关文件。
- `OTHER` 必须有说明,不能用空状态吞掉未知海关结果。
- 只有平台授权人员可以新增或更正结果;客户只能读取自身可见的结果和凭证。
建议平台接口:
- `GET /api/platform/v1/customs/loading-plans/declaration-batches/{batchId}/results`
- `POST /api/platform/v1/customs/loading-plans/declaration-batches/{batchId}/results`
- `POST /api/platform/v1/customs/loading-plans/clearance-results/{resultId}/resolve`
- `GET /api/merchant/v1/customs/orders/{orderId}/clearance-results`
## 四、三端交互
| 参与方 | 可以做什么 | 不可以做什么 |
|---|---|---|
| 客户 | 上传/替换自身退税资料;查看并确认或打回整份回执;查看自身批次、报关单号、海关结果和凭证 | 不能查看同柜其他客户;不能提交正式申报;不能录入放行/扣货 |
| 平台报关人员 | 核对资料和回执;发送报关行;创建/提交正式申报批次;回填报关单号;录入和解决海关结果 | 不能用客户确认代替正式申报;不能用完税文件代替放行结果 |
| 报关行 | 线下处理申报并返回回执、报关单号和海关结果文件 | 不直接调用客户接口;所有回执和结果由平台留痕上传 |
| PDA/运输 | PDA 产出 `LOADED`;运输处理待发区、送港、进港、甩柜、改配和实际开航 | 不创建报关批次,不修改报关结果,不因甩柜重置资料或确认 |
## 五、状态投影
平台柜级状态继续保留当前四态,用新增投影补充信息:
| 现有状态 | 新增投影 | 客户文案 |
|---|---|---|
| `WAITING_CUSTOMER_DOCUMENTS` | 无有效批次 | 待上传退税报关资料 |
| `READY_TO_START` | 可开始报关 | 资料已齐,等待平台发送报关行 |
| `DECLARING` | 回执确认中/已发送报关行/正式申报中 | 报关处理中 |
| `COMPLETED` | 完税文件齐全,正式申报或结果可能仍未关闭 | 报关文件已完成,等待海关结果(如有) |
运输投影单独读取待发区和船期对象;甩柜只更新原柜船名、航次和时间历史,不变更批次、资料、回执、结果或客户确认。
## 六、最小验收矩阵
1. 未全部客户确认时创建/提交正式批次返回业务冲突,数据零漂移。
2. 同一幂等键重放返回同一批次;换参数返回冲突。
3. 提交后资料范围、回执和客户确认不可修改。
4. 同一批次可追加查验、补资料、放行、扣货和其他结果,历史顺序稳定。
5. 查验/补资料未解决时不显示放行;扣货保留原因和凭证。
6. 客户 A 不能读取客户 B 的批次、结果和文件。
7. 报关结果不推进送港、进港或实际开航;甩柜只改变原柜船期。
8. 正式申报和结果事实可以在报关 `COMPLETED` 后继续存在,不能把 `COMPLETED` 直接当成 `RELEASED`。
本设计已完成代码接入:Firstleg 建立正式申报批次和海关结果表、版本/幂等/审计门禁及平台/客户接口;Admin 页面提供创建、提交、录入和处理入口,Client 页面展示本订单可见结果。真实 HTTP 证据见 `baiyue-firstleg/reports/formal-customs-declaration-and-clearance-result-20260927.json`。当前仍保持 `COMPLETED`、海关放行、待发区和实际开航的状态边界,PDA 与船期不参与结果对象。