Files

110 lines
4.9 KiB
JavaScript

function id(value) { return value == null ? null : String(value) }
function number(value) { return value == null || Number.isNaN(Number(value)) ? null : Number(value) }
function text(value) { return value == null ? null : String(value) }
function bool(value) { return value === true }
function sorted(values, key) {
return [...(Array.isArray(values) ? values : [])]
.sort((left, right) => key(left).localeCompare(key(right)))
}
function planItem(item) {
return {
id: id(item?.id), loadingPlanId: id(item?.loadingPlanId), inboundId: id(item?.inboundId),
inboundDetailId: id(item?.inboundDetailId), accountId: id(item?.accountId), orderId: id(item?.orderId),
packageCount: number(item?.packageCount), loadSequence: number(item?.loadSequence),
frozenAt: text(item?.frozenAt), version: number(item?.version), deleted: bool(item?.deleted),
}
}
function detailItem(item) {
return {
itemId: id(item?.itemId), accountId: id(item?.accountId), inboundId: id(item?.inboundId),
inboundDetailId: id(item?.inboundDetailId), packageCount: number(item?.packageCount),
palletCount: number(item?.palletCount), loadSequence: number(item?.loadSequence),
frozenAt: text(item?.frozenAt),
}
}
function readiness(value) {
return {
preloadPushed: bool(value?.preloadPushed), containerNoReady: bool(value?.containerNoReady),
preloadLinkCount: number(value?.preloadLinkCount), confirmedPreloadCount: number(value?.confirmedPreloadCount),
oceanBookingId: id(value?.oceanBookingId), oceanBookingStatus: text(value?.oceanBookingStatus),
pdaTaskId: id(value?.pdaTaskId), pdaTaskStatus: text(value?.pdaTaskStatus),
confirmationStatus: text(value?.confirmationStatus), canConfirm: bool(value?.canConfirm),
readyForPda: bool(value?.readyForPda),
blockingReasons: sorted(value?.blockingReasons, (item) => text(item) || '').map(text),
}
}
function history(value) {
return {
historyId: id(value?.historyId), itemId: id(value?.itemId), actionType: text(value?.actionType),
fromStatus: text(value?.fromStatus), toStatus: text(value?.toStatus),
beforeSnapshot: text(value?.beforeSnapshot), afterSnapshot: text(value?.afterSnapshot),
operationReason: text(value?.operationReason), occurredAt: text(value?.occurredAt),
}
}
function link(value) {
return {
id: id(value?.id), tenantId: id(value?.tenantId), inboundId: id(value?.inboundId),
preloadPlanId: id(value?.preloadPlanId), preloadStatus: text(value?.preloadStatus),
preloadVersion: number(value?.preloadVersion), loadingPlanId: id(value?.loadingPlanId),
containerBookingId: id(value?.containerBookingId), containerNo: text(value?.containerNo),
loadingPlanStatus: text(value?.loadingPlanStatus), loadingPlanVersion: number(value?.loadingPlanVersion),
allocatedPackageCount: number(value?.allocatedPackageCount), linkedAt: text(value?.linkedAt),
}
}
export function projectPushPreloadStability({ plan, detail, links, task }) {
const summary = detail?.summary || {}
return {
plan: {
id: id(plan?.id), bookingId: id(plan?.bookingId), status: text(plan?.status),
containerNo: text(plan?.containerNo), voyageNo: text(plan?.voyageNo), version: number(plan?.version),
items: sorted(plan?.items, (item) => id(item?.id) || '').map(planItem),
},
detail: {
summary: {
planId: id(summary?.planId), containerBookingId: id(summary?.containerBookingId),
containerNo: text(summary?.containerNo), cabinetNo: text(summary?.cabinetNo),
status: text(summary?.status), version: number(summary?.version),
skuCount: number(summary?.skuCount), totalPackageCount: number(summary?.totalPackageCount),
readiness: readiness(summary?.readiness),
},
items: sorted(detail?.items, (item) => id(item?.itemId) || '').map(detailItem),
histories: sorted(detail?.histories,
(item) => `${id(item?.historyId) || ''}:${text(item?.occurredAt) || ''}`).map(history),
},
links: sorted(links, (item) => id(item?.id) || '').map(link),
task: { http: number(task?.http), code: text(task?.code) },
}
}
function display(value) {
if (value === undefined) return 'missing'
return JSON.stringify(value)
}
export function diffPushPreloadStability(before, after) {
const changes = []
function visit(left, right, path) {
if (Object.is(left, right)) return
if (Array.isArray(left) && Array.isArray(right)) {
const length = Math.max(left.length, right.length)
for (let index = 0; index < length; index += 1) visit(left[index], right[index], `${path}[${index}]`)
return
}
if (left && right && typeof left === 'object' && typeof right === 'object') {
const keys = [...new Set([...Object.keys(left), ...Object.keys(right)])].sort()
for (const key of keys) visit(left[key], right[key], path ? `${path}.${key}` : key)
return
}
changes.push(`${path}:${display(left)}->${display(right)}`)
}
visit(before, after, '')
return changes
}