fix: validate transfer rejection and align dispatch HTTP contracts
This commit is contained in:
@@ -9,6 +9,15 @@ function id(value) { return value == null ? '' : String(value) }
|
||||
function records(value) { return Array.isArray(value?.records) ? value.records : [] }
|
||||
function codeOf(response) { return response?.body?.code == null ? '' : String(response.body.code) }
|
||||
function success(response) { return response?.http === 200 && codeOf(response) === '200' }
|
||||
export function dispatchBusinessSnapshot(value) {
|
||||
return JSON.stringify({ id: id(value?.id), dispatchNo: value?.dispatchNo, status: value?.status,
|
||||
packageCount: value?.packageCount, palletCount: value?.palletCount,
|
||||
items: (value?.items || []).map(item => ({ planPalletId: id(item.planPalletId),
|
||||
warehousePalletId: id(item.warehousePalletId), sourceStage: item.sourceStage,
|
||||
packageCount: item.packageCount, inboundCode: item.inboundCode }))
|
||||
.sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b))),
|
||||
})
|
||||
}
|
||||
function conflict(response) { return response?.http === 409 || (response?.http === 200 && codeOf(response) === 'A0409') }
|
||||
function trace(response) {
|
||||
return `HTTP=${response?.http ?? 'missing'}, code=${codeOf(response) || 'missing'}, requestId=${response?.requestId || 'missing'}, traceId=${response?.traceId || 'missing'}`
|
||||
@@ -76,12 +85,11 @@ async function runRelabelDispatch(context, relabel) {
|
||||
relabelNo: relabel.relabelNo, planPalletId: null,
|
||||
})
|
||||
const detail = await api(context, 'GET', '回查本轮换标排车详情', `${BASE}/${encodeURIComponent(dispatchNo)}`)
|
||||
const detailMarks = (detail.data?.items || []).flatMap((item) => String(item?.cartonMarks || '')
|
||||
.split(',').map((mark) => mark.trim()).filter(Boolean))
|
||||
context.assert(MODULE, '排车详情冻结全部换标后箱唛且不混入原箱唛', detail.response,
|
||||
relabel.relabelCartonMarks.every((mark) => detailMarks.includes(mark))
|
||||
&& relabel.sourceCartonMarks.every((mark) => !detailMarks.includes(mark)),
|
||||
`frozenMarks=${detailMarks.join(',')}; ${trace(detail.response)}`, OPTIONS)
|
||||
// DispatchResponse.Item omits cartonMarks. Phase5 verifies the persisted marks
|
||||
// through OutboundDetail.pallets after transferring this exact dispatch.
|
||||
context.assert(MODULE, '排车详情保留本轮换标托盘与箱数快照', detail.response,
|
||||
success(detail.response) && dispatchBusinessSnapshot(detail.data) === dispatchBusinessSnapshot(arranged.data),
|
||||
trace(detail.response), OPTIONS)
|
||||
}
|
||||
|
||||
export async function run(context) {
|
||||
@@ -233,8 +241,10 @@ export async function run(context) {
|
||||
context.createdResources.phase4OverseasDispatch.finalStatus = arranged.data?.status || null
|
||||
|
||||
const duplicateArrange = await context.requestOverseas('POST', `${BASE}/pre-arrange`, preArrangeBody)
|
||||
context.addStep(MODULE, '已转换正式锁的旧草稿载荷再次预排返回A0409', duplicateArrange,
|
||||
conflict(duplicateArrange), trace(duplicateArrange), OPTIONS)
|
||||
context.addStep(MODULE, '出库前同草稿重复预排复用原排车且业务快照不漂移', duplicateArrange,
|
||||
success(duplicateArrange)
|
||||
&& dispatchBusinessSnapshot(duplicateArrange.body?.data) === dispatchBusinessSnapshot(arranged.data),
|
||||
trace(duplicateArrange), OPTIONS)
|
||||
|
||||
const pageResult = await api(context, 'GET', '按排车单号回查跨客户分页', query(BASE, {
|
||||
page: 1, size: 20, dispatchNo,
|
||||
|
||||
Reference in New Issue
Block a user