fix(booking): restore arrival time and release validation

This commit is contained in:
2026-10-22 18:47:54 +08:00
parent 22e545fef9
commit a041650ba1
3 changed files with 41 additions and 8 deletions
@@ -1,6 +1,6 @@
import { flushPromises, mount } from '@vue/test-utils'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import ElementPlus from 'element-plus'
import ElementPlus, { ElDatePicker } from 'element-plus'
import { ApiResponseError } from '@/shared/api/http'
import { listPlatformPartners } from '@/modules/master-data'
import { listPlatformWarehouses } from '@/modules/warehouses'
@@ -133,7 +133,8 @@ describe('OceanBookingDetailView one-click release', () => {
expect(wrapper.get('[aria-label="预报毛重"]').element).toHaveProperty('value', '15000.000')
expect(wrapper.get('[aria-label="预报体积"]').element).toHaveProperty('value', '68.000')
const labels = wrapper.findAll('.el-form-item__label').map(item => item.text())
for (const removed of ['客户(选填)', '预计到港', '包装单位', '备注']) expect(labels).not.toContain(removed)
for (const removed of ['客户(选填)', '包装单位', '备注']) expect(labels).not.toContain(removed)
expect(labels).toContain('预计到港')
expect(wrapper.find('[aria-label="起运港名称"]').exists()).toBe(false)
expect(wrapper.find('[aria-label="目的港名称"]').exists()).toBe(false)
expect(wrapper.findAll('.container-table th').map(item => item.text())).toEqual(['操作', '柜型', '数量'])
@@ -228,15 +229,43 @@ describe('OceanBookingDetailView one-click release', () => {
wrapper.unmount()
})
it('allows release without an estimated arrival while preserving other requirements', async () => {
it('blocks release without estimated arrival while still allowing a partial draft save', async () => {
const saved = booking()
saved.estimatedArrivalAt = null
saved.oceanBooking.estimatedArrivalAt = null
vi.mocked(getOceanBooking).mockResolvedValue(saved)
vi.mocked(releaseOceanBooking).mockResolvedValue({ ...saved, status: 'RELEASED', version: 4 })
vi.mocked(updateOceanBookingDraft).mockResolvedValue({ ...saved, version: 4 })
const { vm, wrapper } = await mountView()
await vm.submitRelease()
expect(releaseOceanBooking).toHaveBeenCalledWith('123', { expectedVersion: 3 })
expect(vm.actionError?.message).toBe('放舱前请填写预计到港时间')
expect(releaseOceanBooking).not.toHaveBeenCalled()
await vm.save()
expect(updateOceanBookingDraft).toHaveBeenCalledWith('123', expect.objectContaining({ data: expect.objectContaining({ estimatedArrivalAt: null }) }))
wrapper.unmount()
})
it('loads and saves estimated arrival from the date input and includes it in release confirmation', async () => {
const arrival = '2026-09-25T10:30:00'
vi.mocked(updateOceanBookingDraft).mockResolvedValue({ ...booking('DRAFT', 4), estimatedArrivalAt: arrival })
const { vm, wrapper } = await mountView()
const picker = wrapper.findAllComponents(ElDatePicker).find(item => item.props('placeholder') === '请选择预计到港时间')!
expect(picker.props('modelValue')).toBe('2026-09-20T08:00:00')
picker.vm.$emit('update:modelValue', arrival)
await flushPromises()
await vm.save()
expect(updateOceanBookingDraft).toHaveBeenCalledWith('123', expect.objectContaining({ data: expect.objectContaining({ estimatedArrivalAt: arrival }) }))
await wrapper.findAll('button').find(button => button.text() === '放舱')!.trigger('click')
await flushPromises()
expect(wrapper.get('.release-summary').text()).toContain(arrival)
wrapper.unmount()
})
it('blocks an arrival before the sailing date', async () => {
const { vm, wrapper } = await mountView()
vm.form.data.estimatedArrivalAt = '2026-08-31T08:00:00'
await vm.submitRelease()
expect(vm.actionError?.message).toBe('预计到港时间不能早于预计开船时间')
expect(releaseOceanBooking).not.toHaveBeenCalled()
wrapper.unmount()
})