实现 M009 手工开票前端页面

This commit is contained in:
andy
2026-07-17 11:57:26 +07:00
parent 11478c6913
commit 72fee44a68
16 changed files with 2032 additions and 3 deletions

View File

@@ -931,7 +931,94 @@ GET /api/reservation/task-card-field-whitelist
}
```
## 12. 已确认后置接口
## 12. Manual Invoice 手工开票生成接口
M009 后端 CP2 已实现,前端 V1 已接入 `/reservation/invoices/new`,可以在无订单 / 无任务数据时独立生成 Proforma Invoice。该接口是正式业务开票生成入口不走 M008 调试上传 access key。
路径:
```text
POST /api/reservation/invoices/manual-generations
```
入参:
```json
{
"hotel_id": "HOTEL-TEST",
"source_type": "MANUAL",
"task_id": null,
"order_id": null,
"template_code": "PROFORMA_INVOICE_V1",
"invoice_payload": {
"document": {
"invoice_date": "2026-07-17",
"booking_date": "2026-07-12",
"due_date": "2026-07-22"
},
"recipient": {
"company_code": "LIAN_TAI",
"contact_id": "LIAN_TAI_KHUN_ANN",
"company": "LIAN TAI TRAVEL (THAILAND) CO., LTD.",
"attention": "Khun Ann",
"address": "2/86 Rajpattana Road, Rajpattana, Sapansoong, Bangkok, TH, 10240",
"telephone": "061-397-2675",
"email": "op.liantaitravel@gmail.com"
},
"booking": {
"group_name": "GRP-DEMO-0802",
"arrival_date": "2026-08-02",
"departure_date": "2026-08-05",
"room_rate_note": "includingBF",
"extra_bed_rate": 1200
},
"charges": [
{
"description": "GRP-DEMO-0802",
"room_type": "Deluxe Room",
"quantity": 2,
"rate": 3000,
"nights": 3
}
]
}
}
```
返参:
```json
{
"invoice_generation_id": "2080000000000000001",
"generation_status": "SUCCEEDED",
"pdf_url": "https://oss.example.test/reservation-invoices/HOTEL-TEST/2026-07-17/.../proforma-invoice.pdf",
"pdf_object_key": "reservation-invoices/HOTEL-TEST/2026-07-17/.../proforma-invoice.pdf",
"generated_excel_object_key": "reservation-invoices/HOTEL-TEST/2026-07-17/.../proforma-invoice.xlsx",
"totals": {
"subtotal": 16822.43,
"vat": 1177.57,
"total": 18000.00,
"currency": "THB"
},
"created_at": "2026-07-17T03:30:00Z"
}
```
前端诉求:
- 前端已按 `RESERVATION_INVOICE_GENERATE` 做路由权限保护;侧边栏是否展示仍取决于登录态后端返回的 `menus[]`
- 如需在菜单中展示,建议后端 / 管理员配置 `menu_code=RESERVATION_MANUAL_INVOICE``route_path=/reservation/invoices/new``permission_code=RESERVATION_INVOICE_GENERATE`
- 该接口必须支持 `source_type=MANUAL``task_id` / `order_id` 为空。
- 如果前端同时传 `task_id``order_id`,必须保证任务属于该订单;后端不一致时返回 `RESERVATION_INVOICE_CONTEXT_MISMATCH`
- `recipient.company_code``recipient.contact_id` 用于表达目录选择结果;`company``attention``address``telephone``email` 是最终用于生成 PDF 的文本值Manual 覆盖时也必须提交。
- 后端需要重新计算金额、VAT 和合计;前端计算只做预览。
- 后端需要返回可预览 / 下载的 PDF URL。
- 该接口应走 Bearer 登录、酒店访问权和 `RESERVATION_INVOICE_GENERATE` 权限,不走 M008 调试上传 access key。
- 第一版最多支持 10 条 `charges[]`;超过 10 条会返回 `RESERVATION_INVOICE_VALIDATION_FAILED`
- 第一版只支持 `template_code=PROFORMA_INVOICE_V1`,模板文件由后端受控维护。
- 第一版已写入 `workflow_reservation_invoice_generation` 生成记录和业务审计,但暂不提供前端查询历史列表 / 详情接口。
## 13. 已确认后置接口
普通任务切换订单接口继续后置,前端暂不开发提交能力。后续如果恢复开发,建议另行确认:
@@ -960,7 +1047,7 @@ POST /api/reservation/tasks/{taskId}/order-binding
}
```
## 13. 待确认问题
## 14. 待确认问题
- 订单列表、任务列表当前统一使用 `items + page` 分页结构;邮件会话详情不分页,返回同一会话全部邮件。
- 邮件会话详情接口已优先使用 `GET /api/source-messages/{sourceMessageId}/conversation`
@@ -970,3 +1057,4 @@ POST /api/reservation/tasks/{taskId}/order-binding
- `GET /api/reservation/tasks` 结构化 S10/S99 行的 `task_type` 返回值请后端最终确认:前端已兼容 `SOURCE_MESSAGE_ONLY``MESSAGE_NOTIFICATION`,但文档口径最好稳定一个。
- `manual-review-resolutions` 成功响应中的 `opera_operations[]` 数量请后端最终确认;前端不写死两条,只按返回内容刷新展示。
- 系统管理菜单树增强接口已完成:`GET /api/admin/menus/tree``PUT /api/admin/menus/tree-order`
- Manual Invoice 第一阶段的客户 / 联系人目录来源、模板初始文件、VAT 配置和生成记录是否必须落库,已在 M009 中列为开发前确认项。