fix: align HTTP acceptance fixtures and pallet permissions

This commit is contained in:
2026-09-14 12:40:40 +08:00
parent e55ab73e61
commit a2ea0ba9e6
15 changed files with 205 additions and 50 deletions
@@ -6,6 +6,13 @@ export const DOCUMENT_TYPES = Object.freeze([
'DESTINATION_CLEARANCE', 'DELIVERY_ORDER',
])
export function applicableDocumentTypes(channelCode) {
if (!String(channelCode || '').trim()) throw new Error('货柜缺少权威渠道,不能判断DO适用性')
const seaRail = ['EXX_RAIL_NY', 'NYEXX', 'OA_CHICAGO_RAIL', 'CPHT']
.includes(String(channelCode).trim().toUpperCase())
return seaRail ? ['DESTINATION_CLEARANCE'] : [...DOCUMENT_TYPES]
}
function id(value) { return value == null ? '' : String(value) }
function codeOf(response) { return response?.body?.code == null ? 'missing' : String(response.body.code) }
function success(response) { return response?.http === 200 && codeOf(response) === '200' }
@@ -115,6 +122,13 @@ export async function run(context) {
return
}
const detailResponse = await context.request('GET', `${CONTAINERS}/domestic/${containerId}`)
const detail = context.apiSuccess(MODULE, '读取本轮货柜权威渠道', detailResponse, '', OPTIONS)
if (id(detail?.container?.id) !== containerId || !detail?.container?.channelCode) {
context.addStep(MODULE, '货柜渠道适用性前置', detailResponse, false, '缺少同柜权威渠道', OPTIONS)
return
}
const expectedTypes = applicableDocumentTypes(detail.container.channelCode)
const specs = [
{
type: 'DESTINATION_CLEARANCE',
@@ -122,7 +136,7 @@ export async function run(context) {
readPath: `${CONTAINERS}/${containerId}/clearance`,
completePath: `${CONTAINERS}/${containerId}/clearance/complete`,
},
...['DELIVERY_ORDER'].map((type) => ({
...expectedTypes.filter((type) => type === 'DELIVERY_ORDER').map((type) => ({
type,
uploadPath: `${CONTAINERS}/${containerId}/documents/${type}/upload`,
readPath: `${CONTAINERS}/${containerId}/documents/${type}`,
@@ -131,17 +145,28 @@ export async function run(context) {
const documents = []
for (const spec of specs) documents.push(await uploadAndVerify(context, spec))
let applicabilityPassed = true
if (!expectedTypes.includes('DELIVERY_ORDER')) {
const rejected = await upload(context, `${CONTAINERS}/${containerId}/documents/DELIVERY_ORDER/upload`,
'DELIVERY_ORDER', 0, `${context.marker} 海铁DO负向验收`, key(context, 'rail-do-rejected'))
applicabilityPassed = conflict(rejected) && traced(rejected)
&& rejected.body?.message === '海铁渠道不适用DO资料'
context.addStep(MODULE, '海铁DO上传按渠道规则拒绝', rejected, applicabilityPassed,
`code=${codeOf(rejected)}, requestId=${rejected.requestId}, traceId=${rejected.traceId}`, OPTIONS)
}
const overviewResponse = await context.request('GET', `${CONTAINERS}/${containerId}/overview`)
const overview = context.apiSuccess(MODULE, '回查货柜作业资料聚合', overviewResponse, '', OPTIONS)
const storedTypes = new Set((overview?.documents || []).map((item) => item?.documentType))
const typesValid = expectedTypes.every((type) => storedTypes.has(type))
&& (expectedTypes.includes('DELIVERY_ORDER') || !storedTypes.has('DELIVERY_ORDER'))
context.assert(MODULE, '同一LOADED柜次聚合返回作业资料且身份未漂移', overviewResponse,
id(overview?.container?.id) === containerId && documents.every(Boolean)
&& DOCUMENT_TYPES.every((type) => storedTypes.has(type)),
&& typesValid && applicabilityPassed,
`containerBookingId=${containerId}, documentTypes=${[...storedTypes].join('|') || 'none'}`, OPTIONS)
if (documents.every(Boolean) && DOCUMENT_TYPES.every((type) => storedTypes.has(type))) {
if (id(overview?.container?.id) === containerId && documents.every(Boolean) && typesValid && applicabilityPassed) {
context.createdResources.phase3ContainerDocuments = {
marker: context.marker, containerBookingId: containerId, loadingPlanId: planId,
warehouseId, finalStatus: 'COMPLETED', documentTypes: [...DOCUMENT_TYPES],
warehouseId, finalStatus: 'COMPLETED', documentTypes: expectedTypes,
documentIds: Object.fromEntries(documents.map((item) => [item.documentType, id(item.id)])),
}
}