test: verify complete PDA batch history

This commit is contained in:
2026-08-25 13:59:58 +08:00
parent 98766e2b1a
commit 9093550615
5 changed files with 49 additions and 13 deletions
@@ -566,6 +566,10 @@ export async function run(context) {
const batchPath = `${pdaBase}/tasks/${canonicalTaskId}/batch`
const batchKey = `${context.marker}-bridge-batch`.slice(0, 128)
const skipBatchKey = `${context.marker}-exception-skip-batch`.slice(0, 128)
const partialBatchKey = `${context.marker}-exception-partial-batch`.slice(0, 128)
const dynamicBatchKey = `${context.marker}-dynamic-pick`.slice(0, 128)
const expectedBatchOperationIds = [batchKey, skipBatchKey, partialBatchKey, dynamicBatchKey]
const batchPayload = {
warehouseId, loadingPlanId, containerBookingId,
expectedVersion: Number(claimed?.version),
@@ -1021,6 +1025,8 @@ export async function run(context) {
const incrementalFixture = context.createdResources?.orchestrationFixtures?.phase3LoadingIncremental
const incrementalInboundId = id(incrementalFixture?.inboundId)
let skipBatchVerified = false
let partialBatchVerified = false
let dynamicIncrementVerified = false
if (!incrementalInboundId || incrementalFixture?.marker !== context.marker || incrementalInboundId === inboundId) {
context.addStep(MODULE, '取得本轮独立动态增量入库单', null, false,
@@ -1068,10 +1074,10 @@ export async function run(context) {
expectedVersion: Number(skipTask?.version), inventorySnapshotToken: skipInventory?.snapshotToken,
items: [{ itemId: id(skipTaskItem?.id), action: 'SKIP', version: Number(skipTaskItem?.version),
reason: skipReason }],
}, { 'Idempotency-Key': `${context.marker}-exception-skip-batch`.slice(0, 128) })
}, { 'Idempotency-Key': skipBatchKey })
const skippedTask = context.apiSuccess(MODULE, 'SKIP 携带异常原因并原子解决待拣明细', skipBatchResponse, '', OPTIONS)
const skippedTaskItem = skippedTask?.items?.find?.((item) => id(item?.id) === id(skipTaskItem?.id))
context.assert(MODULE, '合法 SKIP 保存零实拣事实并恢复 AWAITING_REVIEW', skipBatchResponse,
skipBatchVerified = context.assert(MODULE, '合法 SKIP 保存零实拣事实并恢复 AWAITING_REVIEW', skipBatchResponse,
Boolean(skipReason.trim()) && skippedTaskItem?.itemStatus === 'SKIPPED'
&& Number(skippedTaskItem?.pickedPackageCount) === 0
&& skippedTask?.workflowStatus === 'AWAITING_REVIEW' && skippedTask?.taskStatus === 'LOADING',
@@ -1125,10 +1131,10 @@ export async function run(context) {
inventorySnapshotToken: partialInventory?.snapshotToken,
items: [{ itemId: id(unresolvedTaskItem?.id), action: 'PARTIAL', finalPickedPackageCount: 1,
releaseMode: 'MANUAL', locationIds: [], version: Number(unresolvedTaskItem?.version) }],
}, { 'Idempotency-Key': `${context.marker}-exception-partial-batch`.slice(0, 128) })
}, { 'Idempotency-Key': partialBatchKey })
const partialTask = context.apiSuccess(MODULE, '合法 PARTIAL 解决未完成明细', partialBatchResponse, '', OPTIONS)
const partialTaskItem = partialTask?.items?.find?.((item) => id(item?.id) === id(unresolvedTaskItem?.id))
context.assert(MODULE, '部分拣货数量守恒并恢复最终可确认状态', partialBatchResponse,
partialBatchVerified = context.assert(MODULE, '部分拣货数量守恒并恢复最终可确认状态', partialBatchResponse,
partialTaskItem?.itemStatus === 'PARTIAL' && Number(partialTaskItem?.plannedPackageCount) === 2
&& Number(partialTaskItem?.pickedPackageCount) === 1
&& partialTask?.workflowStatus === 'AWAITING_REVIEW' && partialTask?.taskStatus === 'LOADING',
@@ -1226,7 +1232,6 @@ export async function run(context) {
context.assert(MODULE, '动态增量 fixture 至少保留两件可用数量供调整与最小已拣门禁', dynamicCandidatesResponse,
Number(dynamicCandidate?.availablePackageCount) >= 2,
`availablePackageCount=${dynamicCandidate?.availablePackageCount ?? 'missing'}`, OPTIONS)
if (Number(dynamicCandidate?.availablePackageCount) < 2) return
if (Number(dynamicCandidate?.availablePackageCount) >= 2 && reassignedPlanItem?.id) {
const adjustResponse = await request(context, 'PATCH',
`${smartLoadingBase}/plans/${loadingPlanId}/items/${encodeURIComponent(id(reassignedPlanItem.id))}`, {
@@ -1259,7 +1264,7 @@ export async function run(context) {
inventorySnapshotToken: refreshedDynamicInventory?.snapshotToken,
items: [{ itemId: id(refreshedDynamicTaskItem?.id), action: 'PICK', pickedPackageCount: Number(reassignedPlanItem?.packageCount),
releaseMode: 'MANUAL', locationIds: [], version: Number(refreshedDynamicTaskItem?.version) }],
}, { 'Idempotency-Key': `${context.marker}-dynamic-pick`.slice(0, 128) })
}, { 'Idempotency-Key': dynamicBatchKey })
const dynamicPickedTask = context.apiSuccess(MODULE, '刷新后完成动态新增项拣货', dynamicBatchResponse, '', OPTIONS)
context.assert(MODULE, '动态新增项拣完后同一任务重新进入 AWAITING_REVIEW', dynamicBatchResponse,
id(dynamicPickedTask?.id) === canonicalTaskId && dynamicPickedTask?.workflowStatus === 'AWAITING_REVIEW'
@@ -1341,7 +1346,8 @@ export async function run(context) {
atomicBatchVerified: awaitingReview && atomicBatchReplayVerified,
inventorySnapshotVerified: inventorySnapshotVerified && atomicBatchReplayVerified,
inventoryMutationVerified, inventoryMutationCleanup,
dynamicIncrementVerified, incrementalInboundId,
skipBatchVerified, partialBatchVerified, dynamicIncrementVerified,
expectedBatchOperationIds, incrementalInboundId,
pdaTaskVersion: Number(stagedTask?.version),
marker: context.marker, inboundStatus: 'LOADING', loadingPlanStatus: 'LOADING', finalStatus: 'AWAITING_REVIEW',
}