Files
admin-web/src/modules/ocean-bookings/workflow.test.ts
T

88 lines
5.3 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { oceanBookingPrintSignature, oceanBookingWorkflow } from './workflow'
import type { OceanBookingDetail, OceanBookingResource } from './types'
function detail(): OceanBookingDetail {
// 流程只消费订舱已保存事实,不依赖权限、选项请求或页面临时输入。
const resource: OceanBookingResource = {
id: '123', bookingNo: 'OB-123', status: 'DRAFT', version: 1,
customerId: null, customerName: null, billOfLadingNo: null,
shipperName: null, consigneeName: null, containerCount: 1,
channelCode: null, channelName: null, warehouseId: null, warehouseName: null,
shippingCompanyId: null, shippingCompanyName: null, carrierCode: null, bookingAgentId: null, bookingAgentName: null,
vesselName: null, voyageNo: null, departurePortCode: null, departurePortName: null,
destinationPortCode: null, destinationPortName: null, placeOfDelivery: null,
estimatedSailingAt: null, estimatedArrivalAt: null, remark: null, createdAt: null, updatedAt: null,
orderNo: null, carrierName: null, bookingAgent: null, pol: null, pod: null,
mblShipper: null, mblConsignee: null, soNo: null, cutoffAt: null,
etd: null, atd: null, eta: null, ata: null, containerSummary: null, amount: null, currency: null,
declaredPackageCount: 500, declaredGrossWeightKg: 15000, declaredVolumeCbm: 68,
actualPackageCount: null, actualGrossWeightKg: null, actualVolumeCbm: null,
}
return { ...resource, oceanBooking: resource, parties: [], containerRequirements: [], containers: [], documents: [], histories: [], statusHistory: [] }
}
describe('ocean booking workflow milestones', () => {
it('starts on the first step and does not mark an unsaved form as complete', () => {
expect(oceanBookingWorkflow(null, false, false, {}).map(step => step.state))
.toEqual(['current', 'pending', 'pending', 'pending'])
expect(oceanBookingWorkflow(detail(), true, false, {})[0]).toMatchObject({ state: 'current', status: '修改待保存' })
})
it('advances from saved draft to preview, then to release without inventing a print record', () => {
const saved = detail()
const initial = oceanBookingWorkflow(saved, false, false, {})
expect(initial.map(step => step.state)).toEqual(['complete', 'current', 'pending', 'pending'])
expect(initial[0]?.status).toBe('已保存')
const previews = { SHIPPING_INSTRUCTION: oceanBookingPrintSignature(saved, 'SHIPPING_INSTRUCTION') }
const previewed = oceanBookingWorkflow(saved, false, false, previews)
expect(previewed.map(step => step.state)).toEqual(['complete', 'complete', 'current', 'pending'])
expect(previewed[1]?.status).toBe('已预览')
expect(previewed.some(step => step.status === '已打印')).toBe(false)
})
it('restores released progress from server data and requires all saved actual values before final completion', () => {
const saved = detail()
saved.status = 'RELEASED'
let steps = oceanBookingWorkflow(saved, false, false, {})
expect(steps.map(step => step.state)).toEqual(['complete', 'complete', 'complete', 'current'])
expect(steps[1]).toMatchObject({ state: 'complete', status: '可重新预览 / 打印' })
expect(steps[2]).toMatchObject({ state: 'complete', status: '已放舱' })
expect(steps[3]).toMatchObject({ state: 'current', status: '待补齐实值' })
saved.actualPackageCount = 480
saved.actualGrossWeightKg = 14320
saved.actualVolumeCbm = 65
const previews = { BILL_OF_LADING_CONFIRMATION: oceanBookingPrintSignature(saved, 'BILL_OF_LADING_CONFIRMATION') }
expect(oceanBookingWorkflow(saved, false, true, previews)[3]).toMatchObject({ state: 'current', status: '实值待保存' })
steps = oceanBookingWorkflow(saved, false, false, {})
expect(steps[3]).toMatchObject({ state: 'current', status: '可预览 / 打印' })
expect(oceanBookingWorkflow(saved, false, false, previews)[3]).toMatchObject({ state: 'complete', status: '已预览' })
})
it('invalidates only previews whose actual data changed', () => {
const saved = detail()
saved.status = 'RELEASED'
saved.actualPackageCount = 480; saved.actualGrossWeightKg = 14320; saved.actualVolumeCbm = 65
const previews = {
SHIPPING_INSTRUCTION: oceanBookingPrintSignature(saved, 'SHIPPING_INSTRUCTION'),
BILL_OF_LADING_CONFIRMATION: oceanBookingPrintSignature(saved, 'BILL_OF_LADING_CONFIRMATION'),
}
saved.version = 100 // 附件等引起的订舱版本变化不会伪造或抹去相同单据的预览事实。
saved.actualPackageCount = 490
let steps = oceanBookingWorkflow(saved, false, false, previews)
expect(steps[1]?.state).toBe('complete')
expect(steps[3]).toMatchObject({ state: 'current', status: '可预览 / 打印' })
saved.declaredPackageCount = 510
steps = oceanBookingWorkflow(saved, false, false, previews)
expect(steps[1]).toMatchObject({ state: 'complete', status: '可重新预览 / 打印' })
})
it('requires a fresh preview when draft print data changes before release', () => {
const saved = detail()
const previews = { SHIPPING_INSTRUCTION: oceanBookingPrintSignature(saved, 'SHIPPING_INSTRUCTION') }
saved.declaredPackageCount = 510
expect(oceanBookingWorkflow(saved, false, false, previews).map(step => step.state))
.toEqual(['complete', 'current', 'pending', 'pending'])
})
})