81 lines
4.3 KiB
JavaScript
81 lines
4.3 KiB
JavaScript
function count(value) {
|
|
const number = Number(value)
|
|
return Number.isFinite(number) ? number : NaN
|
|
}
|
|
|
|
function currentMonth() {
|
|
return new Intl.DateTimeFormat('en-CA', {
|
|
timeZone: 'Asia/Shanghai', year: 'numeric', month: '2-digit',
|
|
}).format(new Date()).slice(0, 7)
|
|
}
|
|
|
|
function id(value) { return value == null ? '' : String(value) }
|
|
|
|
function listOf(value) {
|
|
if (Array.isArray(value)) return value
|
|
if (Array.isArray(value?.records)) return value.records
|
|
return null
|
|
}
|
|
|
|
export async function run(context) {
|
|
const module = 'sailing-calendar'
|
|
const base = '/api/platform/v1/sailings'
|
|
const month = currentMonth()
|
|
|
|
const calendarResponse = await context.request('GET', `${base}/calendar?month=${month}`)
|
|
const calendar = context.apiSuccess(module, '查询船期月历', calendarResponse)
|
|
const records = Array.isArray(calendar?.records) ? calendar.records : []
|
|
const summary = calendar?.summary
|
|
const filterOptions = calendar?.filterOptions
|
|
context.assert(module, '月历记录、汇总与筛选选项结构完整', calendarResponse,
|
|
records.every((row) => id(row.id) && id(row.sailingNo) && 'etaAt' in row)
|
|
&& summary && Number.isFinite(count(summary.sailingCount))
|
|
&& filterOptions && Array.isArray(filterOptions.warehouses) && Array.isArray(filterOptions.channels),
|
|
`month=${month},records=${records.length},sailingCount=${summary?.sailingCount ?? 'missing'}`)
|
|
context.assert(module, '月历容量汇总均为非负有限数', calendarResponse,
|
|
['actualReceivedCbm', 'catchableForecastCbm', 'riskUnmatchedCbm'].every((field) =>
|
|
Number.isFinite(count(summary?.[field])) && count(summary?.[field]) >= 0),
|
|
JSON.stringify(summary || {}).slice(0, 200))
|
|
|
|
const channelsResponse = await context.request('GET', '/api/platform/v1/sailing-channels')
|
|
const channels = context.apiSuccess(module, '查询船期渠道资源', channelsResponse)
|
|
const channelRows = listOf(channels) ?? []
|
|
context.assert(module, '渠道列表字段完整', channelsResponse,
|
|
channelRows.every((row) => id(row.id) && id(row.channelCode) && Number.isFinite(count(row.defaultCutoffDays))),
|
|
`count=${channelRows.length}`)
|
|
|
|
const templatesResponse = await context.request('GET', '/api/platform/v1/sailing-templates?page=1&size=200')
|
|
const templates = context.apiSuccess(module, '查询船期模板', templatesResponse)
|
|
const templateRows = listOf(templates) ?? []
|
|
context.assert(module, '模板列表字段完整', templatesResponse,
|
|
templateRows.every((row) => id(row.id) && id(row.channelId) && id(row.warehouseId) && Array.isArray(row.weekdays)),
|
|
`count=${templateRows.length}`)
|
|
|
|
const exceptionsResponse = await context.request('GET', '/api/platform/v1/sailing-assignments/exceptions?page=1&size=20')
|
|
const exceptions = context.apiSuccess(module, '查询船期异常分配', exceptionsResponse)
|
|
const exceptionRows = listOf(exceptions) ?? []
|
|
context.assert(module, '异常分配列表字段完整', exceptionsResponse,
|
|
exceptionRows.every((row) => id(row.assignmentId) && Number.isFinite(count(row.volumeCbm))),
|
|
`count=${exceptionRows.length},total=${exceptions?.total ?? 'array'}`)
|
|
|
|
if (records[0]) {
|
|
const detailResponse = await context.request('GET', `${base}/${encodeURIComponent(records[0].id)}`)
|
|
const detail = context.apiSuccess(module, '查询当前船期详情', detailResponse)
|
|
context.assert(module, '船期详情包含版本与货量摘要', detailResponse,
|
|
id(detail?.sailing?.id) === id(records[0].id)
|
|
&& Number.isFinite(count(detail?.sailing?.version))
|
|
&& detail?.sailing?.volumeSummary != null
|
|
&& Array.isArray(detail?.histories),
|
|
`id=${detail?.sailing?.id},version=${detail?.sailing?.version}`)
|
|
} else {
|
|
context.addCoverageGap(module, 'sailing-calendar', '船期详情与变更历史',
|
|
'当前月份没有船期记录;需先由订舱/模板生成本轮船期后重跑', 'not-implemented', { blocking: false })
|
|
}
|
|
|
|
const missingResponse = await context.request('GET', `${base}/999999999999999`)
|
|
context.assert(module, '不存在的船期详情被拒绝', missingResponse,
|
|
(missingResponse.http === 200 && ['A0403', 'A0404'].includes(String(missingResponse.body?.code)))
|
|
|| missingResponse.http === 404,
|
|
`HTTP=${missingResponse.http},code=${missingResponse.body?.code ?? 'missing'}`)
|
|
}
|