diff --git a/scripts/admin-test-env-modules/phase3-container-documents.mjs b/scripts/admin-test-env-modules/phase3-container-documents.mjs index c76a65d4e..93c2ba943 100644 --- a/scripts/admin-test-env-modules/phase3-container-documents.mjs +++ b/scripts/admin-test-env-modules/phase3-container-documents.mjs @@ -11,7 +11,7 @@ function codeOf(response) { return response?.body?.code == null ? 'missing' : St function success(response) { return response?.http === 200 && codeOf(response) === '200' } function conflict(response) { return response?.http === 200 && codeOf(response) === 'A0409' } function traced(response) { return Boolean(response?.requestId) && Boolean(response?.traceId) } -function key(context, label) { return `${context.marker}-four-documents-${label}`.slice(0, 128) } +function key(context, label) { return `${context.marker}-operational-documents-${label}`.slice(0, 128) } function validDocument(document, type, completed) { return Boolean(document?.id) && Boolean(document?.fileId) && document?.documentType === type && /^[0-9a-f]{64}$/i.test(String(document?.fileHash || '')) diff --git a/scripts/admin-test-env-modules/phase4-overseas-pda.mjs b/scripts/admin-test-env-modules/phase4-overseas-pda.mjs index 1c87eb5f7..b2036d8d0 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-pda.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-pda.mjs @@ -752,6 +752,7 @@ export async function run(context) { primary: primary ? { membershipId: primary.membershipId, username: primary.username, token: primary.token } : null, secondary: secondary ? { membershipId: secondary.membershipId, username: secondary.username, token: secondary.token } : null, overseasWarehouseId: sharedWarehouse.id, + merchantToken, completedFixtures: [], cleanup, } diff --git a/scripts/admin-test-env-modules/phase5-overseas-fulfillment-contract.test.mjs b/scripts/admin-test-env-modules/phase5-overseas-fulfillment-contract.test.mjs index 36cc8df3a..a2a9271f9 100644 --- a/scripts/admin-test-env-modules/phase5-overseas-fulfillment-contract.test.mjs +++ b/scripts/admin-test-env-modules/phase5-overseas-fulfillment-contract.test.mjs @@ -58,6 +58,8 @@ test('phase-five module proves completion, customer visit, manual exception and '/customer-visits/${encodeURIComponent(visitId)}', "visitResult: 'SATISFIED'", '/exception-orders', '/return-inbound-options', '/mark-return', "returnDirection: 'OVERSEAS_WAREHOUSE'", + 'returnSources', 'outboundPalletItemId', 'inventoryPositionId', + "idempotencyKey: key(context, 'DELIVERY-RETURN')", '派送退回同键同载荷重放', 'RETURN_PENDING_WITH_COMPLETED_VISIT', ]) assert.ok(source.includes(token), token) assert.match(source, /manualExceptionNo/) diff --git a/scripts/admin-test-env-modules/phase5-overseas-fulfillment.mjs b/scripts/admin-test-env-modules/phase5-overseas-fulfillment.mjs index def07f1e2..e3ffdb708 100644 --- a/scripts/admin-test-env-modules/phase5-overseas-fulfillment.mjs +++ b/scripts/admin-test-env-modules/phase5-overseas-fulfillment.mjs @@ -321,18 +321,36 @@ export async function run(context) { context.assert(MODULE, '退回候选严格属于当前派送单', returnOptions.response, Boolean(returnInbound), `candidate=${Boolean(returnInbound)}; ${trace(returnOptions.response)}`, OPTIONS) if (!returnInbound) return + const returnSource = Array.isArray(returnInbound.returnSources) + ? returnInbound.returnSources.find((value) => id(value?.outboundPalletItemId) + && id(value?.inventoryPositionId) && Number(value?.maxReturnPackages) > 0) : null + context.assert(MODULE, '退回候选包含可追溯的出库托盘库存来源', returnOptions.response, + Boolean(returnSource), `source=${Boolean(returnSource)}; ${trace(returnOptions.response)}`, OPTIONS) + if (!returnSource) return + const returnBody = { + inboundOrderId: id(returnInbound.inboundOrderId), reason: `${context.marker}-delivery-return`, + returnDirection: 'OVERSEAS_WAREHOUSE', returnLogisticsNo: `${context.marker}-RETURN`.slice(0, 128), + items: [{ + outboundPalletItemId: id(returnSource.outboundPalletItemId), + inventoryPositionId: id(returnSource.inventoryPositionId), + packageCount: 1, + }], + idempotencyKey: key(context, 'DELIVERY-RETURN'), + } const returned = await platform(context, 'POST', '标记派送退回海外仓并创建退货异常', - query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}/mark-return`, { customerId }), { - inboundOrderId: id(returnInbound.inboundOrderId), reason: `${context.marker}-delivery-return`, - returnDirection: 'OVERSEAS_WAREHOUSE', returnLogisticsNo: `${context.marker}-RETURN`.slice(0, 128), - packageCount: 1, skuCode: null, - }) + query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}/mark-return`, { customerId }), returnBody) const returnExceptionNo = id(returned.data?.exceptionNo) context.assert(MODULE, '派送退回生成独立PENDING异常单', returned.response, nonBlank(returnExceptionNo) && returned.data?.status === 'PENDING' && returnExceptionNo !== manualExceptionNo, trace(returned.response), OPTIONS) context.createdResources.phase5OverseasFulfillment.returnExceptionNo = returnExceptionNo || null + const returnReplay = await platform(context, 'POST', '派送退回同键同载荷重放', + query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}/mark-return`, { customerId }), returnBody) + context.assert(MODULE, '派送退回重放复用同一异常单', returnReplay.response, + returnReplay.data?.replayed === true && id(returnReplay.data?.exceptionNo) === returnExceptionNo, + trace(returnReplay.response), OPTIONS) + const delivery = await platform(context, 'GET', '回查派送退回终态', query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}`, { customerId })) context.assert(MODULE, '派送退回后单据状态为RETURN_PENDING且保留出库关联', delivery.response,