test(firstleg): cover simulated container booking links

This commit is contained in:
2026-08-14 21:00:20 +08:00
parent 7184f5083a
commit a4a4374c67
14 changed files with 318 additions and 81 deletions
@@ -125,7 +125,7 @@ function bookingPayload(marker, sequence, source) {
shippingCompanyId: null, shippingCompanyName: `SPLIT-SHIPPING-${suffix}`.slice(0, 128),
bookingAgentId: null, bookingAgentName: `SPLIT-AGENT-${suffix}`.slice(0, 128),
departurePortCode: 'CNSZX', departurePortName: '深圳', destinationPortCode: 'USLAX', destinationPortName: '洛杉矶',
placeOfDelivery: 'LAX', serviceTerm: 'CY/CY', freightTerm: 'PREPAID', remark: marker,
placeOfDelivery: 'LAX', serviceTerm: 'CY-CY', freightTerm: 'NINGBO', remark: marker,
parties: [{ partyType: 'SHIPPER', partyName: `SPLIT-SHIPPER-${suffix}` },
{ partyType: 'CONSIGNEE', partyName: `SPLIT-CONSIGNEE-${suffix}` },
{ partyType: 'NOTIFY_PARTY', partyName: `SPLIT-NOTIFY-${suffix}` }],
@@ -137,6 +137,13 @@ function bookingPayload(marker, sequence, source) {
async function loadOneFragment(context, state) {
const { tenantId, rootOrderId, sourceOrderId, sourceOrderNo, warehouseId, sourcePackageCount, sequence } = state
const operationBase = `${context.marker}-chain-${sequence}`.slice(0, 100)
const simulationResponse = await request(context, 'POST', CONTAINERS, {
channelCode: state.channelCode, warehouseId, containerType: '40HQ', capacityCbm: 100, maxWeightKg: 100000,
})
const simulation = context.apiSuccess(MODULE, `为 ${sourceOrderNo} 新增内部模拟柜`, simulationResponse, '', OPTIONS)
const containerId = id(simulation?.id)
if (!containerId) return null
context.createdResources.phase3OrderSplitting.retainedAuditRecordIds.push(containerId)
const bookingCreate = await request(context, 'POST', '/api/platform/v1/ocean-bookings', {
expectedVersion: 0, data: bookingPayload(context.marker, sequence, state),
}, { 'Idempotency-Key': `${operationBase}-booking-create` })
@@ -152,13 +159,16 @@ async function loadOneFragment(context, state) {
const bookingConfirm = await request(context, 'POST', `/api/platform/v1/ocean-bookings/${oceanBookingId}/confirm`, {
expectedVersion: Number(bookingSubmitted?.oceanBooking?.version), reason: context.marker,
}, { 'Idempotency-Key': `${operationBase}-booking-confirm` })
const bookingConfirmed = context.apiSuccess(MODULE, `确认 ${sourceOrderNo} 的订舱并自动分配柜次`, bookingConfirm, '', OPTIONS)
const containerId = id(bookingConfirmed?.containerAllocations?.[0]?.containerBookingId)
context.assert(MODULE, `${sourceOrderNo} 订舱确认后取得稳定柜次`, bookingConfirm,
isPositiveId(containerId) && id(bookingConfirmed?.oceanBooking?.id) === oceanBookingId,
`oceanBookingId=${oceanBookingId}, containerBookingId=${containerId || 'missing'}`, OPTIONS)
if (!containerId) return null
context.createdResources.phase3OrderSplitting.retainedAuditRecordIds.push(containerId)
const bookingConfirmed = context.apiSuccess(MODULE, `确认 ${sourceOrderNo} 的真实订舱`, bookingConfirm, '', OPTIONS)
const requirement = bookingConfirmed?.containerRequirements?.find?.((item) => item.containerType === '40HQ')
if (!requirement?.id) return null
const linkResponse = await request(context, 'POST', `${CONTAINERS}/${containerId}/ocean-booking-link`, {
oceanBookingId, requirementId: id(requirement.id), expectedVersion: Number(simulation.version),
})
const linked = context.apiSuccess(MODULE, `关联 ${sourceOrderNo} 的模拟柜与真实订舱`, linkResponse, '', OPTIONS)
context.assert(MODULE, `${sourceOrderNo} 关联后保持稳定内部柜次`, linkResponse,
isPositiveId(containerId) && id(linked?.id) === containerId && linked?.cabinetNo === simulation.cabinetNo,
`oceanBookingId=${oceanBookingId}, containerBookingId=${containerId}`, OPTIONS)
const candidatesPath = `${SMART}/candidates?bookingId=${encodeURIComponent(containerId)}&warehouseId=${encodeURIComponent(warehouseId)}`
const candidatesResponse = await context.request('GET', candidatesPath)