diff --git a/scripts/admin-test-env-modules/inbound-measurement.mjs b/scripts/admin-test-env-modules/inbound-measurement.mjs index 61d26bdcf..ebcdaa981 100644 --- a/scripts/admin-test-env-modules/inbound-measurement.mjs +++ b/scripts/admin-test-env-modules/inbound-measurement.mjs @@ -397,7 +397,7 @@ export async function run(context) { const finalResponse = await context.request('GET', measurementPath) const finalMeasurement = context.apiSuccess(MODULE, '查询审核后的最终测量状态', finalResponse, '', OPTIONS) context.assert(MODULE, '审核后入库与测量状态闭环且结果未变化', finalResponse, - finalMeasurement?.processStatus === 'INBOUNDED' && finalMeasurement?.measureReviewStatus === 'APPROVED' + finalMeasurement?.processStatus === 'WAIT_SPLIT' && finalMeasurement?.measureReviewStatus === 'APPROVED' && finalMeasurement?.measurementStatus === 'APPROVED' && Number(finalMeasurement?.actualPackageCount) === originalPackageCount && closeTo(finalMeasurement?.actualVolumeCbm, totalVolume) diff --git a/scripts/admin-test-env-modules/order-inbound-status-fixtures-contract.test.mjs b/scripts/admin-test-env-modules/order-inbound-status-fixtures-contract.test.mjs index f972cc06f..9934d418b 100644 --- a/scripts/admin-test-env-modules/order-inbound-status-fixtures-contract.test.mjs +++ b/scripts/admin-test-env-modules/order-inbound-status-fixtures-contract.test.mjs @@ -24,10 +24,10 @@ test('所有写入均走订单生命周期 HTTP API 且不清理保留数据', ( assert.doesNotMatch(source, /cleanup|remove|unlink/i) }) -test('入库通过真实订单测量链保留四个测量态和 INBOUNDED', () => { +test('入库通过真实订单测量链保留测量态并最终进入 WAIT_SPLIT', () => { assert.match(source, /result\.inbounds\.WAIT_MEASURE/) assert.match(source, /processStatus: 'WAIT_MEASURE'/) - for (const status of ['MEASURING', 'MEASURE_PENDING', 'MEASURE_REJECTED', 'INBOUNDED']) { + for (const status of ['MEASURING', 'MEASURE_PENDING', 'MEASURE_REJECTED', 'WAIT_SPLIT']) { assert.match(source, new RegExp(`'${status}'`)) } assert.match(source, /\.\/inbound-measurement\.mjs/) @@ -38,7 +38,9 @@ test('入库不可独立保留状态显式阻断', () => { for (const status of ['WAIT_PRICING', 'FEE_CONFIRMING', 'INBOUNDING', 'VOIDED']) { assert.match(source, new RegExp(`${status}:`)) } - assert.match(source, /AutomaticInboundCompletionService 在同一调用内立即从 INBOUNDING 推进 INBOUNDED/) + assert.match(source, /AutomaticInboundCompletionService 在同一调用内立即从 INBOUNDING 推进 WAIT_SPLIT/) + assert.match(source, /processStatus=INBOUNDED/) + assert.match(source, /查询存量 INBOUNDED 兼容样本/) assert.match(source, /没有作废入库单 API/) assert.match(source, /context\.assert\(MODULE, `入库列表保留 \$\{status\}`/) }) @@ -49,7 +51,7 @@ test('统一订单声明合法可达状态并显式阻断废弃或无 API 状态 for (const status of ['INBOUNDED', 'WAIT_SPLIT', 'LOADING', 'LOADED', 'DELIVERED']) { assert.match(source, new RegExp(`'${status}'`)) } - assert.match(source, /WAIT_SPLIT 标记为历史废弃状态/) + assert.doesNotMatch(source, /WAIT_SPLIT 标记为历史废弃状态/) assert.match(source, /没有完成派送并写 DELIVERED 的公开业务 API/) }) diff --git a/scripts/admin-test-env-modules/order-inbound-status-fixtures.mjs b/scripts/admin-test-env-modules/order-inbound-status-fixtures.mjs index f241959cd..96d04d5e0 100644 --- a/scripts/admin-test-env-modules/order-inbound-status-fixtures.mjs +++ b/scripts/admin-test-env-modules/order-inbound-status-fixtures.mjs @@ -262,31 +262,47 @@ export async function run(context, matrix = context.createdResources.manualState id: waitMeasure.orderId, status: 'WAIT_MEASURE', detailPath: `/orders/${waitMeasure.orderId}`, } - for (const status of ['MEASURING', 'MEASURE_PENDING', 'MEASURE_REJECTED', 'INBOUNDED']) { + for (const status of ['MEASURING', 'MEASURE_PENDING', 'MEASURE_REJECTED', 'WAIT_SPLIT']) { const sample = await prepareInboundStatus(context, status) result.inbounds[status] = sample matrix.pages.inbounds.fixtures[status] = { id: sample.inboundId, status, detailPath: `/orders/${sample.orderId}`, } - if (status === 'INBOUNDED') { - result.unifiedOrders.INBOUNDED = sample - matrix.pages.unifiedOrders.fixtures.INBOUNDED = { + if (status === 'WAIT_SPLIT') { + result.unifiedOrders.WAIT_SPLIT = sample + matrix.pages.unifiedOrders.fixtures.WAIT_SPLIT = { id: sample.orderId, status, detailPath: `/orders/${sample.orderId}`, } } } + const legacyResponse = await context.request('GET', + `/api/platform/v1/inbounds?tenantId=${query(fixture.tenantId)}&processStatus=INBOUNDED&page=1&size=20`) + const legacyPage = context.apiSuccess(MODULE, '查询存量 INBOUNDED 兼容样本', legacyResponse, '', OPTIONS) + const legacyInbound = rows(legacyPage)[0] + if (legacyInbound?.id && legacyInbound?.orderId) { + const sample = { inboundId: id(legacyInbound.id), orderId: id(legacyInbound.orderId), tenantId: fixture.tenantId, + status: 'INBOUNDED', inboundCode: legacyInbound.inboundCode || null } + result.inbounds.INBOUNDED = sample + result.unifiedOrders.INBOUNDED = sample + matrix.pages.inbounds.fixtures.INBOUNDED = { + id: sample.inboundId, status: 'INBOUNDED', detailPath: `/orders/${sample.orderId}`, + } + matrix.pages.unifiedOrders.fixtures.INBOUNDED = { + id: sample.orderId, status: 'INBOUNDED', detailPath: `/orders/${sample.orderId}`, + } + } + const blockers = { - WAIT_PRICING: '当前审核通过 API 直接写 INBOUNDED;仅异常放行开关路径可写 WAIT_PRICING', + WAIT_PRICING: '审核通过先进入 WAIT_PRICING,但自动计费与入库编排会继续推进,不能稳定停留', FEE_CONFIRMING: '需要先取得可匹配的真实计价快照并停在费用确认前', - INBOUNDING: 'AutomaticInboundCompletionService 在同一调用内立即从 INBOUNDING 推进 INBOUNDED,无可暂停 API', + INBOUNDING: 'AutomaticInboundCompletionService 在同一调用内立即从 INBOUNDING 推进 WAIT_SPLIT,无可暂停 API', VOIDED: 'InboundProcessStatus 声明了 VOIDED,但当前 Controller/Service 没有作废入库单 API', } for (const status of INBOUND_FILTER_STATUSES) if (!matrix.pages.inbounds.fixtures[status]) { context.assert(MODULE, `入库列表保留 ${status}`, null, false, blockers[status], OPTIONS) } const unifiedBlockers = { - WAIT_SPLIT: '服务端已将 WAIT_SPLIT 标记为历史废弃状态,查询时统一归一为 INBOUNDED,不能再写入或返回', LOADING: '需要分柜、排柜及 PDA 专项独立样本', LOADED: '需要完成装柜证据和 PDA 门禁的专项独立样本', DELIVERED: '当前后端没有完成派送并写 DELIVERED 的公开业务 API', diff --git a/scripts/admin-test-env-modules/phase3-container-loading.mjs b/scripts/admin-test-env-modules/phase3-container-loading.mjs index 43de6aa7e..10e556059 100644 --- a/scripts/admin-test-env-modules/phase3-container-loading.mjs +++ b/scripts/admin-test-env-modules/phase3-container-loading.mjs @@ -45,7 +45,7 @@ export async function run(context) { const tenantId = id(source?.tenantId) const inboundId = id(source?.inboundId) if (!tenantId || !inboundId || source?.marker !== context.marker) { - context.addStep(MODULE, '取得独立柜次级 INBOUNDED fixture', null, false, + context.addStep(MODULE, '取得独立柜次级 WAIT_SPLIT fixture', null, false, `fixture marker=${source?.marker || 'missing'}, current marker=${context.marker}`, OPTIONS) return } @@ -56,7 +56,8 @@ export async function run(context) { `tenantId=${tenantId}, inboundId=${inboundId}`, OPTIONS) const warehouseId = id(inbound?.summary?.warehouseId) context.assert(MODULE, '柜次候选入库单状态、测量和仓库门禁有效', inboundResponse, - inbound?.summary?.processStatus === 'INBOUNDED' && inbound?.summary?.measureReviewStatus === 'APPROVED' + ['WAIT_SPLIT', 'INBOUNDED'].includes(inbound?.summary?.processStatus) + && inbound?.summary?.measureReviewStatus === 'APPROVED' && Boolean(warehouseId), `status=${inbound?.summary?.processStatus || 'missing'}, review=${inbound?.summary?.measureReviewStatus || 'missing'}, warehouseId=${warehouseId || 'missing'}`, OPTIONS) if (!warehouseId) return