实现 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

@@ -26,6 +26,7 @@ export default {
nav: {
orders: 'Order list',
taskQueue: 'Task queue',
manualInvoice: 'Manual invoice',
sourceMessages: 'Source messages',
systemStatus: 'System status',
orderDetail: 'Order detail',
@@ -250,6 +251,84 @@ export default {
createdAt: 'Created at',
},
},
manualInvoice: {
title: 'Manual invoice',
subtitle: 'Generate a Proforma Invoice PDF by entering fields manually without an order or task.',
sourceBadge: 'Manual generation',
independentHint: 'This V1 page is not linked to an order or task. The backend records generation and audit data.',
documentSection: 'Document',
recipientSection: 'Recipient',
bookingSection: 'Booking',
chargesSection: 'Charges',
previewSection: 'Amount preview',
resultSection: 'Generation result',
invoiceDate: 'Invoice date',
bookingDate: 'Booking date',
dueDate: 'Due date',
companySeed: 'Select company',
contactSeed: 'Select attention',
selectCompany: 'Select company',
selectContact: 'Select attention',
company: 'Company',
attention: 'Attention',
address: 'Address',
telephone: 'Tel',
email: 'Email',
groupName: 'Group name',
arrivalDate: 'Arrival date',
departureDate: 'Departure date',
roomRateNote: 'Room rate note',
extraBedRate: 'Extra bed rate',
description: 'Description',
roomType: 'Room type',
quantity: 'Quantity',
rate: 'Rate',
nights: 'Nights',
amount: 'Amount',
subtotal: 'Sub-total',
vat: 'VAT 7%',
total: 'Total',
addCharge: 'Add charge',
removeCharge: 'Remove',
maxChargesReached: 'V1 supports up to 10 charge lines.',
previewDisclaimer: 'The frontend only previews amounts. Backend totals are authoritative.',
manualOverrideHint: 'Selecting company and attention fills contact details; every text field remains editable.',
generate: 'Generate PDF',
generating: 'Generating',
openPdf: 'Open PDF',
downloadPdf: 'Download PDF',
generationId: 'Generation ID',
generationStatus: 'Status',
pdfUrl: 'PDF URL',
hotelId: 'Hotel ID',
templateCode: 'Template',
createdAt: 'Created at',
noPdfUrl: 'The backend did not return a PDF URL.',
backendTotals: 'Backend totals',
validationTitle: 'Please fix the form',
statuses: {
SUCCEEDED: 'Generated',
GENERATED: 'Generated',
FAILED: 'Failed',
PROCESSING: 'Generating',
},
errors: {
FRONTEND_VALIDATION: 'Form validation failed. Check required fields and charge lines.',
RESERVATION_INVOICE_VALIDATION_FAILED: 'Invoice field validation failed. Please check the form.',
RESERVATION_INVOICE_CONTEXT_MISMATCH: 'The order or task context does not match.',
DOCUMENT_CONVERSION_FAILED: 'PDF generation failed. Please retry or contact an administrator.',
DOCUMENT_CONVERSION_TIMEOUT: 'PDF generation timed out. Please retry later.',
AUTH_401: 'Your session has expired. Please sign in again.',
AUTH_403: 'Your account does not have manual invoice permission.',
UNKNOWN: 'Generation failed. Please retry later.',
requiredFields: 'Complete dates, recipient, booking details, and at least one valid charge line.',
invalidEmail: 'Email format is invalid.',
dueDateBeforeBookingDate: 'Due date cannot be earlier than booking date.',
departureBeforeArrival: 'Departure date must be later than arrival date.',
extraBedNegative: 'Extra bed rate cannot be less than 0.',
chargePositive: 'Quantity, rate, and nights must be greater than 0.',
},
},
order: {
summary: 'Order summary',
taskQueue: 'Order task queue',

View File

@@ -26,6 +26,7 @@ export default {
nav: {
orders: 'รายการออเดอร์',
taskQueue: 'คิวงาน',
manualInvoice: 'ออกใบแจ้งหนี้เอง',
sourceMessages: 'แหล่งที่มาข้อความ',
systemStatus: 'สถานะระบบ',
orderDetail: 'รายละเอียดออเดอร์',
@@ -250,6 +251,84 @@ export default {
createdAt: 'เวลาสร้าง',
},
},
manualInvoice: {
title: 'ออกใบแจ้งหนี้เอง',
subtitle: 'กรอกข้อมูลเองเพื่อสร้าง Proforma Invoice PDF โดยไม่ต้องอ้างอิงออเดอร์หรืองาน',
sourceBadge: 'สร้างด้วยตนเอง',
independentHint: 'หน้า V1 นี้ไม่ผูกกับออเดอร์หรืองาน หลังบ้านจะบันทึกประวัติการสร้างและ audit',
documentSection: 'ข้อมูลเอกสาร',
recipientSection: 'ผู้รับ',
bookingSection: 'ข้อมูลการจอง',
chargesSection: 'รายการค่าใช้จ่าย',
previewSection: 'ตัวอย่างยอดเงิน',
resultSection: 'ผลการสร้าง',
invoiceDate: 'วันที่ Invoice',
bookingDate: 'วันที่ Booking',
dueDate: 'Due Date',
companySeed: 'เลือก Company',
contactSeed: 'เลือก Attention',
selectCompany: 'เลือก Company',
selectContact: 'เลือก Attention',
company: 'Company',
attention: 'Attention',
address: 'Address',
telephone: 'Tel',
email: 'Email',
groupName: 'Group Name',
arrivalDate: 'Arrival Date',
departureDate: 'Departure Date',
roomRateNote: 'Room Rate Note',
extraBedRate: 'Extra Bed Rate',
description: 'Description',
roomType: 'Room Type',
quantity: 'Quantity',
rate: 'Rate',
nights: 'Nights',
amount: 'Amount',
subtotal: 'Sub-Total',
vat: 'VAT 7%',
total: 'Total',
addCharge: 'เพิ่มรายการ',
removeCharge: 'ลบ',
maxChargesReached: 'V1 รองรับได้สูงสุด 10 รายการค่าใช้จ่าย',
previewDisclaimer: 'ยอดนี้เป็นเพียงตัวอย่าง ยอดสุดท้ายให้ยึด totals จากหลังบ้าน',
manualOverrideHint: 'เลือก Company / Attention แล้วระบบจะกรอกข้อมูลให้ แต่ยังแก้ไขข้อความได้ทั้งหมด',
generate: 'สร้าง PDF',
generating: 'กำลังสร้าง',
openPdf: 'เปิด PDF',
downloadPdf: 'ดาวน์โหลด PDF',
generationId: 'รหัสการสร้าง',
generationStatus: 'สถานะ',
pdfUrl: 'ลิงก์ PDF',
hotelId: 'รหัสโรงแรม',
templateCode: 'เทมเพลต',
createdAt: 'เวลาสร้าง',
noPdfUrl: 'หลังบ้านไม่ได้ส่งลิงก์ PDF กลับมา',
backendTotals: 'ยอดจากหลังบ้าน',
validationTitle: 'กรุณาแก้ไขแบบฟอร์ม',
statuses: {
SUCCEEDED: 'สร้างแล้ว',
GENERATED: 'สร้างแล้ว',
FAILED: 'สร้างไม่สำเร็จ',
PROCESSING: 'กำลังสร้าง',
},
errors: {
FRONTEND_VALIDATION: 'ตรวจสอบแบบฟอร์มไม่ผ่าน กรุณาตรวจฟิลด์ที่จำเป็นและรายการค่าใช้จ่าย',
RESERVATION_INVOICE_VALIDATION_FAILED: 'ตรวจสอบข้อมูล Invoice ไม่ผ่าน กรุณาตรวจแบบฟอร์ม',
RESERVATION_INVOICE_CONTEXT_MISMATCH: 'ออเดอร์หรืองานไม่ตรงกัน',
DOCUMENT_CONVERSION_FAILED: 'สร้าง PDF ไม่สำเร็จ กรุณาลองอีกครั้งหรือติดต่อผู้ดูแล',
DOCUMENT_CONVERSION_TIMEOUT: 'สร้าง PDF หมดเวลา กรุณาลองใหม่ภายหลัง',
AUTH_401: 'เซสชันหมดอายุ กรุณาเข้าสู่ระบบใหม่',
AUTH_403: 'บัญชีนี้ไม่มีสิทธิ์ออกใบแจ้งหนี้เอง',
UNKNOWN: 'สร้างไม่สำเร็จ กรุณาลองอีกครั้ง',
requiredFields: 'กรุณากรอกวันที่ ผู้รับ ข้อมูลการจอง และอย่างน้อยหนึ่งรายการค่าใช้จ่ายที่ถูกต้อง',
invalidEmail: 'รูปแบบ Email ไม่ถูกต้อง',
dueDateBeforeBookingDate: 'Due Date ต้องไม่เร็วกว่าวันที่ Booking',
departureBeforeArrival: 'Departure Date ต้องหลัง Arrival Date',
extraBedNegative: 'Extra Bed Rate ต้องไม่ต่ำกว่า 0',
chargePositive: 'Quantity, Rate และ Nights ต้องมากกว่า 0',
},
},
order: {
summary: 'สรุปออเดอร์',
taskQueue: 'คิวงานของออเดอร์นี้',

View File

@@ -26,6 +26,7 @@ export default {
nav: {
orders: '订单列表',
taskQueue: '任务队列',
manualInvoice: '手工开票',
sourceMessages: '消息来源',
systemStatus: '系统状态',
orderDetail: '订单详情',
@@ -250,6 +251,84 @@ export default {
createdAt: '创建时间',
},
},
manualInvoice: {
title: '手工开票',
subtitle: '无订单、无任务时,手工填写 Proforma Invoice 字段并生成 PDF。',
sourceBadge: '手工生成',
independentHint: '本页第一版不关联订单或任务,生成记录和审计由后端统一落库。',
documentSection: '单据信息',
recipientSection: '收件方',
bookingSection: '预订信息',
chargesSection: '费用明细',
previewSection: '金额预览',
resultSection: '生成结果',
invoiceDate: '开票日期Invoice Date',
bookingDate: '预订日期Booking Date',
dueDate: '付款截止日期Due Date',
companySeed: '选择公司Company',
contactSeed: '选择收件人Attention',
selectCompany: '请选择公司',
selectContact: '请选择收件人',
company: '公司Company',
attention: '收件人Attention',
address: '地址Address',
telephone: 'Tel',
email: 'Email',
groupName: '团队名称Group Name',
arrivalDate: '到店日期Arrival Date',
departureDate: '离店日期Departure Date',
roomRateNote: '房价备注Room Rate Note',
extraBedRate: '加床价格Extra Bed Rate',
description: '费用描述Description',
roomType: '房型Room Type',
quantity: '数量Quantity',
rate: '单价Rate',
nights: '晚数Nights',
amount: 'Amount',
subtotal: 'Sub-Total',
vat: 'VAT 7%',
total: 'Total',
addCharge: '新增费用',
removeCharge: '删除',
maxChargesReached: '第一版最多支持 10 条费用明细。',
previewDisclaimer: '前端仅做金额预览,最终金额以后端返回 totals 为准。',
manualOverrideHint: '选择 Company / Attention 后会自动带出资料,带出的文本仍可手工覆盖。',
generate: '生成 PDF',
generating: '生成中',
openPdf: '打开 PDF',
downloadPdf: '下载 PDF',
generationId: '生成记录 ID',
generationStatus: '生成状态',
pdfUrl: 'PDF 链接',
hotelId: '酒店 ID',
templateCode: '模板',
createdAt: '创建时间',
noPdfUrl: '后端未返回 PDF 链接。',
backendTotals: '后端返回金额',
validationTitle: '请先修正表单',
statuses: {
SUCCEEDED: '已生成',
GENERATED: '已生成',
FAILED: '生成失败',
PROCESSING: '生成中',
},
errors: {
FRONTEND_VALIDATION: '表单校验未通过,请检查必填字段和费用明细。',
RESERVATION_INVOICE_VALIDATION_FAILED: 'Invoice 字段校验失败,请检查表单内容。',
RESERVATION_INVOICE_CONTEXT_MISMATCH: '订单或任务上下文不匹配。',
DOCUMENT_CONVERSION_FAILED: 'PDF 生成失败,请稍后重试或联系管理员。',
DOCUMENT_CONVERSION_TIMEOUT: 'PDF 生成超时,请稍后重试。',
AUTH_401: '登录已失效,请重新登录后再生成。',
AUTH_403: '当前账号没有手工开票权限。',
UNKNOWN: '生成失败,请稍后重试。',
requiredFields: '请补充日期、收件方、预订信息和至少一条有效费用明细。',
invalidEmail: 'Email 格式不正确。',
dueDateBeforeBookingDate: 'Due Date 不能早于 Booking 日期。',
departureBeforeArrival: 'Departure Date 必须晚于 Arrival Date。',
extraBedNegative: '加床价格不能小于 0。',
chargePositive: '费用明细的 Quantity、Rate、Nights 必须大于 0。',
},
},
order: {
summary: '订单摘要',
taskQueue: '同订单任务队列',