对齐手工开票页面原型
This commit is contained in:
@@ -209,6 +209,97 @@ describe('ReservationManualInvoiceView', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('renders the invoice.html style page sections and sticky action bar', () => {
|
||||
const wrapper = mountView()
|
||||
|
||||
expect(wrapper.find('[data-testid="manual-invoice-prototype-page"]').exists()).toBe(true)
|
||||
expect(wrapper.text()).toContain('创建 Invoice')
|
||||
expect(wrapper.text()).toContain('01')
|
||||
expect(wrapper.text()).toContain('Basic Information')
|
||||
expect(wrapper.text()).toContain('02')
|
||||
expect(wrapper.text()).toContain('Please refer to the following reservation')
|
||||
expect(wrapper.text()).toContain('03')
|
||||
expect(wrapper.text()).toContain('Description&Amount')
|
||||
expect(wrapper.find('[data-testid="manual-invoice-action-bar"]').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('shows final-format date previews like the invoice prototype', async () => {
|
||||
const wrapper = mountView()
|
||||
|
||||
await wrapper.find('[data-testid="booking-arrival-date"]').setValue('2026-08-02')
|
||||
await wrapper.find('[data-testid="booking-departure-date"]').setValue('2026-08-05')
|
||||
await wrapper.find('[data-testid="document-due-date"]').setValue('2026-07-22')
|
||||
|
||||
expect(wrapper.find('[data-testid="arrival-date-preview"]').text()).toContain('02/08/2026')
|
||||
expect(wrapper.find('[data-testid="departure-date-preview"]').text()).toContain('05/08/2026')
|
||||
expect(wrapper.find('[data-testid="due-date-preview"]').text()).toContain('22/07/2026')
|
||||
})
|
||||
|
||||
it('keeps primary reservation controls bound to the first charge line', async () => {
|
||||
const wrapper = mountView()
|
||||
|
||||
await wrapper.find('[data-testid="primary-room-rate"]').setValue('3200')
|
||||
await wrapper.find('[data-testid="primary-room-count"]').setValue('4')
|
||||
await wrapper.find('[data-testid="primary-night-count"]').setValue('3')
|
||||
|
||||
expect((wrapper.find('[data-testid="charge-rate-0"]').element as HTMLInputElement).value).toBe('3200')
|
||||
expect((wrapper.find('[data-testid="charge-quantity-0"]').element as HTMLInputElement).value).toBe('4')
|
||||
expect((wrapper.find('[data-testid="charge-nights-0"]').element as HTMLInputElement).value).toBe('3')
|
||||
expect(wrapper.find('[data-testid="charge-amount-0"]').text()).toContain('38,400.00')
|
||||
})
|
||||
|
||||
it('submits comma-formatted numeric inputs as normalized numbers', async () => {
|
||||
vi.mocked(service.generateManualReservationInvoice).mockResolvedValue(createResult())
|
||||
const wrapper = mountView()
|
||||
|
||||
await wrapper.find('[data-testid="recipient-company-code"]').setValue('QBD')
|
||||
await fillMinimumInvoiceForm(wrapper)
|
||||
await wrapper.find('[data-testid="booking-extra-bed-rate"]').setValue('1,200')
|
||||
await wrapper.find('[data-testid="charge-rate-0"]').setValue('3,000')
|
||||
await wrapper.find('[data-testid="manual-invoice-submit"]').trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(service.generateManualReservationInvoice).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
invoice_payload: expect.objectContaining({
|
||||
booking: expect.objectContaining({
|
||||
extra_bed_rate: 1200,
|
||||
}),
|
||||
charges: [
|
||||
expect.objectContaining({
|
||||
rate: 3000,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('clears directory contact text when switching company back to manual input', async () => {
|
||||
const wrapper = mountView()
|
||||
|
||||
await wrapper.find('[data-testid="recipient-company-code"]').setValue('HANATOUR')
|
||||
await wrapper.find('[data-testid="recipient-contact-id"]').setValue('HANATOUR_BOLAM_JO')
|
||||
expect((wrapper.find('[data-testid="recipient-email"]').element as HTMLInputElement).value).toBe(
|
||||
'melissa0609@hanatour.com',
|
||||
)
|
||||
|
||||
await wrapper.find('[data-testid="recipient-company-code"]').setValue('MANUAL')
|
||||
|
||||
expect((wrapper.find('[data-testid="recipient-contact-id"]').element as HTMLSelectElement).value).toBe('MANUAL')
|
||||
expect((wrapper.find('input[placeholder="输入 Company"]').element as HTMLInputElement).value).toBe('')
|
||||
expect((wrapper.find('input[placeholder="输入 Attention"]').element as HTMLInputElement).value).toBe('')
|
||||
expect((wrapper.find('[data-testid="recipient-email"]').element as HTMLInputElement).value).toBe('')
|
||||
})
|
||||
|
||||
it('keeps invoice date out of the keyboard focus order while preserving the payload field', () => {
|
||||
const wrapper = mountView()
|
||||
const invoiceDate = wrapper.find('[data-testid="document-invoice-date"]')
|
||||
|
||||
expect(invoiceDate.attributes('type')).toBe('hidden')
|
||||
expect(invoiceDate.attributes('required')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('links company and attention seed data while allowing manual overrides before submit', async () => {
|
||||
vi.mocked(service.generateManualReservationInvoice).mockResolvedValue(createResult())
|
||||
const wrapper = mountView()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user