fix(lastleg): complete generated pallet receiving flow
This commit is contained in:
@@ -125,76 +125,46 @@ async function uploadVersion(context, path, label, expectedVersion, operation, c
|
||||
return { response, document }
|
||||
}
|
||||
|
||||
async function verifyFourContainerDocuments(context, { containerBookingId, loadingPlanId, warehouseId }) {
|
||||
async function verifyDomesticCustomsEvidence(context, { containerBookingId, loadingPlanId, warehouseId }) {
|
||||
const reason = `${context.marker}-人工验收节点资料`
|
||||
const simpleDocuments = [
|
||||
{ type: 'DESTINATION_CLEARANCE', base: `/api/platform/v1/containers/${containerBookingId}/clearance`,
|
||||
uploadPath: `/api/platform/v1/containers/${containerBookingId}/clearance/document/upload` },
|
||||
{ type: 'CUSTOMS_DECLARATION', base: `/api/platform/v1/first-leg/loading-lists/${loadingPlanId}/customs`,
|
||||
query: `warehouseId=${encodeURIComponent(warehouseId)}`,
|
||||
uploadPath: `/api/platform/v1/first-leg/loading-lists/${loadingPlanId}/customs/document/upload?warehouseId=${encodeURIComponent(warehouseId)}` },
|
||||
]
|
||||
const completed = []
|
||||
for (const document of simpleDocuments) {
|
||||
const first = await uploadVersion(context, document.uploadPath, `首次上传${document.type}`, 0,
|
||||
`${document.type.toLowerCase()}-v1`, `${context.marker} ${document.type} v1`)
|
||||
if (!first.document?.fileId) return false
|
||||
const readPath = `${document.base}${document.query ? `?${document.query}` : ''}`
|
||||
const firstRead = await context.request('GET', readPath)
|
||||
const firstEcho = context.apiSuccess(MODULE, `回显${document.type}首版`, firstRead, '', OPTIONS)
|
||||
context.assert(MODULE, `${document.type}首版回显身份一致`, firstRead,
|
||||
id(firstEcho?.id) === id(first.document.id) && id(firstEcho?.fileId) === id(first.document.fileId),
|
||||
`documentId=${id(firstEcho?.id) || 'missing'}, version=${firstEcho?.version ?? 'missing'}`, OPTIONS)
|
||||
const firstDownloadPath = document.type === 'DESTINATION_CLEARANCE'
|
||||
? `${document.base}/document/${id(first.document.fileId)}/download`
|
||||
: `${document.base}/document/${id(first.document.fileId)}/download?${document.query}`
|
||||
const firstDownload = await download(context, firstDownloadPath, context.token)
|
||||
context.assert(MODULE, `下载${document.type}首版`, firstDownload,
|
||||
firstDownload.http === 200 && firstDownload.bytes.length > 0 && firstDownload.contentType.includes('text/plain'),
|
||||
`HTTP=${firstDownload.http}, bytes=${firstDownload.bytes.length}`, OPTIONS)
|
||||
const second = await uploadVersion(context, document.uploadPath, `更新${document.type}为第二版`,
|
||||
Number(firstEcho?.version), `${document.type.toLowerCase()}-v2`, `${context.marker} ${document.type} v2`)
|
||||
context.assert(MODULE, `${document.type}更新保持同一聚合并递增版本`, second.response,
|
||||
id(second.document?.id) === id(first.document.id) && Number(second.document?.version) === Number(firstEcho?.version) + 1,
|
||||
`documentId=${id(second.document?.id) || 'missing'}, version=${second.document?.version ?? 'missing'}`, OPTIONS)
|
||||
const completeResponse = await request(context, 'POST', `${document.base}/complete${document.query ? `?${document.query}` : ''}`, {
|
||||
expectedVersion: Number(second.document?.version), operationReason: reason,
|
||||
}, context.token, { 'Idempotency-Key': key(context, `${document.type.toLowerCase()}-complete`) })
|
||||
const complete = context.apiSuccess(MODULE, `完成${document.type}`, completeResponse, '', OPTIONS)
|
||||
context.assert(MODULE, `${document.type}完成态、时间和版本可回读`, completeResponse,
|
||||
id(complete?.id) === id(first.document.id) && Boolean(complete?.completedAt)
|
||||
&& Number(complete?.version) === Number(second.document?.version) + 1,
|
||||
`completedAt=${complete?.completedAt || 'missing'}, version=${complete?.version ?? 'missing'}`, OPTIONS)
|
||||
completed.push(complete)
|
||||
}
|
||||
|
||||
for (const type of ['DELIVERY_ORDER', 'PICKUP_ORDER']) {
|
||||
const base = `/api/platform/v1/containers/${containerBookingId}/documents/${type}`
|
||||
const first = await uploadVersion(context, `${base}/upload`, `首次上传${type}`, 0,
|
||||
`${type.toLowerCase()}-v1`, `${context.marker} ${type} v1`)
|
||||
if (!first.document?.fileId) return false
|
||||
const firstDownload = await download(context, `${base}/${id(first.document.fileId)}/download`, context.token)
|
||||
context.assert(MODULE, `下载${type}首版`, firstDownload,
|
||||
firstDownload.http === 200 && firstDownload.bytes.length > 0 && firstDownload.contentType.includes('text/plain'),
|
||||
`HTTP=${firstDownload.http}, bytes=${firstDownload.bytes.length}`, OPTIONS)
|
||||
const second = await uploadVersion(context, `${base}/upload`, `更新${type}为第二版`,
|
||||
Number(first.document.version), `${type.toLowerCase()}-v2`, `${context.marker} ${type} v2`)
|
||||
const echoResponse = await context.request('GET', base)
|
||||
const echo = context.apiSuccess(MODULE, `回显${type}当前版本`, echoResponse, '', OPTIONS)
|
||||
context.assert(MODULE, `${type}首次与更新保持同一聚合且当前版本唯一`, echoResponse,
|
||||
id(echo?.id) === id(first.document.id) && id(echo?.fileId) === id(second.document?.fileId)
|
||||
&& Number(echo?.version) === Number(first.document.version) + 1,
|
||||
`documentId=${id(echo?.id) || 'missing'}, version=${echo?.version ?? 'missing'}`, OPTIONS)
|
||||
}
|
||||
const type = 'CUSTOMS_DECLARATION'
|
||||
const query = `warehouseId=${encodeURIComponent(warehouseId)}`
|
||||
const base = `/api/platform/v1/first-leg/loading-lists/${loadingPlanId}/customs`
|
||||
const uploadPath = `${base}/document/upload?${query}`
|
||||
const first = await uploadVersion(context, uploadPath, `首次上传${type}`, 0,
|
||||
`${type.toLowerCase()}-v1`, `${context.marker} ${type} v1`)
|
||||
if (!first.document?.fileId) return false
|
||||
const firstRead = await context.request('GET', `${base}?${query}`)
|
||||
const firstEcho = context.apiSuccess(MODULE, `回显${type}首版`, firstRead, '', OPTIONS)
|
||||
context.assert(MODULE, `${type}首版回显身份一致`, firstRead,
|
||||
id(firstEcho?.id) === id(first.document.id) && id(firstEcho?.fileId) === id(first.document.fileId),
|
||||
`documentId=${id(firstEcho?.id) || 'missing'}, version=${firstEcho?.version ?? 'missing'}`, OPTIONS)
|
||||
const firstDownload = await download(context,
|
||||
`${base}/document/${id(first.document.fileId)}/download?${query}`, context.token)
|
||||
context.assert(MODULE, `下载${type}首版`, firstDownload,
|
||||
firstDownload.http === 200 && firstDownload.bytes.length > 0 && firstDownload.contentType.includes('text/plain'),
|
||||
`HTTP=${firstDownload.http}, bytes=${firstDownload.bytes.length}`, OPTIONS)
|
||||
const second = await uploadVersion(context, uploadPath, `更新${type}为第二版`,
|
||||
Number(firstEcho?.version), `${type.toLowerCase()}-v2`, `${context.marker} ${type} v2`)
|
||||
context.assert(MODULE, `${type}更新保持同一聚合并递增版本`, second.response,
|
||||
id(second.document?.id) === id(first.document.id) && Number(second.document?.version) === Number(firstEcho?.version) + 1,
|
||||
`documentId=${id(second.document?.id) || 'missing'}, version=${second.document?.version ?? 'missing'}`, OPTIONS)
|
||||
const completeResponse = await request(context, 'POST', `${base}/complete?${query}`, {
|
||||
expectedVersion: Number(second.document?.version), operationReason: reason,
|
||||
}, context.token, { 'Idempotency-Key': key(context, `${type.toLowerCase()}-complete`) })
|
||||
const complete = context.apiSuccess(MODULE, `完成${type}`, completeResponse, '', OPTIONS)
|
||||
context.assert(MODULE, `${type}完成态、时间和版本可回读`, completeResponse,
|
||||
id(complete?.id) === id(first.document.id) && Boolean(complete?.completedAt)
|
||||
&& Number(complete?.version) === Number(second.document?.version) + 1,
|
||||
`completedAt=${complete?.completedAt || 'missing'}, version=${complete?.version ?? 'missing'}`, OPTIONS)
|
||||
|
||||
const overviewResponse = await context.request('GET', `/api/platform/v1/containers/${containerBookingId}/overview`)
|
||||
const overview = context.apiSuccess(MODULE, '四类资料完成后回查整柜聚合', overviewResponse, '', OPTIONS)
|
||||
const overview = context.apiSuccess(MODULE, '国内报关完成后回查整柜聚合', overviewResponse, '', OPTIONS)
|
||||
const documents = Array.isArray(overview?.documents) ? overview.documents : []
|
||||
const photos = Array.isArray(overview?.pda?.photos) ? overview.pda.photos.filter((item) => item?.status === 'ACTIVE') : []
|
||||
context.assert(MODULE, '整柜聚合回显四类当前资料与真实PDA照片证据', overviewResponse,
|
||||
['DESTINATION_CLEARANCE', 'CUSTOMS_DECLARATION', 'DELIVERY_ORDER', 'PICKUP_ORDER']
|
||||
.every((type) => documents.some((item) => item?.documentType === type))
|
||||
&& completed.every((item) => documents.some((value) => id(value?.id) === id(item?.id) && value?.completed === true))
|
||||
context.assert(MODULE, '整柜聚合回显国内报关资料与真实PDA照片证据', overviewResponse,
|
||||
documents.some((item) => item?.documentType === type
|
||||
&& id(item?.id) === id(complete?.id) && item?.completed === true)
|
||||
&& photos.length >= 5 && photos.every((item) => /^\/api\/platform\/v1\/containers\/\d+\/pda\/photos\/\d+\/download$/.test(String(item?.downloadPath || ''))),
|
||||
`documents=${documents.map((item) => item?.documentType).join('|') || 'none'}, activePhotos=${photos.length}`, OPTIONS)
|
||||
for (const [index, photo] of photos.entries()) {
|
||||
@@ -505,8 +475,8 @@ export async function run(context) {
|
||||
context.addStep(MODULE, '回执 fileId 不能伪造为客户报关资料引用', forgedReference, failure(forgedReference),
|
||||
`HTTP=${forgedReference.http}, code=${codeOf(forgedReference)}`, OPTIONS)
|
||||
|
||||
if (!(await verifyFourContainerDocuments(context, { containerBookingId, loadingPlanId, warehouseId }))) {
|
||||
context.addStep(MODULE, '四类整柜资料必须完成后才允许进入出仓确认', null, false,
|
||||
if (!(await verifyDomesticCustomsEvidence(context, { containerBookingId, loadingPlanId, warehouseId }))) {
|
||||
context.addStep(MODULE, '国内报关资料与PDA证据必须完成后才允许进入出仓确认', null, false,
|
||||
`containerBookingId=${containerBookingId}, loadingPlanId=${loadingPlanId}, warehouseId=${warehouseId}`, OPTIONS)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user