添加一家公司

This commit is contained in:
andy committed 2026-09-09 15:47:32 +08:00
1 parent 3bce336b6c
commit 32bee57df6
12 files changed
+136 -27

No files matched your search

+1
View File
@@ -365,6 +365,7 @@ export default {
noPdfUrl: 'The backend did not return a PDF URL.',
backendTotals: 'Backend totals',
validationTitle: 'Please fix the form',
generationErrorTitle: 'Generation failed',
fieldErrors: {
required: 'Required',
invalidEmail: 'Invalid email',
+1
View File
@@ -365,6 +365,7 @@ export default {
noPdfUrl: 'หลังบ้านไม่ได้ส่งลิงก์ PDF กลับมา',
backendTotals: 'ยอดจากหลังบ้าน',
validationTitle: 'กรุณาแก้ไขแบบฟอร์ม',
generationErrorTitle: 'สร้างไม่สำเร็จ',
fieldErrors: {
required: 'จำเป็นต้องกรอก',
invalidEmail: 'รูปแบบ Email ไม่ถูกต้อง',
+1
View File
@@ -365,6 +365,7 @@ export default {
noPdfUrl: '后端未返回 PDF 链接。',
backendTotals: '后端返回金额',
validationTitle: '请先修正表单',
generationErrorTitle: '生成失败',
fieldErrors: {
required: '必填',
invalidEmail: 'Email 格式不正确',
@@ -816,6 +816,24 @@ describe('ReservationManualInvoiceView', () => {
expect(wrapper.text()).toContain('PDF 生成超时')
})
it('does not label backend generation failures as form validation errors', async () => {
vi.mocked(service.generateManualReservationInvoice).mockRejectedValue(
new ApiError('Request failed with status 502', 502, {
error_code: 'RESERVATION_INVOICE_GENERATION_FAILED',
message: 'Invoice PDF 生成失败,请稍后重试。',
}),
)
const wrapper = mountView()
await wrapper.find('[data-testid="recipient-company-code"]').setValue('QBD')
await fillMinimumInvoiceForm(wrapper)
await wrapper.find('[data-testid="manual-invoice-submit"]').trigger('click')
await flushPromises()
expect(wrapper.text()).toContain('生成失败')
expect(wrapper.text()).not.toContain(zhCN.manualInvoice.validationTitle)
})
it('keeps backend raw details in a folded technical detail block', async () => {
vi.mocked(service.generateManualReservationInvoice).mockRejectedValue(
new ApiError('Request failed with status 422', 422, {
@@ -922,6 +922,19 @@ const recipientCompanies: RecipientCompanySeed[] = [
},
],
},
{
company_code: 'CENTURY_WAN_CHENG',
company: 'Century Wan Cheng Tourism Co., Ltd.',
contacts: [
{
contact_id: 'CENTURY_WAN_CHENG_KHUN_NID',
attention: 'Khun Nid',
address: '622 Soi Ratchada Niwet, Intersection 20, Huai Khwang District, Bangkok 10310',
telephone: '081-736-9808',
email: 'meojiutravel.hotel@gmail.com',
},
],
},
{
company_code: 'HANATOUR',
company: 'HANATOUR TD CO., LTD.',
@@ -1015,6 +1028,7 @@ const messages = ref<string[]>([])
const technicalDetails = ref<string[]>([])
const downloadMessageKey = ref('')
const alertTone = ref<'error' | 'success'>('error')
const alertKind = ref<'validation' | 'generation'>('validation')
const generationResult = ref<ManualInvoiceGenerationResult | null>(null)
const documentDatesEdited = ref(false)
const primaryNightsEdited = ref(false)
@@ -1044,7 +1058,9 @@ const alertTitle = computed(() => {
if (alertTone.value === 'success') {
return t('manualInvoice.resultSection')
}
return t('manualInvoice.validationTitle')
return alertKind.value === 'generation'
? t('manualInvoice.generationErrorTitle')
: t('manualInvoice.validationTitle')
})
watch(
@@ -1131,6 +1147,7 @@ async function submitInvoice(): Promise<void> {
validationAttempted.value = true
messages.value = validateForm()
alertTone.value = 'error'
alertKind.value = 'validation'
if (messages.value.length > 0) {
return
}
@@ -1144,6 +1161,7 @@ async function submitInvoice(): Promise<void> {
const errorDescription = describeGenerationError(error)
messages.value = [errorDescription.message]
technicalDetails.value = errorDescription.technicalDetails
alertKind.value = isBackendValidationError(error) ? 'validation' : 'generation'
} finally {
submitting.value = false
}
@@ -1457,6 +1475,10 @@ function errorCodeFromDetails(details: unknown): string {
return 'UNKNOWN'
}
function isBackendValidationError(error: unknown): boolean {
return error instanceof ApiError && errorCodeFromDetails(error.details) === 'RESERVATION_INVOICE_VALIDATION_FAILED'
}
function detailMessages(details: unknown): string[] {
if (!isRecord(details)) {
return []