|
|
|
@@ -48,6 +48,73 @@ async function merchant(context, token, method, name, path, body = undefined) {
|
|
|
|
|
return { response, data }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function transferDeliveries(data) {
|
|
|
|
|
return Array.isArray(data?.deliveries) ? data.deliveries.filter((value) => nonBlank(value?.deliveryNo)) : []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function deliveryNumbers(data) {
|
|
|
|
|
return transferDeliveries(data).map((value) => id(value.deliveryNo)).sort()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function poll(action, predicate, attempts = 45, intervalMs = 1_000) {
|
|
|
|
|
let result = null
|
|
|
|
|
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
|
|
|
result = await action()
|
|
|
|
|
if (predicate(result)) return { result, attempts: attempt }
|
|
|
|
|
if (attempt < attempts) await new Promise((resolve) => setTimeout(resolve, intervalMs))
|
|
|
|
|
}
|
|
|
|
|
return { result, attempts }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function saveReceiptAndComplete(context, delivery, customerId, index) {
|
|
|
|
|
const deliveryNo = id(delivery.deliveryNo)
|
|
|
|
|
const documentsPath = query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}/documents`, { customerId })
|
|
|
|
|
const before = await platform(context, 'GET', `读取第${index + 1}张派送单资料版本`, documentsPath)
|
|
|
|
|
const version = Number(before.data?.version)
|
|
|
|
|
context.assert(MODULE, `第${index + 1}张派送单资料提供乐观锁版本`, before.response,
|
|
|
|
|
Number.isInteger(version) && version >= 0, `version=${before.data?.version ?? 'missing'}; ${trace(before.response)}`, OPTIONS)
|
|
|
|
|
if (!success(before.response) || !Number.isInteger(version) || version < 0) return null
|
|
|
|
|
|
|
|
|
|
const uploadResponse = await context.requestOverseasMultipart('POST',
|
|
|
|
|
query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}/documents/RECEIPT/files`, { customerId }), {
|
|
|
|
|
name: `${context.marker}-${deliveryNo}-receipt.txt`, type: 'text/plain',
|
|
|
|
|
content: new TextEncoder().encode(`${context.marker} receipt acceptance for ${deliveryNo}`),
|
|
|
|
|
})
|
|
|
|
|
const uploaded = context.apiSuccess(MODULE, `上传第${index + 1}张派送单签收文件`, uploadResponse,
|
|
|
|
|
trace(uploadResponse), OPTIONS)
|
|
|
|
|
const fileId = id(uploaded?.fileId)
|
|
|
|
|
context.assert(MODULE, `第${index + 1}张派送单签收文件返回业务绑定ID`, uploadResponse,
|
|
|
|
|
/^\d+$/.test(fileId), `fileIdPresent=${/^\d+$/.test(fileId)}; ${trace(uploadResponse)}`, OPTIONS)
|
|
|
|
|
if (!success(uploadResponse) || !fileId) return null
|
|
|
|
|
|
|
|
|
|
const existing = (before.data?.categories || []).map((category) => ({
|
|
|
|
|
category: category.category,
|
|
|
|
|
fileIds: (category.files || []).map((file) => id(file.fileId)).filter((value) => /^\d+$/.test(value)),
|
|
|
|
|
})).filter((binding) => binding.category && binding.category !== 'RECEIPT' && binding.fileIds.length > 0)
|
|
|
|
|
const saveBody = {
|
|
|
|
|
expectedVersion: version, idempotencyKey: key(context, 'SAVE-RECEIPT', String(index)),
|
|
|
|
|
bolNo: before.data?.bolNo || null,
|
|
|
|
|
documents: [...existing, { category: 'RECEIPT', fileIds: [fileId] }],
|
|
|
|
|
}
|
|
|
|
|
const saved = await platform(context, 'PUT', `保存第${index + 1}张派送单签收资料并自动完成`, documentsPath, saveBody)
|
|
|
|
|
context.assert(MODULE, `第${index + 1}张派送单签收资料保存后已上传`, saved.response,
|
|
|
|
|
saved.data?.categories?.some((category) => category?.category === 'RECEIPT'
|
|
|
|
|
&& category?.status === 'UPLOADED' && Number(category?.fileCount) === 1), trace(saved.response), OPTIONS)
|
|
|
|
|
if (!success(saved.response)) return null
|
|
|
|
|
|
|
|
|
|
const savedReplay = await platform(context, 'PUT', `第${index + 1}张派送单签收资料同键重放`, documentsPath, saveBody)
|
|
|
|
|
context.assert(MODULE, `第${index + 1}张派送单资料重放版本稳定`, savedReplay.response,
|
|
|
|
|
savedReplay.data?.replayed === true && Number(savedReplay.data?.version) === Number(saved.data?.version),
|
|
|
|
|
trace(savedReplay.response), OPTIONS)
|
|
|
|
|
const completed = await platform(context, 'GET', `回查第${index + 1}张派送单自动完成`,
|
|
|
|
|
query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}`, { customerId }))
|
|
|
|
|
context.assert(MODULE, `第${index + 1}张派送单签收保存即进入DELIVERED`, completed.response,
|
|
|
|
|
completed.data?.order?.status === 'DELIVERED'
|
|
|
|
|
&& completed.data?.operations?.some((operation) => operation?.operationNode === 'RECEIPT_AUTO_COMPLETE'),
|
|
|
|
|
trace(completed.response), OPTIONS)
|
|
|
|
|
return success(completed.response) && completed.data?.order?.status === 'DELIVERED' ? completed.data : null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function relabelOutboundMarksMatch(detail, relabel) {
|
|
|
|
|
const marks = (detail?.pallets || []).flatMap(item => String(item.cartonMarks || '')
|
|
|
|
|
.split(',').map(mark => mark.trim()).filter(Boolean))
|
|
|
|
@@ -74,7 +141,7 @@ async function verifyRelabelDispatchOutbound(context, relabel, transferBody) {
|
|
|
|
|
success(detail.response) && detail.data?.outbound?.outboundNo === outboundNo
|
|
|
|
|
&& detail.data?.outbound?.dispatchNo === relabel.dispatchNo
|
|
|
|
|
&& relabelOutboundMarksMatch(detail.data, relabel), trace(detail.response), OPTIONS)
|
|
|
|
|
Object.assign(relabel, { outboundNo, deliveryNo: transferred.data?.deliveryNo })
|
|
|
|
|
Object.assign(relabel, { outboundNo, deliveryNos: deliveryNumbers(transferred.data) })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function loginMerchant(context, customerId) {
|
|
|
|
@@ -170,7 +237,7 @@ async function pickAll(context, token, dispatchNo) {
|
|
|
|
|
|
|
|
|
|
export async function run(context) {
|
|
|
|
|
context.createdResources.phase5OverseasFulfillment = {
|
|
|
|
|
marker: context.marker, dispatchNo: null, outboundNo: null, deliveryNo: null,
|
|
|
|
|
marker: context.marker, dispatchNo: null, outboundNo: null, deliveryNo: null, deliveryNos: [],
|
|
|
|
|
visitId: null, manualExceptionNo: null, returnExceptionNo: null, finalStatus: null,
|
|
|
|
|
cleanup: 'marker-owned completed delivery, customer visit and return exception are retained as acceptance evidence',
|
|
|
|
|
}
|
|
|
|
@@ -220,18 +287,25 @@ export async function run(context) {
|
|
|
|
|
const transferred = await merchant(context, merchantToken, 'POST', '客户创建派送并原子转出库单',
|
|
|
|
|
query(MERCHANT_DELIVERY_BASE, { dispatchNo }), transferBody)
|
|
|
|
|
const outboundNo = id(transferred.data?.outboundNo)
|
|
|
|
|
const deliveryNo = id(transferred.data?.deliveryNo)
|
|
|
|
|
context.assert(MODULE, '转派送同时生成WAIT_OUTBOUND与WAIT_DELIVERY单据', transferred.response,
|
|
|
|
|
nonBlank(outboundNo) && nonBlank(deliveryNo) && transferred.data?.outboundStatus === 'WAIT_OUTBOUND'
|
|
|
|
|
&& transferred.data?.deliveryStatus === 'WAIT_DELIVERY' && Number(transferred.data?.packageCount) > 0,
|
|
|
|
|
`outboundNo=${outboundNo || 'missing'}, deliveryNo=${deliveryNo || 'missing'}; ${trace(transferred.response)}`, OPTIONS)
|
|
|
|
|
if (!success(transferred.response) || !outboundNo || !deliveryNo) return
|
|
|
|
|
Object.assign(context.createdResources.phase5OverseasFulfillment, { outboundNo, deliveryNo })
|
|
|
|
|
const deliveries = transferDeliveries(transferred.data)
|
|
|
|
|
const deliveryNos = deliveryNumbers(transferred.data)
|
|
|
|
|
const destinationKeys = deliveries.map((value) => id(value.destinationWarehouseCode || value.destinationWarehouseId))
|
|
|
|
|
const deliveryNo = deliveryNos[0] || ''
|
|
|
|
|
context.assert(MODULE, '转派送按目的FBA仓生成WAIT_DELIVERY单据数组', transferred.response,
|
|
|
|
|
nonBlank(outboundNo) && deliveries.length > 0 && new Set(deliveryNos).size === deliveries.length
|
|
|
|
|
&& new Set(destinationKeys).size === deliveries.length && destinationKeys.every(nonBlank)
|
|
|
|
|
&& transferred.data?.outboundStatus === 'WAIT_OUTBOUND'
|
|
|
|
|
&& deliveries.every((value) => value?.deliveryStatus === 'WAIT_DELIVERY')
|
|
|
|
|
&& deliveries.reduce((sum, value) => sum + Number(value?.packageCount || 0), 0) === Number(transferred.data?.packageCount)
|
|
|
|
|
&& Number(transferred.data?.packageCount) > 0,
|
|
|
|
|
`outboundNo=${outboundNo || 'missing'}, deliveries=${deliveryNos.join(',') || 'missing'}, destinations=${destinationKeys.join(',') || 'missing'}; ${trace(transferred.response)}`, OPTIONS)
|
|
|
|
|
if (!success(transferred.response) || !outboundNo || deliveries.length === 0) return
|
|
|
|
|
Object.assign(context.createdResources.phase5OverseasFulfillment, { outboundNo, deliveryNo, deliveryNos })
|
|
|
|
|
const adminReplay = await platform(context, 'POST', '后台转派送复用客户已创建的同一出库派送单',
|
|
|
|
|
`${DISPATCH_BASE}/${encodeURIComponent(dispatchNo)}/transfer-delivery`, transferBody)
|
|
|
|
|
context.assert(MODULE, '后台与客户转派送共享同一业务事实', adminReplay.response,
|
|
|
|
|
adminReplay.data?.replayed === true && id(adminReplay.data?.outboundNo) === outboundNo
|
|
|
|
|
&& id(adminReplay.data?.deliveryNo) === deliveryNo, trace(adminReplay.response), OPTIONS)
|
|
|
|
|
&& JSON.stringify(deliveryNumbers(adminReplay.data)) === JSON.stringify(deliveryNos), trace(adminReplay.response), OPTIONS)
|
|
|
|
|
const lockedItem = updated.data?.items?.[0]
|
|
|
|
|
if (lockedItem?.id) {
|
|
|
|
|
const deniedRemove = await context.requestOverseas('DELETE',
|
|
|
|
@@ -246,24 +320,28 @@ export async function run(context) {
|
|
|
|
|
query(MERCHANT_DELIVERY_BASE, { dispatchNo }), transferBody)
|
|
|
|
|
context.assert(MODULE, '转派送重放复用同一业务单据', transferReplay.response,
|
|
|
|
|
transferReplay.data?.replayed === true && id(transferReplay.data?.outboundNo) === outboundNo
|
|
|
|
|
&& id(transferReplay.data?.deliveryNo) === deliveryNo, trace(transferReplay.response), OPTIONS)
|
|
|
|
|
&& JSON.stringify(deliveryNumbers(transferReplay.data)) === JSON.stringify(deliveryNos), trace(transferReplay.response), OPTIONS)
|
|
|
|
|
const transferConflict = await context.requestOverseas('POST', query(MERCHANT_DELIVERY_BASE, { dispatchNo }),
|
|
|
|
|
{ ...transferBody, idempotencyKey: key(context, 'TRANSFER-DIFFERENT') }, {}, merchantToken)
|
|
|
|
|
context.addStep(MODULE, '同一排车使用另一幂等键仍返回既有单据', transferConflict,
|
|
|
|
|
success(transferConflict) && id(transferConflict.body?.data?.outboundNo) === outboundNo
|
|
|
|
|
&& transferConflict.body?.data?.replayed === true, trace(transferConflict), OPTIONS)
|
|
|
|
|
&& transferConflict.body?.data?.replayed === true
|
|
|
|
|
&& JSON.stringify(deliveryNumbers(transferConflict.body?.data)) === JSON.stringify(deliveryNos), trace(transferConflict), OPTIONS)
|
|
|
|
|
|
|
|
|
|
const merchantPage = await merchant(context, merchantToken, 'GET', '客户分页回查自身派送单',
|
|
|
|
|
query(MERCHANT_DELIVERY_BASE, { page: 1, size: 20, dispatchNo }))
|
|
|
|
|
const merchantRows = Array.isArray(merchantPage.data?.records) ? merchantPage.data.records : []
|
|
|
|
|
context.assert(MODULE, '客户派送列表包含本轮单据且不依赖customerId参数', merchantPage.response,
|
|
|
|
|
merchantRows.some((value) => id(value?.deliveryNo) === deliveryNo && id(value?.dispatchNo) === dispatchNo),
|
|
|
|
|
context.assert(MODULE, '客户派送列表包含本轮全部FBA派送单且不依赖customerId参数', merchantPage.response,
|
|
|
|
|
deliveryNos.every((number) => merchantRows.some((value) => id(value?.deliveryNo) === number
|
|
|
|
|
&& id(value?.dispatchNo) === dispatchNo)),
|
|
|
|
|
`records=${merchantRows.length}; ${trace(merchantPage.response)}`, OPTIONS)
|
|
|
|
|
const merchantDetail = await merchant(context, merchantToken, 'GET', '客户读取自身派送详情',
|
|
|
|
|
`${MERCHANT_DELIVERY_BASE}/${encodeURIComponent(deliveryNo)}`)
|
|
|
|
|
context.assert(MODULE, '客户派送详情返回订单、货物、费用与操作四段正式契约', merchantDetail.response,
|
|
|
|
|
id(merchantDetail.data?.order?.deliveryNo) === deliveryNo
|
|
|
|
|
&& id(merchantDetail.data?.order?.dispatchNo) === dispatchNo
|
|
|
|
|
&& nonBlank(id(merchantDetail.data?.order?.destinationWarehouseCode
|
|
|
|
|
|| merchantDetail.data?.order?.destinationWarehouseId))
|
|
|
|
|
&& Array.isArray(merchantDetail.data?.skus) && merchantDetail.data.skus.length > 0
|
|
|
|
|
&& Array.isArray(merchantDetail.data?.fees) && Array.isArray(merchantDetail.data?.operations),
|
|
|
|
|
`skus=${merchantDetail.data?.skus?.length ?? 'missing'}, fees=${merchantDetail.data?.fees?.length ?? 'missing'}, operations=${merchantDetail.data?.operations?.length ?? 'missing'}; ${trace(merchantDetail.response)}`,
|
|
|
|
@@ -301,42 +379,52 @@ export async function run(context) {
|
|
|
|
|
outbound.data?.outbound?.outboundNo === outboundNo && outbound.data?.outbound?.status === 'OUTBOUNDED',
|
|
|
|
|
trace(outbound.response), OPTIONS)
|
|
|
|
|
|
|
|
|
|
const deliveryBeforeStatus = await platform(context, 'GET', '读取派送状态更新即时版本',
|
|
|
|
|
query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}`, { customerId }))
|
|
|
|
|
const deliveryVersion = Number(deliveryBeforeStatus.data?.order?.version)
|
|
|
|
|
context.assert(MODULE, '派送详情提供状态乐观锁版本', deliveryBeforeStatus.response,
|
|
|
|
|
Number.isInteger(deliveryVersion) && deliveryVersion >= 0,
|
|
|
|
|
`version=${deliveryBeforeStatus.data?.order?.version ?? 'missing'}; ${trace(deliveryBeforeStatus.response)}`, OPTIONS)
|
|
|
|
|
if (!Number.isInteger(deliveryVersion) || deliveryVersion < 0) return
|
|
|
|
|
const delivering = await platform(context, 'PUT', '派送单推进配送中',
|
|
|
|
|
query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}/status`, { customerId }),
|
|
|
|
|
{ status: 'DELIVERING', expectedVersion: deliveryVersion, remark: `${context.marker}-delivering` })
|
|
|
|
|
context.assert(MODULE, '派送状态进入DELIVERING', delivering.response,
|
|
|
|
|
delivering.data?.deliveryStatus === 'DELIVERING', trace(delivering.response), OPTIONS)
|
|
|
|
|
if (!success(delivering.response)) return
|
|
|
|
|
const deliveryBeforeComplete = await platform(context, 'GET', '读取派送完成即时版本',
|
|
|
|
|
query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}`, { customerId }))
|
|
|
|
|
const completeVersion = Number(deliveryBeforeComplete.data?.order?.version)
|
|
|
|
|
context.assert(MODULE, '配送中详情版本已递增', deliveryBeforeComplete.response,
|
|
|
|
|
Number.isInteger(completeVersion) && completeVersion > deliveryVersion,
|
|
|
|
|
`before=${deliveryVersion}, after=${deliveryBeforeComplete.data?.order?.version ?? 'missing'}; ${trace(deliveryBeforeComplete.response)}`,
|
|
|
|
|
OPTIONS)
|
|
|
|
|
if (!Number.isInteger(completeVersion) || completeVersion <= deliveryVersion) return
|
|
|
|
|
const completed = await platform(context, 'POST', '确认派送完成并生成客户回访',
|
|
|
|
|
for (const [index, delivery] of deliveries.entries()) {
|
|
|
|
|
const currentNo = id(delivery.deliveryNo)
|
|
|
|
|
const beforeStatus = await platform(context, 'GET', `读取第${index + 1}张派送单状态版本`,
|
|
|
|
|
query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(currentNo)}`, { customerId }))
|
|
|
|
|
const deliveryVersion = Number(beforeStatus.data?.order?.version)
|
|
|
|
|
context.assert(MODULE, `第${index + 1}张派送单提供状态乐观锁版本`, beforeStatus.response,
|
|
|
|
|
Number.isInteger(deliveryVersion) && deliveryVersion >= 0,
|
|
|
|
|
`version=${beforeStatus.data?.order?.version ?? 'missing'}; ${trace(beforeStatus.response)}`, OPTIONS)
|
|
|
|
|
if (!Number.isInteger(deliveryVersion) || deliveryVersion < 0) return
|
|
|
|
|
const delivering = await platform(context, 'PUT', `第${index + 1}张派送单推进配送中`,
|
|
|
|
|
query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(currentNo)}/status`, { customerId }),
|
|
|
|
|
{ status: 'DELIVERING', expectedVersion: deliveryVersion, remark: `${context.marker}-delivering-${index + 1}` })
|
|
|
|
|
context.assert(MODULE, `第${index + 1}张派送状态进入DELIVERING`, delivering.response,
|
|
|
|
|
delivering.data?.deliveryStatus === 'DELIVERING', trace(delivering.response), OPTIONS)
|
|
|
|
|
if (!success(delivering.response)) return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const completedDeliveries = []
|
|
|
|
|
for (const [index, delivery] of deliveries.entries()) {
|
|
|
|
|
const completed = await saveReceiptAndComplete(context, delivery, customerId, index)
|
|
|
|
|
if (!completed) return
|
|
|
|
|
completedDeliveries.push(completed)
|
|
|
|
|
}
|
|
|
|
|
context.assert(MODULE, '每个目的FBA仓派送单均由各自签收文件自动完成', null,
|
|
|
|
|
completedDeliveries.length === deliveries.length
|
|
|
|
|
&& completedDeliveries.every((value) => value?.order?.status === 'DELIVERED'),
|
|
|
|
|
`deliveries=${deliveryNos.join(',')}, completed=${completedDeliveries.length}`, OPTIONS)
|
|
|
|
|
|
|
|
|
|
const removedComplete = await context.requestOverseas('POST',
|
|
|
|
|
query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}/complete`, { customerId }),
|
|
|
|
|
{ status: 'DELIVERED', expectedVersion: completeVersion, remark: `${context.marker}-delivered` })
|
|
|
|
|
const visitId = id(completed.data?.visitId)
|
|
|
|
|
context.assert(MODULE, '派送完成生成PENDING回访记录', completed.response,
|
|
|
|
|
completed.data?.deliveryStatus === 'DELIVERED' && completed.data?.visitStatus === 'PENDING'
|
|
|
|
|
&& /^\d+$/.test(visitId), `visitIdPresent=${/^\d+$/.test(visitId)}; ${trace(completed.response)}`, OPTIONS)
|
|
|
|
|
if (!success(completed.response) || !visitId) return
|
|
|
|
|
{ status: 'DELIVERED', expectedVersion: 0, remark: `${context.marker}-removed-complete-probe` })
|
|
|
|
|
context.addStep(MODULE, '人工确认派送完成接口已移除', removedComplete,
|
|
|
|
|
removedComplete?.http === 404 || removedComplete?.http === 405
|
|
|
|
|
|| (removedComplete?.http === 200 && ['A0404', 'A0405'].includes(code(removedComplete))),
|
|
|
|
|
trace(removedComplete), OPTIONS)
|
|
|
|
|
|
|
|
|
|
const visits = await platform(context, 'GET', '按派送单回查签收自动生成的客户回访',
|
|
|
|
|
query(`${LASTLEG_BASE}/customer-visits`, { page: 1, size: 200, customerId, keyword: deliveryNo }))
|
|
|
|
|
const visitRow = Array.isArray(visits.data?.records)
|
|
|
|
|
? visits.data.records.find((value) => id(value?.deliveryNo) === deliveryNo) : null
|
|
|
|
|
const visitId = id(visitRow?.id)
|
|
|
|
|
context.assert(MODULE, '签收自动完成生成PENDING回访记录', visits.response,
|
|
|
|
|
/^\d+$/.test(visitId) && visitRow?.status === 'PENDING',
|
|
|
|
|
`visitIdPresent=${/^\d+$/.test(visitId)}; ${trace(visits.response)}`, OPTIONS)
|
|
|
|
|
if (!visitId) return
|
|
|
|
|
context.createdResources.phase5OverseasFulfillment.visitId = visitId
|
|
|
|
|
const completeReplay = await platform(context, 'POST', '确认派送完成重复调用',
|
|
|
|
|
query(`${LASTLEG_BASE}/delivery-orders/${encodeURIComponent(deliveryNo)}/complete`, { customerId }),
|
|
|
|
|
{ status: 'DELIVERED', expectedVersion: completeVersion, remark: `${context.marker}-delivered` })
|
|
|
|
|
context.assert(MODULE, '派送完成重放复用同一回访', completeReplay.response,
|
|
|
|
|
completeReplay.data?.replayed === true && id(completeReplay.data?.visitId) === visitId,
|
|
|
|
|
trace(completeReplay.response), OPTIONS)
|
|
|
|
|
|
|
|
|
|
const visitDetail = await platform(context, 'GET', '读取本轮客户回访详情',
|
|
|
|
|
query(`${LASTLEG_BASE}/customer-visits/${encodeURIComponent(visitId)}`, { customerId }))
|
|
|
|
@@ -345,6 +433,29 @@ export async function run(context) {
|
|
|
|
|
context.assert(MODULE, '回访详情包含派送关联的真实入仓单与尾程单', visitDetail.response,
|
|
|
|
|
Boolean(inbound), `inboundOption=${Boolean(inbound)}; ${trace(visitDetail.response)}`, OPTIONS)
|
|
|
|
|
if (!inbound) return
|
|
|
|
|
|
|
|
|
|
const domesticInbound = await poll(async () => context.request('GET', query('/api/platform/inbounds', {
|
|
|
|
|
tenantId: customerId, inboundCode: inbound.inboundCode, page: 1, size: 20,
|
|
|
|
|
})), (response) => success(response) && Array.isArray(response.body?.data?.records)
|
|
|
|
|
&& response.body.data.records.some((value) => value?.inboundCode === inbound.inboundCode
|
|
|
|
|
&& value?.processStatus === 'DELIVERED'))
|
|
|
|
|
const inboundSummary = domesticInbound.result?.body?.data?.records?.find(
|
|
|
|
|
(value) => value?.inboundCode === inbound.inboundCode)
|
|
|
|
|
context.addStep(MODULE, '海外签收完成事件回推头程入仓单DELIVERED', domesticInbound.result,
|
|
|
|
|
success(domesticInbound.result) && inboundSummary?.processStatus === 'DELIVERED',
|
|
|
|
|
`inboundCode=${inbound.inboundCode}, pollRequests=${domesticInbound.attempts}, processStatus=${inboundSummary?.processStatus || 'missing'}; ${trace(domesticInbound.result)}`, OPTIONS)
|
|
|
|
|
const sourceOrderId = id(inboundSummary?.orderId)
|
|
|
|
|
if (!sourceOrderId) {
|
|
|
|
|
blocker(context, '取得签收对应头程订单', '头程入仓详情缺少来源订单ID', domesticInbound.result)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const domesticOrder = await poll(async () => context.request('GET',
|
|
|
|
|
query(`/api/platform/v1/orders/${encodeURIComponent(sourceOrderId)}`, { tenantId: customerId })),
|
|
|
|
|
(response) => success(response) && response.body?.data?.summary?.mainStatus === 'COMPLETED')
|
|
|
|
|
context.addStep(MODULE, '同订单全部入仓签收后统一订单进入COMPLETED', domesticOrder.result,
|
|
|
|
|
success(domesticOrder.result) && domesticOrder.result?.body?.data?.summary?.mainStatus === 'COMPLETED',
|
|
|
|
|
`orderId=${sourceOrderId}, pollRequests=${domesticOrder.attempts}, mainStatus=${domesticOrder.result?.body?.data?.summary?.mainStatus || 'missing'}; ${trace(domesticOrder.result)}`, OPTIONS)
|
|
|
|
|
|
|
|
|
|
const savedVisit = await platform(context, 'PUT', '保存无附件客户回访结果',
|
|
|
|
|
query(`${LASTLEG_BASE}/customer-visits/${encodeURIComponent(visitId)}`, { customerId }), {
|
|
|
|
|
selectedInboundOrderId: id(inbound.inboundOrderId), visitResult: 'SATISFIED',
|
|
|
|
|