优化
This commit is contained in:
@@ -14,6 +14,7 @@ import { mkdir, writeFile } from 'node:fs/promises'
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { resolve } from 'node:path'
|
||||
import { createInterface } from 'node:readline/promises'
|
||||
import { frozenOuterMeasurement, publishedMeasurementItemsMatch } from './client-phase2-measurement-evidence.mjs'
|
||||
|
||||
const args = parseArgs(process.argv.slice(2))
|
||||
const gateway = trimSlash(args.gateway ?? process.env.ADMIN_TEST_GATEWAY)
|
||||
@@ -75,7 +76,6 @@ let pendingFixture
|
||||
let foreignFixture
|
||||
let platformTerminalDetail
|
||||
let platformMeasurement
|
||||
let dimensionRules = []
|
||||
let merchantBilling
|
||||
|
||||
try {
|
||||
@@ -192,7 +192,7 @@ async function fixtureDiscoveryModule() {
|
||||
}))
|
||||
platformTerminalDetail = detail.json.data
|
||||
|
||||
const dimensionConfig = await apiStep('phase2-measurement-fixture',
|
||||
await apiStep('phase2-measurement-fixture',
|
||||
'load four customer dimension weighting rules', {
|
||||
method: 'GET',
|
||||
path: `/api/platform/v1/first-leg/customer-dimension-config?tenantId=${report.resources.tenantId}`,
|
||||
@@ -214,7 +214,6 @@ async function fixtureDiscoveryModule() {
|
||||
version: rule.version,
|
||||
})),
|
||||
}))
|
||||
dimensionRules = dimensionConfig.json.data.rules
|
||||
|
||||
const measurement = await apiStep('phase2-measurement-fixture',
|
||||
'load approved terminal measurement detail', {
|
||||
@@ -297,9 +296,9 @@ async function fixtureDiscoveryModule() {
|
||||
})
|
||||
|
||||
await softLocalStep('phase2-measurement-fixture',
|
||||
'carton billing volume uses current customer dimension weighting', () => {
|
||||
'carton billing volume agrees with frozen calculated outer dimensions', () => {
|
||||
for (const item of platformMeasurement.items) {
|
||||
const expected = resolveWeightedDimensions(item, dimensionRules)
|
||||
const expected = frozenOuterMeasurement(item)
|
||||
assertApproxEqual(item.unitVolumeCbm, expected.unitVolumeCbm, 0.000001,
|
||||
`${item.itemNo} weighted unit volume`)
|
||||
}
|
||||
@@ -310,7 +309,7 @@ async function fixtureDiscoveryModule() {
|
||||
measured: dimensions(item),
|
||||
storedOuter: dimensions(item, 'outer'),
|
||||
unitVolumeCbm: item.unitVolumeCbm,
|
||||
expected: resolveWeightedDimensions(item, dimensionRules),
|
||||
expected: frozenOuterMeasurement(item),
|
||||
})),
|
||||
})
|
||||
|
||||
@@ -486,22 +485,13 @@ async function terminalBillingModule() {
|
||||
|
||||
await softLocalStep('phase2-client-billing', 'published carton measurements match platform snapshot', () => {
|
||||
const publishedItems = arrayData(merchantBilling.measurementItems)
|
||||
assertEqual(publishedItems.length, platformMeasurement.items.length, 'published measurement item count')
|
||||
const platformById = new Map(platformMeasurement.items.map((item) => [String(item.id), item]))
|
||||
for (const item of publishedItems) {
|
||||
assertStringId(item.id, 'published measurement item id')
|
||||
const expected = platformById.get(String(item.id))
|
||||
assertPresent(expected, `platform measurement item ${item.id}`)
|
||||
for (const field of ['packageCount', 'lengthCm', 'widthCm', 'heightCm',
|
||||
'unitVolumeCbm', 'totalVolumeCbm', 'volumeWeightKg']) {
|
||||
assertApproxEqual(item[field], expected[field], 0.000001, `${item.itemNo} ${field}`)
|
||||
}
|
||||
}
|
||||
assertTrue(publishedMeasurementItemsMatch(publishedItems, platformMeasurement.items), 'published outer dimensions and frozen calculation metadata')
|
||||
}, { measurementItemCount: arrayData(merchantBilling.measurementItems).length })
|
||||
|
||||
await softLocalStep('phase2-client-billing', 'published carton volumes follow current weighting rules', () => {
|
||||
await softLocalStep('phase2-client-billing', 'published carton volumes follow frozen outer dimensions', () => {
|
||||
const platformById = new Map(platformMeasurement.items.map(item => [String(item.id), item]))
|
||||
for (const item of arrayData(merchantBilling.measurementItems)) {
|
||||
const expected = resolveWeightedDimensions(item, dimensionRules)
|
||||
const expected = frozenOuterMeasurement(platformById.get(String(item.id)))
|
||||
assertApproxEqual(item.unitVolumeCbm, expected.unitVolumeCbm, 0.000001,
|
||||
`${item.itemNo} published weighted unit volume`)
|
||||
}
|
||||
@@ -510,7 +500,7 @@ async function terminalBillingModule() {
|
||||
itemNo: item.itemNo,
|
||||
measured: dimensions(item),
|
||||
unitVolumeCbm: item.unitVolumeCbm,
|
||||
expected: resolveWeightedDimensions(item, dimensionRules),
|
||||
frozenOuter: [item.lengthCm, item.widthCm, item.heightCm],
|
||||
})),
|
||||
})
|
||||
|
||||
@@ -816,33 +806,6 @@ function assertDimensionRule(rule) {
|
||||
0.0005, `${rule.boxType} configured volume`)
|
||||
}
|
||||
|
||||
function resolveWeightedDimensions(item, rules) {
|
||||
const measured = [Number(item.lengthCm), Number(item.widthCm), Number(item.heightCm)]
|
||||
.sort((left, right) => right - left)
|
||||
const candidates = [...arrayData(rules)].sort((left, right) =>
|
||||
Number(left.innerLengthCm) * Number(left.innerWidthCm) * Number(left.innerHeightCm)
|
||||
- Number(right.innerLengthCm) * Number(right.innerWidthCm) * Number(right.innerHeightCm))
|
||||
const rule = candidates.find((candidate) => {
|
||||
const inner = [Number(candidate.innerLengthCm), Number(candidate.innerWidthCm),
|
||||
Number(candidate.innerHeightCm)].sort((left, right) => right - left)
|
||||
return measured.every((value, index) => value <= inner[index])
|
||||
})
|
||||
if (!rule) {
|
||||
const rawVolume = measured.reduce((total, value) => total * value, 1) / 1_000_000
|
||||
return { boxType: null, ruleVersion: null, outer: dimensions(item),
|
||||
unitVolumeCbm: round(rawVolume, 3) }
|
||||
}
|
||||
const edgePair = Number(rule.edgeAdditionCm) * 2
|
||||
const outer = [Number(rule.innerLengthCm) + edgePair, Number(rule.innerWidthCm) + edgePair,
|
||||
Number(rule.innerHeightCm) + edgePair]
|
||||
return {
|
||||
boxType: rule.boxType,
|
||||
ruleVersion: rule.version,
|
||||
outer,
|
||||
unitVolumeCbm: round(outer.reduce((total, value) => total * value, 1) / 1_000_000, 3),
|
||||
}
|
||||
}
|
||||
|
||||
function dimensions(value, prefix = '') {
|
||||
const field = (name) => `${prefix}${prefix ? name[0].toUpperCase() + name.slice(1) : name}`
|
||||
return [value?.[field('lengthCm')] ?? null, value?.[field('widthCm')] ?? null,
|
||||
@@ -853,11 +816,6 @@ function sum(values, field) {
|
||||
return arrayData(values).reduce((total, value) => total + Number(value?.[field] ?? 0), 0)
|
||||
}
|
||||
|
||||
function round(value, scale) {
|
||||
const factor = 10 ** scale
|
||||
return Math.round((Number(value) + Number.EPSILON) * factor) / factor
|
||||
}
|
||||
|
||||
function statusCounts(values) {
|
||||
const counts = {}
|
||||
for (const row of arrayData(values)) {
|
||||
|
||||
Reference in New Issue
Block a user