fix: complete pallet code cross-region flow
This commit is contained in:
@@ -78,6 +78,70 @@ async function request(context, method, path, body, headers = {}) {
|
||||
return { method, path, http: 0, body: null, raw: String(error), requestId: null, traceId: null }
|
||||
}
|
||||
}
|
||||
|
||||
async function requestPdf(context, path, body) {
|
||||
try {
|
||||
const response = await fetch(`${context.options.gateway}${path}`, {
|
||||
method: 'POST',
|
||||
headers: { Accept: 'application/pdf', Authorization: `Bearer ${context.token}`,
|
||||
'Content-Type': 'application/json; charset=utf-8' },
|
||||
body: JSON.stringify(body), signal: AbortSignal.timeout(60_000),
|
||||
})
|
||||
const bytes = new Uint8Array(await response.arrayBuffer())
|
||||
return { method: 'POST', path, http: response.status, body: null, raw: null,
|
||||
contentType: response.headers.get('content-type'), byteLength: bytes.length,
|
||||
pdfMagic: String.fromCharCode(...bytes.slice(0, 4)),
|
||||
requestId: response.headers.get('x-request-id'), traceId: response.headers.get('x-trace-id') }
|
||||
} catch (error) {
|
||||
return { method: 'POST', path, http: 0, body: null, raw: String(error), contentType: null,
|
||||
byteLength: 0, pdfMagic: null, requestId: null, traceId: null }
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyPalletLabels(context, fixture, loadingPlanId) {
|
||||
if (fixture.destinationType !== 'FBA' || fixture.fulfillmentType === 'ONE_CLICK_DROPSHIP') return null
|
||||
const warehouseId = id(fixture.warehouseId)
|
||||
const base = `/api/platform/v1/first-leg/loading-plans/${encodeURIComponent(loadingPlanId)}/pallet-labels`
|
||||
const path = `${base}/prepare?warehouseId=${encodeURIComponent(warehouseId)}`
|
||||
const preparedResponse = await context.request('POST', path, {})
|
||||
const manifest = context.apiSuccess(MODULE, '生成并读取按 FBA 仓分组的散货托盘码清单', preparedResponse, '', OPTIONS)
|
||||
const labels = (manifest?.groups || []).flatMap((group) => group?.labels || [])
|
||||
const codesValid = labels.length > 0 && labels.every((label) => {
|
||||
const index = Number(label?.palletIndex)
|
||||
return id(label?.containerNo) === id(fixture.containerNo)
|
||||
&& id(label?.destinationWarehouseInternalCode)
|
||||
&& id(label?.palletCode) === `${fixture.containerNo}-${label.destinationWarehouseInternalCode}-${String(index).padStart(3, '0')}`
|
||||
})
|
||||
const indexesValid = (manifest?.groups || []).every((group) =>
|
||||
(group?.labels || []).every((label, index) => Number(label?.palletIndex) === index + 1))
|
||||
context.assert(MODULE, '散货托盘码使用柜号-FBA内部编号-仓内连续下标', preparedResponse,
|
||||
id(manifest?.containerNo) === id(fixture.containerNo)
|
||||
&& Number(manifest?.totalCount) === labels.length && codesValid && indexesValid,
|
||||
`containerNo=${manifest?.containerNo || 'missing'}, groups=${manifest?.groups?.length ?? 0}, labels=${labels.length}`,
|
||||
OPTIONS)
|
||||
|
||||
const replayResponse = await context.request('POST', path, {})
|
||||
const replay = context.apiSuccess(MODULE, '重复生成散货托盘码返回稳定清单', replayResponse, '', OPTIONS)
|
||||
context.assert(MODULE, '散货托盘码重复生成零漂移', replayResponse,
|
||||
JSON.stringify(replay) === JSON.stringify(manifest), `labels=${labels.length}`, OPTIONS)
|
||||
|
||||
const printPath = `${base}/print?warehouseId=${encodeURIComponent(warehouseId)}`
|
||||
const allPdf = await requestPdf(context, printPath, { destinationWarehouseCode: null, count: null })
|
||||
context.addStep(MODULE, '打印全部 FBA 仓散货托盘码 PDF', allPdf,
|
||||
allPdf.http === 200 && allPdf.contentType?.toLowerCase().includes('application/pdf')
|
||||
&& allPdf.pdfMagic === '%PDF' && allPdf.byteLength > 0,
|
||||
`HTTP=${allPdf.http}, type=${allPdf.contentType || 'missing'}, bytes=${allPdf.byteLength}`, OPTIONS)
|
||||
const group = manifest?.groups?.[0]
|
||||
const selectedPdf = await requestPdf(context, printPath,
|
||||
{ destinationWarehouseCode: group?.destinationWarehouseCode, count: 1 })
|
||||
context.addStep(MODULE, '按指定 FBA 仓补打 1 张托盘码 PDF', selectedPdf,
|
||||
Boolean(group?.destinationWarehouseCode) && selectedPdf.http === 200
|
||||
&& selectedPdf.contentType?.toLowerCase().includes('application/pdf')
|
||||
&& selectedPdf.pdfMagic === '%PDF' && selectedPdf.byteLength > 0,
|
||||
`warehouse=${group?.destinationWarehouseCode || 'missing'}, HTTP=${selectedPdf.http}, bytes=${selectedPdf.byteLength}`,
|
||||
OPTIONS)
|
||||
return manifest
|
||||
}
|
||||
function blockResourceIdentity(resource) {
|
||||
return JSON.stringify({
|
||||
blockId: id(resource?.blockId), slotNo: Number(resource?.slotNo),
|
||||
@@ -490,6 +554,7 @@ export async function run(context) {
|
||||
inventoryBlockSettlementVerified: expectedBlocks.length > 0
|
||||
&& releasedOrTransferredBlocks.every((item) => item.verified) && completedInventoryReleased,
|
||||
}
|
||||
const palletLabelManifest = await verifyPalletLabels(context, fixture, loadingPlanId)
|
||||
const producer = {
|
||||
marker: context.context?.phase4ProducerMatrixMarker || context.marker,
|
||||
eventType: 'FIRST_LEG_LOADING_PLAN_COMPLETED',
|
||||
@@ -511,6 +576,7 @@ export async function run(context) {
|
||||
destinationType: fixture.destinationType || null,
|
||||
destinationWarehouseId: id(fixture.destinationWarehouseId),
|
||||
destinationWarehouseCode: fixture.destinationWarehouseCode || null,
|
||||
palletLabelManifest,
|
||||
containerNo: fixture.containerNo || null,
|
||||
sourceStatus: 'LOADED',
|
||||
verification: 'PRODUCED_IN_COMPLETE_TRANSACTION_PENDING_BRIDGE_CONSUMER_HTTP',
|
||||
|
||||
Reference in New Issue
Block a user