Files
baiyue-firstleg/scripts/admin-test-env-modules/manual-pda-ready-fixture.mjs
T

90 lines
5.7 KiB
JavaScript

import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const MODULE = 'manual-pda-ready-fixture'
const OPTIONS = { scenario: 'manual-pda-ready-fixture', deploymentBlocker: true }
const SMART = '/api/platform/v1/first-leg/smart-loading'
const FIRST_LEG = '/api/platform/v1/first-leg'
const CONTAINERS = '/api/platform/v1/containers'
const PDA = `${FIRST_LEG}/pda-loading`
function id(value) { return value == null ? '' : String(value) }
function rows(value) { return Array.isArray(value) ? value : [] }
function codeOf(response) { return response?.body?.code == null ? 'missing' : String(response.body.code) }
function items(value) {
return rows(value).map((item) => ({ id: id(item.id), inboundId: id(item.inboundId),
packageCount: Number(item.packageCount) }))
.sort((left, right) => left.inboundId.localeCompare(right.inboundId) || left.id.localeCompare(right.id))
}
async function loadSource(context) {
const report = JSON.parse(await readFile(resolve(context.options.manualPdaSourceReport), 'utf8'))
const source = report?.createdResources?.manualPreloadPushVerification
const sourceGateway = String(report?.gateway || '').replace(/\/$/, '')
const valid = sourceGateway === context.options.gateway && source?.stage === 'PRELOAD_EDITING'
&& source?.loadingPlanId && source?.containerBookingId && source?.pdaTaskCreated === false
&& Array.isArray(source?.expectedAssignments) && source.expectedAssignments.length > 0
context.assert(MODULE, '读取同环境推送预装核验报告', null, valid,
`sourceMarker=${report?.marker || 'missing'}, sameGateway=${sourceGateway === context.options.gateway}, loadingPlanId=${id(source?.loadingPlanId) || 'missing'}`,
OPTIONS)
return valid ? source : null
}
export async function run(context) {
const source = await loadSource(context)
if (!source) return
const planId = id(source.loadingPlanId)
const containerId = id(source.containerBookingId)
const planResponse = await context.request('GET', `${SMART}/plans/${encodeURIComponent(planId)}`)
const plan = context.apiSuccess(MODULE, 'PDA 就绪操作前读取预装计划', planResponse, '', OPTIONS)
const beforeItems = items(plan?.items)
context.assert(MODULE, '操作前计划仍为无号已推送 EDITING', planResponse,
id(plan?.id) === planId && plan?.status === 'EDITING' && plan?.containerNo == null
&& Number(plan?.version) === Number(source.planVersion) && beforeItems.length > 0,
`status=${plan?.status || 'missing'}, expectedVersion=${source.planVersion}, actualVersion=${plan?.version ?? 'missing'}, items=${beforeItems.length}`,
OPTIONS)
if (!plan || beforeItems.length === 0) return
const containerResponse = await context.request('GET', `${CONTAINERS}/domestic/${encodeURIComponent(containerId)}`)
const container = context.apiSuccess(MODULE, 'PDA 就绪操作前读取内部模拟柜', containerResponse, '', OPTIONS)?.container
context.assert(MODULE, '操作前柜次仍无真实柜号和订舱关联', containerResponse,
id(container?.id) === containerId && container?.cabinetNo === source.cabinetNo
&& container?.containerNo == null && container?.oceanBookingId == null
&& Number.isInteger(Number(container?.version)),
`cabinetNo=${container?.cabinetNo || 'missing'}, containerNo=${container?.containerNo || 'null'}, oceanBookingId=${id(container?.oceanBookingId) || 'null'}, version=${container?.version ?? 'missing'}`,
OPTIONS)
const detailResponse = await context.request('GET',
`${FIRST_LEG}/loading-plans/${encodeURIComponent(planId)}?warehouseId=${encodeURIComponent(source.warehouseId)}`)
const detail = context.apiSuccess(MODULE, '操作前读取预装确认门禁', detailResponse, '', OPTIONS)
context.assert(MODULE, '缺少真实柜号与 RELEASED 订舱时不能确认预装', detailResponse,
detail?.summary?.status === 'EDITING' && detail?.summary?.readiness?.canConfirm === false
&& detail?.summary?.readiness?.readyForPda === false
&& detail?.summary?.readiness?.pdaTaskId == null,
`canConfirm=${detail?.summary?.readiness?.canConfirm}, readyForPda=${detail?.summary?.readiness?.readyForPda}, blockers=${rows(detail?.summary?.readiness?.blockers).join(',')}`,
OPTIONS)
const taskResponse = await context.request('GET',
`${PDA}/tasks?loadingPlanId=${encodeURIComponent(planId)}&warehouseId=${encodeURIComponent(source.warehouseId)}`)
context.addStep(MODULE, '操作前 PDA 任务仍不存在', taskResponse,
taskResponse.http === 200 && codeOf(taskResponse) === 'A0404',
`HTTP=${taskResponse.http}, code=${codeOf(taskResponse)}`, OPTIONS)
context.createdResources.manualPdaReadyFixture = {
schemaVersion: 1, sourceMarker: source.sourceMarker, preparedAt: new Date().toISOString(),
stage: 'MANUAL_BOOKING_LINK_CONFIRM_READY', loadingPlanId: planId, containerBookingId: containerId,
cabinetNo: source.cabinetNo, tenantId: id(source.tenantId), warehouseId: id(source.warehouseId),
channelCode: source.channelCode, beforePlanVersion: Number(plan.version),
beforeContainerVersion: Number(container?.version), beforeItems,
expectedAssignments: source.expectedAssignments || [],
instructions: [
'在订舱页面创建与本清单客户、起运仓、渠道和柜型一致的 DRAFT 订舱,并填写承运船司代码 carrierCode 及完整运输资料。',
'确认放舱,使订舱进入 RELEASED;放舱本身不得创建货柜。',
'在原 containerBookingId 上选择该订舱未占用的柜型需求,录入唯一真实 containerNo 完成关联。',
'回到预装详情,确认 canConfirm=true 后执行整份计划确认;不要领取 PDA 任务。',
'记录 bookingNo、containerNo,并立即运行 manual-pda-ready-verify。',
],
}
}