This commit is contained in:
2026-09-15 14:18:18 +08:00
parent 6a2075fe4b
commit a474ca4d93
35 changed files with 751 additions and 228 deletions
@@ -5,6 +5,30 @@ const MODULE = 'dropship-pallet-matrix'
const OPTIONS = { scenario: 'dropship-outbound-edge-cases', deploymentBlocker: true }
const BASE = '/api/platform/v1/last-leg/outbound-orders'
// Expected progress comes from submitted fixture operations, never the server response.
export function receivingProgressMatches(snapshot, expected) {
const count = value => (typeof value === 'number' || typeof value === 'string' && /^\d+$/.test(value))
&& Number.isSafeInteger(Number(value)) && Number(value) >= 0 ? Number(value) : NaN
if (!Array.isArray(snapshot?.inbounds) || !Array.isArray(expected) || !expected.length) return false
if (new Set(expected.map(row => row.inboundCode)).size !== expected.length
|| snapshot.inbounds.length !== expected.length
|| new Set(snapshot.inbounds.map(row => row.inboundCode)).size !== expected.length) return false
let total = 0
let received = 0
for (const row of expected) {
if (!Number.isInteger(row.total) || !Number.isInteger(row.received)
|| row.total <= 0 || row.received < 0 || row.received > row.total) return false
const actual = snapshot.inbounds.find(item => item.inboundCode === row.inboundCode)
if (!actual || count(actual.totalPackages) !== row.total
|| count(actual.receivedPackages) !== row.received
|| count(actual.pendingPackages) !== row.total - row.received) return false
total += row.total
received += row.received
}
return count(snapshot.totalPackages) === total && count(snapshot.receivedPackages) === received
&& count(snapshot.pendingPackages) === total - received
}
function record(edge, name, response, passed, evidence = '') {
edge.context.assert(MODULE, `${edge.label}${name}`, response, passed, evidence, OPTIONS)
}
@@ -25,6 +49,41 @@ async function taskSnapshot(edge) {
return edge.call('边界测试回查出库冻结事实', 'GET', `${BASE}/${edge.task.outboundNo}`)
}
export async function outboundCandidateGuards(edge) {
const warehouse = encodeURIComponent(edge.warehouseId)
const customer = encodeURIComponent(edge.customerId)
const paths = [
['平台首次查询不传客户', `${BASE}/one-click-dropship/candidates?warehouseId=${warehouse}`],
['平台指定客户查询', `${BASE}/one-click-dropship/candidates?customerId=${customer}&warehouseId=${warehouse}`],
]
const snapshots = []
for (const [name, path] of paths) {
const rows = await edge.call(name, 'GET', path)
edge.check(`${edge.label}${name}返回候选数组`, null, Array.isArray(rows))
edge.check(`${edge.label}${name}仓库隔离`, null,
rows.every(row => String(row.overseasWarehouseId) === String(edge.warehouseId)))
if (name === '平台指定客户查询') {
edge.check(`${edge.label}指定客户不返回其他客户库存`, null,
rows.every(row => String(row.customerId) === String(edge.customerId)))
}
const own = rows.filter(row => edge.group.some(x => x.source.inboundCode === row.inboundCode))
for (const record of edge.group) {
const selected = own.filter(row => row.inboundCode === record.source.inboundCode)
const expectedPallets = [...new Set(record.task.pallets.map(p => p.palletNo))].sort()
const actualPallets = [...new Set(selected.map(row => row.palletNo))].sort()
edge.check(`${record.label}${name}全部托盘与箱数完整`, null,
JSON.stringify(expectedPallets) === JSON.stringify(actualPallets)
&& selected.reduce((sum, row) => sum + Number(row.availablePackages), 0) === record.expectedCartonMarks.length
&& selected.every(row => String(row.customerId) === String(edge.customerId)))
}
snapshots.push(own.map(row => ({ inbound: row.inboundCode, pallet: row.palletNo,
position: String(row.inventoryPositionId), sku: row.skuCode, packages: Number(row.availablePackages) }))
.sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b))))
}
edge.check(`${edge.label}客户筛选前后本轮库存事实一致`, null,
JSON.stringify(snapshots[0]) === JSON.stringify(snapshots[1]))
}
export async function outboundCreationGuards(edge) {
const before = await candidates(edge)
const first = edge.body.items[0]