fix(booking): restore arrival time and release validation
This commit is contained in:
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -373,7 +373,7 @@ function releaseValidationError() {
|
||||
const requiredFields: Array<[unknown, string]> = [
|
||||
[form.data.warehouseId, '装柜仓库'], [form.data.channelCode, '物流渠道'],
|
||||
[form.data.billOfLadingNo, '提单号'], [form.data.vesselName, '船名'], [form.data.voyageNo, '航次'],
|
||||
[form.data.estimatedSailingAt, '预计开船时间'],
|
||||
[form.data.estimatedSailingAt, '预计开船时间'], [form.data.estimatedArrivalAt, '预计到港时间'],
|
||||
[form.data.placeOfDelivery, '交货地点'],
|
||||
[form.data.shippingCompanyId, '船公司'], [form.data.bookingAgentId, '订舱代理'],
|
||||
]
|
||||
@@ -488,6 +488,7 @@ onMounted(() => { void load(); void loadOptions() })
|
||||
<el-form-item label="起运港"><el-input v-model="form.data.departurePortCode" placeholder="港代码" aria-label="起运港代码" /></el-form-item>
|
||||
<el-form-item label="目的港"><el-input v-model="form.data.destinationPortCode" placeholder="港代码" aria-label="目的港代码" /></el-form-item>
|
||||
<el-form-item label="预计开船" prop="estimatedSailingAt"><el-date-picker v-model="form.data.estimatedSailingAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择预计开船时间" style="width:100%" /></el-form-item>
|
||||
<el-form-item label="预计到港" prop="estimatedArrivalAt"><el-date-picker v-model="form.data.estimatedArrivalAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择预计到港时间" style="width:100%" /></el-form-item>
|
||||
<el-form-item class="booking-field--wide" label="交货地点"><el-input v-model="form.data.placeOfDelivery" placeholder="请输入最终交货地点" /></el-form-item>
|
||||
<el-form-item label="运费条款"><el-input v-model="form.data.freightTerm" maxlength="64" /></el-form-item>
|
||||
<el-form-item label="运输条款"><el-input v-model="form.data.serviceTerm" maxlength="64" /></el-form-item>
|
||||
@@ -622,6 +623,7 @@ onMounted(() => { void load(); void loadOptions() })
|
||||
<el-descriptions-item label="船名">{{ form.data.vesselName || '—' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="航次">{{ form.data.voyageNo || '—' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="预计开船">{{ form.data.estimatedSailingAt || '—' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="预计到港">{{ form.data.estimatedArrivalAt || '—' }}</el-descriptions-item>
|
||||
</el-descriptions></section>
|
||||
</div>
|
||||
</AppDialog>
|
||||
|
||||
Reference in New Issue
Block a user