101 lines
5.8 KiB
JavaScript
101 lines
5.8 KiB
JavaScript
function text(value) { return value == null ? '' : String(value).trim() }
|
|
const PLATFORM_CHANNELS = '/api/platform/v1/ocean-bookings/channels'
|
|
|
|
export async function publishPlatformLogisticsChannels(context, originWarehouseId, module) {
|
|
const warehouseId = text(originWarehouseId)
|
|
const sourcePath = `${PLATFORM_CHANNELS}?originWarehouseId=${encodeURIComponent(warehouseId)}`
|
|
const response = await context.request('GET', sourcePath)
|
|
const data = context.apiSuccess(module, '按起运仓查询平台正式物流渠道', response,
|
|
`originWarehouseId=${warehouseId}`, { scenario: 'ocean-booking-channel-catalog', deploymentBlocker: true })
|
|
const channels = (Array.isArray(data) ? data : []).flatMap((value) => {
|
|
const channelCode = text(value?.channelCode)
|
|
const channelName = text(value?.channelName)
|
|
return channelCode && channelName ? [{ channelCode, channelName }] : []
|
|
})
|
|
const resource = { marker: context.marker, originWarehouseId: warehouseId, sourcePath, channels }
|
|
context.createdResources.platformLogisticsChannels = resource
|
|
context.assert(module, '平台渠道目录归属本轮起运仓且不含空渠道', response,
|
|
Boolean(warehouseId) && channels.length > 0,
|
|
`originWarehouseId=${warehouseId}, channels=${channels.map((value) => value.channelCode).join('|') || 'none'}`,
|
|
{ scenario: 'ocean-booking-channel-catalog', deploymentBlocker: true })
|
|
return resource
|
|
}
|
|
|
|
export async function resolveOceanBookingMaster(context, module) {
|
|
const resources = context.createdResources || {}
|
|
const candidates = [resources.phase3Loading, resources.phase3ContainerLoading,
|
|
resources.orchestrationFixtures?.phase3Container, resources.inboundMeasurement,
|
|
resources.orders].filter(Boolean)
|
|
const source = candidates.find((item) => item.marker === context.marker) || candidates[0]
|
|
const tenantId = text(source?.tenantId || source?.customerId)
|
|
const inboundId = text(source?.inboundId)
|
|
let summary = source?.summary || null
|
|
if (tenantId && inboundId && typeof context.request === 'function') {
|
|
const response = await context.request('GET', `/api/platform/inbounds/${encodeURIComponent(inboundId)}?tenantId=${encodeURIComponent(tenantId)}`)
|
|
if (String(response?.body?.code) === '200') summary = response.body.data?.summary || summary
|
|
}
|
|
const master = {
|
|
customerId: text(summary?.tenantId || tenantId),
|
|
customerName: text(summary?.customerName || source?.customerName),
|
|
channelCode: text(summary?.channelCode || source?.channelCode),
|
|
channelName: text(summary?.channelName || source?.channelName),
|
|
warehouseId: text(summary?.warehouseId || source?.warehouseId || source?.receivingWarehouseId),
|
|
warehouseName: text(summary?.warehouseName || source?.warehouseName),
|
|
}
|
|
const missing = ['customerId', 'customerName', 'channelCode', 'channelName', 'warehouseId', 'warehouseName']
|
|
.filter((key) => !master[key])
|
|
if (missing.length) {
|
|
context.addStep(module, '订舱 fixture 使用本轮正式客户/渠道/仓库主数据', null, false,
|
|
`marker=${context.marker}, inboundId=${inboundId || 'missing'}, missing=${missing.join(',')}`, { scenario: 'ocean-booking-master-data', deploymentBlocker: true })
|
|
return null
|
|
}
|
|
return master
|
|
}
|
|
|
|
export async function resolveOceanBookingAgent(context, module, carrierCode, options = {}) {
|
|
const normalizedCarrierCode = text(carrierCode).toUpperCase()
|
|
const response = await context.request('GET',
|
|
`/api/platform/v1/ocean-bookings/booking-agents?carrierCode=${encodeURIComponent(normalizedCarrierCode)}`)
|
|
const candidates = context.apiSuccess(module, '按船司读取可用订舱代理', response,
|
|
`carrierCode=${normalizedCarrierCode}`, options)
|
|
const selected = (Array.isArray(candidates) ? candidates : []).find((item) =>
|
|
text(item?.supplierId) && text(item?.name))
|
|
context.assert(module, '订舱代理已由服务端按船司关联过滤', response,
|
|
Boolean(selected), `carrierCode=${normalizedCarrierCode}`, options)
|
|
return selected ? { id: text(selected.supplierId), name: text(selected.name) } : null
|
|
}
|
|
|
|
export function oceanBookingDraft(context, suffix, master, labels = {}) {
|
|
const { channelName: _readOnlyChannelName, warehouseName: _readOnlyWarehouseName, ...writableMaster } = master
|
|
const normalizedSuffix = text(suffix).replace(/[^A-Za-z0-9]/g, '').slice(-32) || 'BOOKING'
|
|
const containerRequirements = labels.containerRequirements || [{
|
|
containerType: '40HC', containerKind: 'FCL', quantity: 1, capacityCbm: 76, maxWeightKg: 28000,
|
|
}]
|
|
return {
|
|
...writableMaster,
|
|
billOfLadingNo: labels.billOfLadingNo || `BL-${suffix}`,
|
|
carrierCode: labels.carrierCode || 'OTHER',
|
|
shippingCompanyId: labels.shippingCompanyId ?? null,
|
|
shippingCompanyName: labels.shippingCompanyId ? labels.shippingCompanyName ?? null : null,
|
|
bookingAgentId: labels.bookingAgentId ?? null,
|
|
bookingAgentName: labels.bookingAgentId ? labels.bookingAgentName ?? null : null,
|
|
vesselName: labels.vesselName || `验收船-${suffix}`, voyageNo: labels.voyageNo || `V-${suffix}`,
|
|
departurePortCode: 'CNSZX', departurePortName: '深圳', destinationPortCode: 'USLAX',
|
|
destinationPortName: '洛杉矶', placeOfDelivery: 'LAX', serviceTerm: 'CY-CY', freightTerm: 'NINGBO',
|
|
estimatedSailingAt: labels.estimatedSailingAt || '2026-09-01T08:00:00',
|
|
estimatedArrivalAt: labels.estimatedArrivalAt || '2026-09-20T08:00:00',
|
|
remark: context.marker,
|
|
parties: [{ partyType: 'SHIPPER', partyName: `发货方-${suffix}` },
|
|
{ partyType: 'CONSIGNEE', partyName: `收货方-${suffix}` },
|
|
{ partyType: 'NOTIFY_PARTY', partyName: `通知方-${suffix}` }],
|
|
containerRequirements,
|
|
}
|
|
}
|
|
|
|
export function oceanBookingDraftWithoutCustomer(context, suffix, master, labels = {}) {
|
|
const draft = oceanBookingDraft(context, suffix, master, labels)
|
|
delete draft.customerId
|
|
delete draft.customerName
|
|
return draft
|
|
}
|