fix(order): show authoritative progress and billing in customer detail
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
import { orderBillingMetric } from './orderDetailSummary.ts'
|
||||
|
||||
test('detail uses the published billing quantity without substituting physical gross weight', () => {
|
||||
const billing = { inbound: { summary: { actualGrossWeightKg: 23, chargeableWeightKg: null } },
|
||||
billingBasis: { chargeUnit: 'KG', chargeableQuantity: 17.0006, chargeableWeightKg: null } }
|
||||
assert.deepEqual(orderBillingMetric(billing, null), { label: '计费重量', quantity: 17.0006, unit: 'kg' })
|
||||
assert.equal(orderBillingMetric(billing, null).quantity.toLocaleString('zh-CN'), '17.001')
|
||||
})
|
||||
|
||||
test('volume charging retains its real unit and missing billing does not invent a quantity', () => {
|
||||
assert.deepEqual(orderBillingMetric({ billingBasis: { chargeUnit: 'CBM', chargeableQuantity: 0.102 } }, 23),
|
||||
{ label: '计费体积', quantity: 0.102, unit: 'm³' })
|
||||
assert.equal(orderBillingMetric(null, null).quantity, null)
|
||||
assert.equal(orderBillingMetric(null, 0).quantity, 0)
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { MerchantInboundBilling } from '../types/inboundBilling'
|
||||
|
||||
/** Published billing quantity and physical gross weight have different meanings. */
|
||||
export function orderBillingMetric(billing: MerchantInboundBilling | null, measuredChargeableWeight: number | null) {
|
||||
if (billing) {
|
||||
const basis = billing.billingBasis
|
||||
return basis.chargeUnit === 'KG'
|
||||
? { label: '计费重量', quantity: basis.chargeableQuantity, unit: 'kg' }
|
||||
: basis.chargeUnit === 'CBM'
|
||||
? { label: '计费体积', quantity: basis.chargeableQuantity, unit: 'm³' }
|
||||
: { label: '计费量', quantity: null, unit: '' }
|
||||
}
|
||||
return { label: '计费重量', quantity: measuredChargeableWeight, unit: 'kg' }
|
||||
}
|
||||
@@ -13,3 +13,13 @@ test('prototype queues preserve order and distinguish partial progress from comp
|
||||
assert.equal(exports.orderProgressLabel({ stage: 'none', partial: false }), '—')
|
||||
assert.equal(exports.orderProgressLabel(), '—')
|
||||
})
|
||||
|
||||
test('detail progress must belong to the requested order and retain partial fulfillment', () => {
|
||||
const progress = { orderId: '2110663764278312961', stage: 'scheduled', partial: true }
|
||||
assert.equal(exports.requireOrderProgress(progress.orderId, progress), progress)
|
||||
assert.equal(exports.orderProgressLabel(exports.requireOrderProgress(progress.orderId, progress)), '部分已排车')
|
||||
assert.throws(() => exports.requireOrderProgress('other-order', progress), /订单履约进度不完整/)
|
||||
assert.throws(() => exports.requireOrderProgress(progress.orderId, undefined), /订单履约进度不完整/)
|
||||
assert.throws(() => exports.requireOrderProgress(progress.orderId, { ...progress, stage: 'UNKNOWN' }), /订单履约进度不完整/)
|
||||
assert.throws(() => exports.requireOrderProgress(progress.orderId, { ...progress, partial: null }), /订单履约进度不完整/)
|
||||
})
|
||||
|
||||
@@ -18,3 +18,12 @@ export function orderProgressLabel(progress?: MerchantOrderProgress) {
|
||||
const label = ORDER_QUEUES.find(q => q.key === progress.stage)?.label ?? '—'
|
||||
return `${progress.partial ? '部分' : ''}${label}`
|
||||
}
|
||||
|
||||
export function requireOrderProgress(orderId: string, progress: MerchantOrderProgress) {
|
||||
if (!progress || String(progress.orderId) !== orderId
|
||||
|| !['none', 'loaded', 'declared', 'cleared', 'scheduled', 'delivering', 'delivered'].includes(progress.stage)
|
||||
|| typeof progress.partial !== 'boolean') {
|
||||
throw new Error('订单履约进度不完整,请重新加载')
|
||||
}
|
||||
return progress
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user