fix: align dropship acceptance with precreated pallets
This commit is contained in:
@@ -90,7 +90,7 @@ async function waitForCompletedMeasurement(context, measurementPath, expectedSta
|
||||
|
||||
export async function completeDropshipPalletization(context, { inboundId, inboundCode, warehouseId, measurement }) {
|
||||
const pendingResponse = await context.request('GET',
|
||||
`/api/platform/v1/first-leg/pda-dropship/tasks/pending?keyword=${encodeURIComponent(inboundCode)}`)
|
||||
`/api/platform/v1/first-leg/pda-dropship/tasks/pending?warehouseId=${warehouseId}&keyword=${encodeURIComponent(inboundCode)}`)
|
||||
const pending = context.apiSuccess(MODULE, '查询一件代发待合托任务', pendingResponse,
|
||||
`inboundId=${inboundId}`, OPTIONS)
|
||||
const task = (pending || []).find((item) => asId(item?.inboundId) === inboundId
|
||||
@@ -110,31 +110,17 @@ export async function completeDropshipPalletization(context, { inboundId, inboun
|
||||
`taskStatus=${claimed?.taskStatus ?? 'missing'}`, OPTIONS)
|
||||
|
||||
const totalCartons = Number(measurement?.actualPackageCount)
|
||||
const createPath = `/api/platform/v1/first-leg/pda-dropship/tasks/${taskId}/pallets/create-and-bind`
|
||||
const expectedPalletCount = Number(measurement?.expectedPalletCount)
|
||||
const taskPath = `/api/platform/v1/first-leg/pda-dropship/tasks/${taskId}?warehouseId=${warehouseId}`
|
||||
const createPayload = { warehouseId, operationId: `${context.marker}-dropship-create-bind`.slice(0, 128) }
|
||||
let palletNo = ''
|
||||
const generatedPallets = Array.isArray(claimed?.pallets) ? claimed.pallets : []
|
||||
context.assert(MODULE, '审核通过时已按预计托数预生成全部DP托盘码', claimResponse,
|
||||
generatedPallets.length === expectedPalletCount && generatedPallets.every((item) =>
|
||||
item?.status === 'OPEN' && Number(item?.cartonCount) === 0 && /^DP-\d{6}-\d{4}$/.test(item?.palletNo || '')),
|
||||
`expected=${expectedPalletCount}, generated=${generatedPallets.length}`, OPTIONS)
|
||||
if (!generatedPallets.length) return null
|
||||
|
||||
let countedCartons = 0
|
||||
const sealedCartonMarks = []
|
||||
let pallet = null
|
||||
|
||||
const palletSnapshot = (value) => JSON.stringify({
|
||||
counted: value?.countedCartons, bound: value?.boundCartons, unbound: value?.unboundCartons,
|
||||
pallets: value?.pallets?.map((item) => ({ id: asId(item.palletId), no: item.palletNo,
|
||||
count: item.cartonCount, status: item.status, version: item.version })),
|
||||
})
|
||||
async function rejectEmptyCreation(before, suffix) {
|
||||
const response = await context.request('POST', createPath,
|
||||
{ ...createPayload, operationId: `${context.marker}-dropship-empty-${suffix}`.slice(0, 128) })
|
||||
context.assert(MODULE, `无待绑箱创建托盘被拒绝-${suffix}`, response,
|
||||
response.http === 200 && String(response.body?.code) === 'A0409',
|
||||
`HTTP=${response.http}, code=${response.body?.code || 'missing'}`, OPTIONS)
|
||||
const afterResponse = await context.request('GET', taskPath)
|
||||
const after = context.apiSuccess(MODULE, `拒绝创建后回查任务-${suffix}`, afterResponse, '', OPTIONS)
|
||||
context.assert(MODULE, `拒绝创建没有空托或计数漂移-${suffix}`, afterResponse,
|
||||
palletSnapshot(after) === palletSnapshot(before), `pallets=${after?.pallets?.length ?? 'missing'}`, OPTIONS)
|
||||
}
|
||||
await rejectEmptyCreation(claimed, 'before-count')
|
||||
|
||||
for (let index = 0; index < totalCartons; index += 1) {
|
||||
const boxCode = `${inboundCode}#${totalCartons}-${index + 1}`
|
||||
@@ -153,7 +139,7 @@ export async function completeDropshipPalletization(context, { inboundId, inboun
|
||||
actualSkuQuantity: Number(resolved.expectedSkuQuantity),
|
||||
discrepancyAction: 'MATCH',
|
||||
discrepancyRemark: null,
|
||||
palletNo: index === 0 ? null : palletNo,
|
||||
palletNo: index === 0 ? null : generatedPallets[Math.min(index, generatedPallets.length - 1)].palletNo,
|
||||
operationId: `${context.marker}-dropship-count-${index + 1}`.slice(0, 128),
|
||||
}
|
||||
const countResponse = await context.request('POST',
|
||||
@@ -184,55 +170,57 @@ export async function completeDropshipPalletization(context, { inboundId, inboun
|
||||
&& Number(replayed?.unboundCartons) === Number(counted?.unboundCartons),
|
||||
`counted=${replayed?.countedCartons ?? 'missing'}, unbound=${replayed?.unboundCartons ?? 'missing'}`, OPTIONS)
|
||||
|
||||
const bindResponse = await context.request('POST', createPath, createPayload)
|
||||
const bound = context.apiSuccess(MODULE, '系统发码创建托盘并绑定全部待组托箱', bindResponse,
|
||||
const firstPallet = generatedPallets[0]
|
||||
const bindPayload = { warehouseId, palletNo: firstPallet.palletNo,
|
||||
operationId: `${context.marker}-dropship-bind-first`.slice(0, 128) }
|
||||
const bindResponse = await context.request('POST',
|
||||
`/api/platform/v1/first-leg/pda-dropship/tasks/${taskId}/pallets/bind-pending`, bindPayload)
|
||||
const bound = context.apiSuccess(MODULE, '后扫预生成托盘码并绑定全部待组托箱', bindResponse,
|
||||
`taskId=${taskId}`, OPTIONS)
|
||||
pallet = bound?.pallets?.find((item) => Number(item.cartonCount) === 1) || null
|
||||
palletNo = pallet?.palletNo || ''
|
||||
const pallet = bound?.pallets?.find((item) => asId(item.palletId) === asId(firstPallet.palletId)) || null
|
||||
context.assert(MODULE, '待组托箱绑定到OPEN托盘且不再游离', bindResponse,
|
||||
Number(bound?.unboundCartons) === 0 && Number(pallet?.cartonCount) === 1
|
||||
&& pallet?.status === 'OPEN' && /^DP-\d{6}-\d{4}$/.test(palletNo)
|
||||
&& bound?.pallets?.length === 1,
|
||||
&& pallet?.status === 'OPEN' && pallet?.palletNo === firstPallet.palletNo
|
||||
&& bound?.pallets?.length === expectedPalletCount,
|
||||
`unbound=${bound?.unboundCartons ?? 'missing'}, palletStatus=${pallet?.status ?? 'missing'}`, OPTIONS)
|
||||
const createReplayResponse = await context.request('POST', createPath, createPayload)
|
||||
const createReplay = context.apiSuccess(MODULE, '系统发码同operationId重放', createReplayResponse, '', OPTIONS)
|
||||
context.assert(MODULE, '系统发码重放不新增托盘且业务码和计数稳定', createReplayResponse,
|
||||
palletSnapshot(createReplay) === palletSnapshot(bound), `palletNo=${palletNo}`, OPTIONS)
|
||||
await rejectEmptyCreation(bound, 'after-bind')
|
||||
} else {
|
||||
pallet = counted?.pallet || pallet
|
||||
const expectedPallet = generatedPallets[Math.min(index, generatedPallets.length - 1)]
|
||||
context.assert(MODULE, `第${index + 1}箱直接进入当前OPEN托盘`, countResponse,
|
||||
counted?.pallet?.palletNo === palletNo && counted?.pallet?.status === 'OPEN',
|
||||
counted?.pallet?.palletNo === expectedPallet.palletNo && counted?.pallet?.status === 'OPEN',
|
||||
`palletNo=${counted?.pallet?.palletNo ?? 'missing'}, status=${counted?.pallet?.status ?? 'missing'}`, OPTIONS)
|
||||
}
|
||||
}
|
||||
context.assert(MODULE, '一件代发工作托盘覆盖测量冻结的全部箱数', null,
|
||||
totalCartons > 0 && countedCartons === totalCartons && Number(pallet?.cartonCount) === totalCartons,
|
||||
`counted=${countedCartons}, palletCartons=${pallet?.cartonCount ?? 'missing'}, expected=${totalCartons || 'missing'}`, OPTIONS)
|
||||
const countedTaskResponse = await context.request('GET', taskPath)
|
||||
let sealed = context.apiSuccess(MODULE, '清点完成后回查预生成托盘分配', countedTaskResponse, '', OPTIONS)
|
||||
context.assert(MODULE, '预生成托盘覆盖测量冻结的全部箱数', countedTaskResponse,
|
||||
totalCartons > 0 && countedCartons === totalCartons
|
||||
&& Number(sealed?.boundCartons) === totalCartons
|
||||
&& sealed?.pallets?.length === expectedPalletCount
|
||||
&& sealed?.pallets?.every((item) => Number(item?.cartonCount) > 0),
|
||||
`counted=${countedCartons}, bound=${sealed?.boundCartons ?? 'missing'}, expected=${totalCartons || 'missing'}`, OPTIONS)
|
||||
|
||||
const palletId = asId(pallet?.palletId)
|
||||
if (!palletId) return null
|
||||
|
||||
const sealResponse = await context.request('POST',
|
||||
`/api/platform/v1/first-leg/pda-dropship/tasks/${taskId}/pallets/${palletId}/seal`, {
|
||||
warehouseId, expectedVersion: Number(pallet?.version),
|
||||
operationId: `${context.marker}-dropship-seal`.slice(0, 128),
|
||||
})
|
||||
const sealed = context.apiSuccess(MODULE, '封托并完成一件代发合托任务', sealResponse,
|
||||
`taskId=${taskId}, palletId=${palletId}`, OPTIONS)
|
||||
context.assert(MODULE, '全部箱数封托后入仓单允许进入WAIT_SPLIT', sealResponse,
|
||||
let lastSealResponse = countedTaskResponse
|
||||
for (let index = 0; index < (sealed?.pallets || []).length; index += 1) {
|
||||
const pallet = sealed.pallets.find((item) => item.status === 'OPEN')
|
||||
if (!pallet) break
|
||||
const sealResponse = await context.request('POST',
|
||||
`/api/platform/v1/first-leg/pda-dropship/tasks/${taskId}/pallets/${asId(pallet.palletId)}/seal`, {
|
||||
warehouseId, expectedVersion: Number(pallet.version),
|
||||
operationId: `${context.marker}-dropship-seal-${index + 1}`.slice(0, 128),
|
||||
})
|
||||
lastSealResponse = sealResponse
|
||||
sealed = context.apiSuccess(MODULE, `封托第${index + 1}个预生成托盘`, sealResponse,
|
||||
`taskId=${taskId}, palletNo=${pallet.palletNo}`, OPTIONS)
|
||||
}
|
||||
context.assert(MODULE, '全部箱数封托后入仓单允许进入WAIT_SPLIT', lastSealResponse,
|
||||
sealed?.taskStatus === 'COMPLETED'
|
||||
&& Number(sealed?.countedCartons) === Number(sealed?.totalCartons)
|
||||
&& Number(sealed?.boundCartons) === Number(sealed?.totalCartons)
|
||||
&& Number(sealed?.unboundCartons) === 0
|
||||
&& sealed?.pallets?.every((item) => item?.status === 'SEALED'),
|
||||
`taskStatus=${sealed?.taskStatus ?? 'missing'}, counted=${sealed?.countedCartons ?? 'missing'}, bound=${sealed?.boundCartons ?? 'missing'}`, OPTIONS)
|
||||
const sealedReplayResponse = await context.request('POST', createPath, createPayload)
|
||||
const sealedReplay = context.apiSuccess(MODULE, '封托完成后系统发码原操作仍可重放', sealedReplayResponse, '', OPTIONS)
|
||||
context.assert(MODULE, '完成后重放不重开任务或新建空托', sealedReplayResponse,
|
||||
sealedReplay?.taskStatus === 'COMPLETED' && palletSnapshot(sealedReplay) === palletSnapshot(sealed),
|
||||
`taskStatus=${sealedReplay?.taskStatus || 'missing'}, palletNo=${palletNo}`, OPTIONS)
|
||||
return { ...sealed, sealedCartonMarks, sealedSourcePalletNos: [palletNo] }
|
||||
return { ...sealed, sealedCartonMarks,
|
||||
sealedSourcePalletNos: (sealed?.pallets || []).map((item) => item.palletNo).filter(Boolean) }
|
||||
}
|
||||
|
||||
async function provisionWarehouseResources(context, { inboundId, tenantId, warehouseId, palletCount }) {
|
||||
@@ -846,9 +834,13 @@ export async function run(context) {
|
||||
? 'ADD' : measuredItem.coefficientMode ?? null,
|
||||
remark: context.marker,
|
||||
}]
|
||||
const palletCount = Math.max(1, Math.min(originalPackageCount,
|
||||
Number(context.context?.waitSplitVariant?.palletCount || 1)))
|
||||
const draftPayload = {
|
||||
measurementId: measured.measurementId, version: Number(measured.version),
|
||||
actualGoodsName: `墨家测量验收-${context.marker.slice(-12)}`,
|
||||
expectedPalletCount: context.createdResources?.orders?.fulfillmentType === 'ONE_CLICK_DROPSHIP'
|
||||
? palletCount : null,
|
||||
items: draftItems,
|
||||
}
|
||||
const draftResponse = await context.request('PUT',
|
||||
@@ -864,7 +856,6 @@ export async function run(context) {
|
||||
return
|
||||
}
|
||||
|
||||
const palletCount = Math.max(1, Number(context.context?.waitSplitVariant?.palletCount || 1))
|
||||
const warehouseResourcesReady = await provisionWarehouseResources(context, {
|
||||
inboundId, tenantId, warehouseId: asId(summary?.warehouseId), palletCount,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user