实现 M009 手工开票前端页面
This commit is contained in:
@@ -60,7 +60,7 @@
|
||||
- 用户 / 权限底座后端 CP1 已完成;前端登录页、动态菜单、管理后台和业务审计 actor 全量迁移仍后置。
|
||||
- 真实 OPERA / OHIP 接入后置;当前仅有 OPERA 模拟骨架。
|
||||
- 任务卡字段控件契约 V1 后端第一版已完成,任务详情 `fields[]` 已返回 `control_type/edit_scope/write_target/options_source/raw_readonly/control_hint`;前端后续按契约接入,不要硬编码 PMS 房型、Rate Code 或未冻结枚举。
|
||||
- Manual Invoice 第一阶段按 M009 推进:后端已提供 `POST /api/reservation/invoices/manual-generations`,页面可以不依赖订单或任务,用户手工填写 / 选择字段后由后端业务接口填充 Excel 模板并生成 PDF;前端不得直接调用 M008 的调试上传转换接口来完成业务开票。
|
||||
- Manual Invoice 第一阶段按 M009 推进:后端已提供 `POST /api/reservation/invoices/manual-generations`,前端已新增 `/reservation/invoices/new` 手工开票页面,页面可以不依赖订单或任务,用户手工填写 / 选择字段后由后端业务接口填充 Excel 模板并生成 PDF;前端不得直接调用 M008 的调试上传转换接口来完成业务开票。侧边栏入口仍以登录后端返回的 menus 为准,建议后续在菜单管理中配置 `RESERVATION_MANUAL_INVOICE` / `/reservation/invoices/new` / `RESERVATION_INVOICE_GENERATE`。
|
||||
|
||||
## 6. 前端开发注意事项
|
||||
|
||||
|
||||
@@ -384,6 +384,9 @@ M009 后端 CP2 已实现:页面可不依赖订单或任务,用户手工填
|
||||
前端注意:
|
||||
|
||||
- 当前 `invoice.html` 可以作为交互原型和控件参考,但不能直接作为生产页面上线。
|
||||
- 前端 V1 已新增 `/reservation/invoices/new` 页面,按 `RESERVATION_INVOICE_GENERATE` 路由权限保护,使用登录态 Bearer token 调用正式业务接口。
|
||||
- 页面已支持无订单 / 无任务独立生成,固定提交 `source_type=MANUAL`,`order_id=null`,`task_id=null`;暂不做订单 / 任务自动预填。
|
||||
- 侧边栏入口不由前端硬编码公开,仍依赖后端登录态 `menus[]`。如需菜单中展示,建议菜单管理配置 `menu_code=RESERVATION_MANUAL_INVOICE`、`route_path=/reservation/invoices/new`、`permission_code=RESERVATION_INVOICE_GENERATE`。
|
||||
- 第一阶段入口建议是独立页面,例如 `/reservation/invoices/new` 或 `/invoices/new`;不要求必须从任务详情或订单详情进入。
|
||||
- 无订单 / 无任务时,页面按 `source_type=MANUAL` 提交,`task_id` 和 `order_id` 可以为空。
|
||||
- 从任务进入时,后续可以使用 `GET /api/reservation/tasks/{taskId}` 的 `fields[]`、草稿或确认 payload 预填;从订单进入时,需要明确选择具体任务或提示仅使用订单摘要,避免一个订单多任务时字段来源不清。
|
||||
|
||||
@@ -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 中列为开发前确认项。
|
||||
|
||||
Reference in New Issue
Block a user