优化
This commit is contained in:
@@ -3,6 +3,7 @@ const OPTIONS = { scenario: 'port-schedule-source-lifecycle', deploymentBlocker:
|
||||
const BASE = '/api/platform/v1/port-schedules'
|
||||
const OCEAN = '/api/platform/v1/ocean-bookings'
|
||||
const OUTBOUND = '/api/platform/v1/first-leg/outbound-dispatches'
|
||||
import { resolveOceanBookingMaster, oceanBookingDraft } from './ocean-booking-fixture.mjs'
|
||||
|
||||
function id(value) { return value == null ? '' : String(value) }
|
||||
function codeOf(response) { return response?.body?.code == null ? 'missing' : String(response.body.code) }
|
||||
@@ -38,38 +39,38 @@ async function request(context, method, path, body, headers = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function oceanDraft(context, suffix) {
|
||||
function oceanDraft(context, suffix, master) {
|
||||
return {
|
||||
customerId: '10001', customerName: `船期验收客户-${suffix}`, billOfLadingNo: `PS-BL-${suffix}`,
|
||||
...oceanBookingDraft(context, suffix, master),
|
||||
shippingCompanyName: `船期船司-${suffix}`, bookingAgentName: `船期代理-${suffix}`,
|
||||
vesselName: `船期船-${suffix}`, voyageNo: `PS${suffix}`, departurePortCode: 'CNSZX',
|
||||
departurePortCode: 'CNSZX',
|
||||
departurePortName: '深圳', destinationPortCode: 'USLAX', destinationPortName: '洛杉矶',
|
||||
placeOfDelivery: 'LAX', serviceTerm: 'CY/CY', freightTerm: 'PREPAID',
|
||||
estimatedSailingAt: at(7 * 24 * 60), estimatedArrivalAt: at(28 * 24 * 60), remark: context.marker,
|
||||
remark: context.marker,
|
||||
parties: [
|
||||
{ partyType: 'SHIPPER', partyName: `发货方-${suffix}` },
|
||||
{ partyType: 'CONSIGNEE', partyName: `收货方-${suffix}` },
|
||||
{ partyType: 'NOTIFY_PARTY', partyName: `通知方-${suffix}` },
|
||||
],
|
||||
containerRequirements: [{ containerType: '40HQ', containerKind: 'FCL', quantity: 1 }],
|
||||
containerRequirements: [{ containerType: '40HQ', containerKind: 'FCL', capacityCbm: 68, maxWeightKg: 28000, quantity: 1 }],
|
||||
}
|
||||
}
|
||||
|
||||
async function ensureOceanBooking(context, suffix) {
|
||||
async function ensureOceanBooking(context, suffix, master) {
|
||||
if (context.createdResources?.oceanBooking?.id) return context.createdResources.oceanBooking
|
||||
const response = await request(context, 'POST', OCEAN, { expectedVersion: 0, data: oceanDraft(context, suffix) },
|
||||
const response = await request(context, 'POST', OCEAN, { expectedVersion: 0, data: oceanDraft(context, suffix, master) },
|
||||
{ 'Idempotency-Key': `${context.marker}-port-ocean`.slice(0, 128) })
|
||||
const detail = context.apiSuccess(MODULE, '创建本轮隔离船期关联订舱', response, '', OPTIONS)
|
||||
const oceanBookingId = id(detail?.oceanBooking?.id)
|
||||
context.assert(MODULE, '船期关联订舱客户归属明确', response,
|
||||
Boolean(oceanBookingId) && id(detail?.oceanBooking?.customerId) === '10001',
|
||||
Boolean(oceanBookingId) && id(detail?.oceanBooking?.customerId) === id(master.customerId),
|
||||
`oceanBookingId=${oceanBookingId || 'missing'}, customerId=${id(detail?.oceanBooking?.customerId) || 'missing'}`, OPTIONS)
|
||||
return oceanBookingId ? { id: oceanBookingId, customerId: '10001' } : null
|
||||
return oceanBookingId ? { id: oceanBookingId, customerId: master.customerId } : null
|
||||
}
|
||||
|
||||
function scheduleData(context, suffix, oceanBookingId, containerBookingId, expired = false) {
|
||||
function scheduleData(context, suffix, oceanBookingId, containerBookingId, customerId, expired = false) {
|
||||
return {
|
||||
customerId: '10001', oceanBookingId, containerBookingId: containerBookingId || null,
|
||||
customerId, oceanBookingId, containerBookingId: containerBookingId || null,
|
||||
sourceType: 'CARRIER', sourceName: `验收船司-${suffix}`, sourceRef: `${context.marker}-SOURCE-${expired ? 'EXPIRED' : 'CURRENT'}`,
|
||||
vesselName: `港务船-${suffix}`, voyageNo: `PV${suffix}`, departurePortCode: 'CNSZX', departurePortName: '深圳',
|
||||
destinationPortCode: 'USLAX', destinationPortName: '洛杉矶', etdAt: at(10 * 24 * 60), etaAt: at(30 * 24 * 60),
|
||||
@@ -100,7 +101,9 @@ export async function run(context) {
|
||||
Array.isArray(page?.records) && Number.isFinite(Number(page?.total)),
|
||||
`records=${page?.records?.length ?? 'n/a'}, total=${page?.total ?? 'n/a'}`, OPTIONS)
|
||||
|
||||
const ocean = await ensureOceanBooking(context, suffix)
|
||||
const master = await resolveOceanBookingMaster(context, MODULE)
|
||||
if (!master) return
|
||||
const ocean = await ensureOceanBooking(context, suffix, master)
|
||||
if (!ocean?.id) return
|
||||
const flow = context.createdResources?.phase3Loading
|
||||
|| context.createdResources?.phase3ContainerLoading
|
||||
@@ -108,7 +111,7 @@ export async function run(context) {
|
||||
? id(flow.containerBookingId) : null
|
||||
const knownAllocation = context.createdResources?.oceanBooking?.id === ocean.id && containerBookingId
|
||||
? containerBookingId : null
|
||||
const payload = { expectedVersion: 0, data: scheduleData(context, suffix, ocean.id, knownAllocation), reason: context.marker }
|
||||
const payload = { expectedVersion: 0, data: scheduleData(context, suffix, ocean.id, knownAllocation, master.customerId), reason: context.marker }
|
||||
const createKey = `${context.marker}-port-create`.slice(0, 128)
|
||||
const createResponse = await request(context, 'POST', BASE, payload, { 'Idempotency-Key': createKey })
|
||||
const created = context.apiSuccess(MODULE, '新增独立港务船期观测', createResponse, '', OPTIONS)
|
||||
@@ -132,7 +135,7 @@ export async function run(context) {
|
||||
`first=${scheduleId}, replay=${id(data(replay)?.portSchedule?.schedule?.id) || 'missing'}`, OPTIONS)
|
||||
|
||||
for (const [name, query] of [
|
||||
['按客户查询船期', `customerId=10001`],
|
||||
['按客户查询船期', `customerId=${encodeURIComponent(master.customerId)}`],
|
||||
['按订舱查询船期', `oceanBookingId=${ocean.id}`],
|
||||
...(knownAllocation ? [['按柜次查询船期', `containerBookingId=${knownAllocation}`]] : []),
|
||||
]) {
|
||||
@@ -144,7 +147,7 @@ export async function run(context) {
|
||||
}
|
||||
|
||||
const initialVersion = Number(created.portSchedule.schedule.version)
|
||||
const expiredData = scheduleData(context, suffix, ocean.id, knownAllocation, true)
|
||||
const expiredData = scheduleData(context, suffix, ocean.id, knownAllocation, master.customerId, true)
|
||||
expiredData.sourceRef = payload.data.sourceRef
|
||||
const updateResponse = await request(context, 'PUT', `${BASE}/${scheduleId}`,
|
||||
{ expectedVersion: initialVersion, data: expiredData, reason: '来源刷新并过期' },
|
||||
@@ -195,7 +198,7 @@ export async function run(context) {
|
||||
`passed=${scheduleGate?.passed ?? 'missing'}, actual=${scheduleGate?.actual || 'missing'}`, OPTIONS)
|
||||
}
|
||||
|
||||
const currentData = scheduleData(context, suffix, ocean.id, knownAllocation, false)
|
||||
const currentData = scheduleData(context, suffix, ocean.id, knownAllocation, master.customerId, false)
|
||||
currentData.sourceRef = payload.data.sourceRef
|
||||
currentData.sourceType = 'MANUAL'
|
||||
currentData.sourceName = `平台人工兜底-${suffix}`
|
||||
@@ -222,7 +225,7 @@ export async function run(context) {
|
||||
|
||||
const forged = await request(context, 'POST', BASE, {
|
||||
expectedVersion: 0,
|
||||
data: { ...scheduleData(context, `${suffix}X`, ocean.id, null), customerId: '10002' },
|
||||
data: { ...scheduleData(context, `${suffix}X`, ocean.id, null, master.customerId), customerId: `${master.customerId}999` },
|
||||
reason: '伪造客户归属',
|
||||
}, { 'Idempotency-Key': `${context.marker}-port-forged-customer`.slice(0, 128) })
|
||||
step(context, '伪造船期客户归属被拒绝', forged,
|
||||
|
||||
Reference in New Issue
Block a user