test: complete phase4 PDA shipping prerequisites
This commit is contained in:
@@ -205,22 +205,63 @@ async function uploadPhotos(context, token) {
|
||||
return photos
|
||||
}
|
||||
|
||||
async function awaitProducerCandidates(context, token, producers) {
|
||||
async function awaitProducerConsumption(context, producers) {
|
||||
const expected = [...new Set(producers.map((item) => id(item?.containerNo)).filter(nonBlank))]
|
||||
if (!expected.length) return true
|
||||
const consumed = new Set()
|
||||
const lastResponses = new Map()
|
||||
for (let attempt = 1; attempt <= 30; attempt += 1) {
|
||||
const missing = expected.filter((containerNo) => !consumed.has(containerNo))
|
||||
const results = await Promise.all(missing.map(async (containerNo) => {
|
||||
const response = await context.requestOverseas('GET',
|
||||
`/api/platform/v1/last-leg/orders?page=1&size=200&containerNo=${encodeURIComponent(containerNo)}`)
|
||||
return { containerNo, response }
|
||||
}))
|
||||
for (const { containerNo, response } of results) {
|
||||
lastResponses.set(containerNo, response)
|
||||
const rows = records(response?.body?.data)
|
||||
if (success(response) && rows.some((item) => id(item?.containerNo) === containerNo)) {
|
||||
consumed.add(containerNo)
|
||||
}
|
||||
}
|
||||
if (expected.every((containerNo) => consumed.has(containerNo))) break
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
}
|
||||
for (const containerNo of expected) {
|
||||
const response = lastResponses.get(containerNo) || null
|
||||
context.addStep(MODULE, `跨区消费生成尾程订单 ${containerNo}`, response,
|
||||
consumed.has(containerNo),
|
||||
`containerNo=${containerNo}, consumed=${consumed.has(containerNo)}; ${trace(response)}`, OPTIONS)
|
||||
}
|
||||
return expected.every((containerNo) => consumed.has(containerNo))
|
||||
}
|
||||
|
||||
async function awaitPickupReadyCandidates(context, token, producers, allProducers) {
|
||||
const expected = [...new Set(producers.map((item) => id(item?.containerNo)).filter(nonBlank))]
|
||||
const expectedSet = new Set(expected)
|
||||
const awaiting = [...new Set(allProducers
|
||||
.filter((item) => item?.shippingReady === false && !expectedSet.has(id(item?.containerNo)))
|
||||
.map((item) => id(item?.containerNo)).filter(nonBlank))]
|
||||
const known = new Set(allProducers.map((item) => id(item?.containerNo)).filter(nonBlank))
|
||||
if (!expected.length) return false
|
||||
let response = null
|
||||
let seen = new Set()
|
||||
for (let attempt = 1; attempt <= 30; attempt += 1) {
|
||||
response = await context.requestOverseas('GET',
|
||||
'/api/pda/v1/last-leg/receiving-containers/candidates', undefined, {}, token)
|
||||
const records = success(response) && Array.isArray(response.body?.data) ? response.body.data : []
|
||||
seen = new Set(records.map((item) => id(item?.containerNo)).filter(nonBlank))
|
||||
if (expected.every((containerNo) => seen.has(containerNo))) break
|
||||
const candidateRows = success(response) && Array.isArray(response.body?.data) ? response.body.data : []
|
||||
seen = new Set(candidateRows.map((item) => id(item?.containerNo)).filter(nonBlank))
|
||||
if (expected.every((containerNo) => seen.has(containerNo))
|
||||
&& awaiting.every((containerNo) => !seen.has(containerNo))) break
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
}
|
||||
const ready = expected.every((containerNo) => seen.has(containerNo))
|
||||
context.addStep(MODULE, '三期生产矩阵全部进入海外待收候选后再开始PDA', response, ready,
|
||||
`expected=${expected.join('|')}, seen=${[...seen].join('|')}; ${trace(response)}`, OPTIONS)
|
||||
const seenExpected = expected.filter((containerNo) => seen.has(containerNo))
|
||||
const missingPickupReady = expected.filter((containerNo) => !seen.has(containerNo))
|
||||
const unexpectedAwaiting = awaiting.filter((containerNo) => seen.has(containerNo))
|
||||
const unexpectedHistorical = [...seen].filter((containerNo) => !known.has(containerNo))
|
||||
const ready = missingPickupReady.length === 0 && unexpectedAwaiting.length === 0
|
||||
context.addStep(MODULE, '实际处理柜全部达到PICKUP_READY并进入PDA候选', response, ready,
|
||||
`expected=${expected.join('|')}, awaiting=${awaiting.join('|') || 'none'}, seenExpected=${seenExpected.join('|') || 'none'}, missingPickupReady=${missingPickupReady.join('|') || 'none'}, unexpectedAwaiting=${unexpectedAwaiting.join('|') || 'none'}, unexpectedHistorical=${unexpectedHistorical.join('|') || 'none'}; ${trace(response)}`, OPTIONS)
|
||||
return ready
|
||||
}
|
||||
|
||||
@@ -501,9 +542,14 @@ export async function run(context) {
|
||||
const producers = [dropship || matrix?.byDestinationType?.FBA?.[0], matrix?.byDestinationType?.OVERSEAS?.[0]]
|
||||
.filter((item) => nonBlank(item?.containerNo))
|
||||
const allProducers = Array.isArray(matrix?.containers) ? matrix.containers : producers
|
||||
if (allProducers.length && !(await awaitProducerCandidates(context, primary.token, allProducers))) {
|
||||
blockerGap(context, '海外待收柜生产矩阵',
|
||||
'三期已发布的FBA、OVERSEAS和第二柜尚未全部被海外事件消费者提交,禁止与消费事务并发入库')
|
||||
if (allProducers.length && !(await awaitProducerConsumption(context, allProducers))) {
|
||||
blockerGap(context, '跨区消费生产矩阵',
|
||||
'三期已发布的四柜尚未全部由海外消费者生成尾程订单,禁止把PICKUP_READY缺口与事件消费混为一谈')
|
||||
return
|
||||
}
|
||||
if (producers.length && !(await awaitPickupReadyCandidates(context, primary.token, producers, allProducers))) {
|
||||
blockerGap(context, '实际处理柜PICKUP_READY门禁',
|
||||
'Dropship/FBA与OVERSEAS实际处理柜尚未全部达到PICKUP_READY;跨区消费已独立验证,不回退处理历史柜')
|
||||
return
|
||||
}
|
||||
for (const [index, producer] of (producers.length ? producers : [null]).entries()) {
|
||||
|
||||
Reference in New Issue
Block a user