收敛海外PDA回归夹具选择

This commit is contained in:
2026-09-02 16:01:58 +08:00
parent 5f688d6131
commit 601ae83504
3 changed files with 27 additions and 19 deletions
@@ -48,22 +48,27 @@ async function ensureMatsonSupplier(context, records) {
} }
export function stableLoadedCartonMarks(items) { export function stableLoadedCartonMarks(items) {
const used = new Set() const groups = new Map()
return [...(Array.isArray(items) ? items : [])] for (const item of [...(Array.isArray(items) ? items : [])]
.sort((left, right) => id(left?.loadingPlanItemId).localeCompare(id(right?.loadingPlanItemId))) .sort((left, right) => id(left?.loadingPlanItemId).localeCompare(id(right?.loadingPlanItemId)))
.flatMap((item) => { ) {
const count = Math.max(0, Number(item?.pickedPackageCount) || 0) const groupKey = id(item?.inboundId) || `item:${id(item?.loadingPlanItemId)}`
const labels = [...new Set((item?.boxCodes || []) const group = groups.get(groupKey) || { count: 0, labels: new Set() }
.map((value) => String(value || '').trim()).filter((value) => value && !used.has(value)))] group.count += Math.max(0, Number(item?.pickedPackageCount) || 0)
// Partial loading keeps the lowest carton indexes on the loaded source inbound and for (const value of item?.boxCodes || []) {
// transfers the highest indexes to the remainder child. Mirror that settlement rule const label = String(value || '').trim()
// instead of sampling labels, otherwise downstream PDA fixtures may reference cartons if (label) group.labels.add(label)
// that were deliberately moved out of this container. }
.sort((left, right) => left.localeCompare(right, undefined, { numeric: true, sensitivity: 'base' })) groups.set(groupKey, group)
.slice(0, count) }
labels.forEach((value) => used.add(value)) // Settlement transfers the highest carton indexes to the remainder child for the whole
return labels // inbound, not per cargo line. Aggregate task rows by inbound before selecting the retained
}) // low indexes so the downstream fixture mirrors the persisted container manifest.
return [...groups.entries()]
.sort(([left], [right]) => left.localeCompare(right))
.flatMap(([, group]) => [...group.labels]
.sort((left, right) => left.localeCompare(right, undefined, { numeric: true, sensitivity: 'base' }))
.slice(0, group.count))
} }
async function request(context, method, path, body, headers = {}) { async function request(context, method, path, body, headers = {}) {
@@ -447,9 +447,12 @@ test('preload and loading versions use immediate operation baselines and exact p
test('loaded carton fixture mirrors partial settlement and keeps the lowest carton indexes', () => { test('loaded carton fixture mirrors partial settlement and keeps the lowest carton indexes', () => {
const marks = stableLoadedCartonMarks([ const marks = stableLoadedCartonMarks([
{ loadingPlanItemId: '20', pickedPackageCount: 3, { loadingPlanItemId: '30', inboundId: '200', pickedPackageCount: 1,
boxCodes: ['NYEXX2609020358#8-5', 'NYEXX2609020358#8-2', 'NYEXX2609020358#8-1', 'NYEXX2609020358#8-3'] }, boxCodes: ['NYEXX2609020358#8-5'] },
{ loadingPlanItemId: '10', pickedPackageCount: 1, boxCodes: ['NYEXX2609020357#4-4', 'NYEXX2609020357#4-1'] }, { loadingPlanItemId: '20', inboundId: '200', pickedPackageCount: 2,
boxCodes: ['NYEXX2609020358#8-2', 'NYEXX2609020358#8-1', 'NYEXX2609020358#8-3'] },
{ loadingPlanItemId: '10', inboundId: '100', pickedPackageCount: 1,
boxCodes: ['NYEXX2609020357#4-4', 'NYEXX2609020357#4-1'] },
]) ])
assert.deepEqual(marks, [ assert.deepEqual(marks, [
'NYEXX2609020357#4-1', 'NYEXX2609020357#4-1',
@@ -529,7 +529,7 @@ async function runReceiving(context, token, secondaryToken, merchantToken, prefe
`/api/pda/v1/last-leg/receiving-containers/${encodeURIComponent(containerNo)}/prepare`, `/api/pda/v1/last-leg/receiving-containers/${encodeURIComponent(containerNo)}/prepare`,
{ idempotencyKey: key(context, 'secondary-prepare') }, conflict) { idempotencyKey: key(context, 'secondary-prepare') }, conflict)
} }
const other = candidates.data.find((item) => item.containerNo !== containerNo) const other = candidates.data.find((item) => item.containerNo !== containerNo && item.operable === true)
if (other) await expected(context, token, 'GET', '当前账号跨柜切换锁返回409', if (other) await expected(context, token, 'GET', '当前账号跨柜切换锁返回409',
`/api/pda/v1/last-leg/receiving-containers/${encodeURIComponent(other.containerNo)}`, undefined, conflict) `/api/pda/v1/last-leg/receiving-containers/${encodeURIComponent(other.containerNo)}`, undefined, conflict)
else blockerGap(context, '跨柜锁409', '当前客户只有一个待收柜,无法在不伪造柜数据的前提下验证跨柜锁') else blockerGap(context, '跨柜锁409', '当前客户只有一个待收柜,无法在不伪造柜数据的前提下验证跨柜锁')