diff --git a/scripts/admin-test-env-modules/phase4-overseas-pda-operations-contract.test.mjs b/scripts/admin-test-env-modules/phase4-overseas-pda-operations-contract.test.mjs index 254a5b2f6..e6bd0c0fa 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-pda-operations-contract.test.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-pda-operations-contract.test.mjs @@ -78,6 +78,14 @@ test('PDA operations reuse received plan pallets and the public location without assert.doesNotMatch(source, /createLocation|createEmptyPallet/) }) +test('P5 follows warehouse review, customer confirmation and fulfillment completion in order', () => { + assert.match(source, /applicationStatus === 'CUSTOMER_CONFIRM_PENDING'/) + assert.match(source, /\/confirm-completion/) + assert.match(source, /status === 'READY_FOR_OUTBOUND'/) + assert.match(source, /status: 'COMPLETED'/) + assert.match(source, /walletStatus === 'SETTLED'/) +}) + test('fixture failure still disables both picker accounts and removes all transient tokens', async () => { const cleanups = [] const gaps = [] diff --git a/scripts/admin-test-env-modules/phase4-overseas-pda-operations.mjs b/scripts/admin-test-env-modules/phase4-overseas-pda-operations.mjs index d0799d931..d22b2210b 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-pda-operations.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-pda-operations.mjs @@ -4,6 +4,7 @@ const OPTIONS = { scenario: SCENARIO, deploymentBlocker: true } const PNG = Uint8Array.from(Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=', 'base64')) function id(value) { return value == null ? '' : String(value) } +function longId(value) { return /^\d+$/.test(String(value || '')) && String(value) !== '0' } function nonBlank(value) { return typeof value === 'string' && value.trim() !== '' } function success(response) { return response?.http === 200 && String(response?.body?.code) === '200' } function conflict(response) { @@ -511,9 +512,24 @@ async function verifyRelabel(context, token, merchantToken, fixture) { idempotencyKey: key(context, 'RELABEL-APPROVE'), remark: `${context.marker}-approved` } const approved = await request(context, token, 'POST', 'P5复核批准换标完成', reviewPath, approveBody) const approveReplay = await request(context, token, 'POST', 'P5批准同键重放', reviewPath, approveBody) - context.assert(MODULE, 'P5最终任务和申请均COMPLETED', approveReplay.response, - approved.data?.taskStatus === 'COMPLETED' && approved.data?.applicationStatus === 'COMPLETED' - && approveReplay.data?.taskStatus === 'COMPLETED', trace(approveReplay.response), OPTIONS) + context.assert(MODULE, 'P5仓库复核完成并进入客户确认', approveReplay.response, + approved.data?.taskStatus === 'COMPLETED' + && approved.data?.applicationStatus === 'CUSTOMER_CONFIRM_PENDING' + && approveReplay.data?.taskStatus === 'COMPLETED' + && approveReplay.data?.applicationStatus === 'CUSTOMER_CONFIRM_PENDING', trace(approveReplay.response), OPTIONS) + const customerConfirm = await context.requestOverseas('POST', + `${relabelBase}/${encodeURIComponent(relabelNo)}/confirm-completion`, { + idempotencyKey: key(context, 'RELABEL-CUSTOMER-CONFIRM'), remark: `${context.marker}-customer-confirm`, + }, {}, merchantToken) + context.addStep(MODULE, 'P5客户确认换标完成进入待出库', customerConfirm, + success(customerConfirm) && customerConfirm.body?.data?.application?.status === 'READY_FOR_OUTBOUND', + trace(customerConfirm), OPTIONS) + const terminal = await context.requestOverseas('PUT', + `${relabelBase}/${encodeURIComponent(relabelNo)}/status`, { + status: 'COMPLETED', remark: `${context.marker}-fulfillment-complete`, + }) + context.addStep(MODULE, 'P5待出库换标单完成履约', terminal, + success(terminal) && terminal.body?.data?.application?.status === 'COMPLETED', trace(terminal), OPTIONS) const settled = await poll(async () => context.requestOverseas('GET', `${relabelBase}/${encodeURIComponent(relabelNo)}`), (response) => success(response) && response.body?.data?.application?.walletStatus === 'SETTLED') context.addStep(MODULE, 'P5换标完成后钱包结算收敛', settled.result, diff --git a/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost-contract.test.mjs b/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost-contract.test.mjs index 191efa229..6d447dff7 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost-contract.test.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost-contract.test.mjs @@ -29,6 +29,8 @@ test('钱包闭环覆盖充值、授信、采购冻结结算和换标结算释 'item.sourceNo === businessNo', "'RELEASED'", "terminalStatus === 'COMPLETED'", + "status: 'CUSTOMER_CONFIRM_PENDING'", + "status: 'READY_FOR_OUTBOUND'", "'CANCELLED'", 'relabelPayload(context, warehouseId, source, suffix, 0.01)', '/relabel-applications/inventory-candidates', diff --git a/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost.mjs b/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost.mjs index 9e7ccde98..bbb213f2f 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost.mjs @@ -226,6 +226,14 @@ async function relabelFlow(context, overseasToken, warehouseId, suffix, terminal const processing = await context.requestOverseas('PUT', `${detailPath}/status`, { status: 'PROCESSING', remark: context.marker }) assert(context, '换标单冻结后才允许进入处理中', processing, success(processing) && processing.body.data?.application?.status === 'PROCESSING') + const confirmPending = await context.requestOverseas('PUT', `${detailPath}/status`, + { status: 'CUSTOMER_CONFIRM_PENDING', remark: context.marker }) + assert(context, '换标处理完成后进入客户确认', confirmPending, + success(confirmPending) && confirmPending.body.data?.application?.status === 'CUSTOMER_CONFIRM_PENDING') + const readyForOutbound = await context.requestOverseas('PUT', `${detailPath}/status`, + { status: 'READY_FOR_OUTBOUND', remark: context.marker }) + assert(context, '换标客户确认后进入待出库', readyForOutbound, + success(readyForOutbound) && readyForOutbound.body.data?.application?.status === 'READY_FOR_OUTBOUND') } const terminal = await context.requestOverseas('PUT', `${detailPath}/status`, { status: terminalStatus, remark: context.marker }) assert(context, `${suffix}换标单进入${terminalStatus}`, terminal,