test(finance): complete automatic fee fixture workflow

This commit is contained in:
2026-08-14 23:03:36 +08:00
parent 1db7c3b3cf
commit 32e9b69556
2 changed files with 35 additions and 1 deletions
@@ -30,6 +30,15 @@ test('fee writes use verified Firstleg paths and do not fabricate historical IDs
assert.match(source, /chargeUnit === 'CBM'/)
})
test('automatic fee fixture completes the reviewed pricing workflow without recalculating', () => {
assert.match(source, /latest\?\.feeId/)
assert.doesNotMatch(source, /latest\?\.id/)
assert.match(source, /`\$\{pricingBase\}\/latest\?\$\{tenantQuery\}`/)
assert.match(source, /request\(context, 'POST', `\$\{pricingBase\}\/confirm\?\$\{tenantQuery\}`\)/)
assert.match(source, /request\(context, 'POST', `\$\{pricingBase\}\/send\?\$\{tenantQuery\}`\)/)
assert.doesNotMatch(source, /request\(context, 'POST', `\$\{pricingBase\}\/calculate/)
})
test('shared fixture source names the finance full acceptance contract', () => {
for (const field of ['marker', 'customerId', 'orders', 'feeSources', 'container', 'allocations', 'supplier', 'voucherFileId', 'deploymentBlocker']) assert.match(source, new RegExp(`\\b${field}\\b`))
for (const field of ['feeSourceId', 'sourceType', 'direction', 'currency', 'amount', 'businessDate', 'billingBasis']) {
@@ -144,6 +144,31 @@ async function loadPublishedAutomaticFee(context, resource) {
`服务端计费实际读取 fl_inbound_order.actual_gross_weight_kg/actual_volume_cbm;inboundId=${resource.inboundId}, actualWeightKg=${actualWeightKg || 'missing'}, actualVolumeCbm=${actualVolumeCbm || 'missing'};测量表有值但主表未同步`)
return null
}
const pricingBase = `/api/platform/v1/inbounds/${encodeURIComponent(resource.inboundId)}/fees`
const tenantQuery = `tenantId=${encodeURIComponent(resource.tenantId)}`
const latestResponse = await context.request('GET', `${pricingBase}/latest?${tenantQuery}`)
let latest = context.apiSuccess(MODULE, '回读测量审核生成的自动费用试算', latestResponse,
`inboundId=${resource.inboundId}`, OPTIONS)
if (!latest?.feeId || !['CALCULATED', 'CONFIRMED', 'SENT'].includes(latest?.feeStatus)) {
blocker(context, '测量审核已生成可确认的自动费用试算',
`inboundId=${resource.inboundId}, feeId=${id(latest?.feeId) || 'missing'}, feeStatus=${latest?.feeStatus || 'missing'}, requestId=${latestResponse?.requestId || 'missing'}, traceId=${latestResponse?.traceId || 'missing'};审核只负责初算,Finance fixture 不重复试算`)
return null
}
if (latest.feeStatus === 'CALCULATED') {
const confirmResponse = await request(context, 'POST', `${pricingBase}/confirm?${tenantQuery}`)
latest = context.apiSuccess(MODULE, '确认测量审核生成的自动费用试算', confirmResponse,
`inboundId=${resource.inboundId}, feeId=${id(latest.feeId)}`, OPTIONS)
}
if (latest?.feeStatus === 'CONFIRMED') {
const sendResponse = await request(context, 'POST', `${pricingBase}/send?${tenantQuery}`)
latest = context.apiSuccess(MODULE, '发送已确认自动费用并发布来源', sendResponse,
`inboundId=${resource.inboundId}, feeId=${id(latest.feeId)}`, OPTIONS)
}
if (latest?.feeStatus !== 'SENT') {
blocker(context, '自动费用确认发送状态闭环',
`inboundId=${resource.inboundId}, feeId=${id(latest?.feeId) || 'missing'}, feeStatus=${latest?.feeStatus || 'missing'}`)
return null
}
const listPath = `/api/platform/v1/inbounds/${encodeURIComponent(resource.inboundId)}/fee-details?accountId=${encodeURIComponent(resource.tenantId)}`
const listResponse = await context.request('GET', listPath)
const details = context.apiSuccess(MODULE, '回读审核链已发布自动费用来源', listResponse,
@@ -153,7 +178,7 @@ async function loadPublishedAutomaticFee(context, resource) {
&& item?.settlementIncluded === true)
if (!published) {
blocker(context, '审核链已生成可结算自动费用来源',
`inboundId=${resource.inboundId}, processStatus=${pricingSummary.processStatus || pricingInbound?.processStatus || 'missing'}, feeDetails=${rows(details).length};测量审核完成链应在进入 WAIT_SPLIT 前生成 APPROVED + PUBLISHED 的 FBA_PRICING 来源,fixture 不重复试算/确认/发布`)
`inboundId=${resource.inboundId}, processStatus=${pricingSummary.processStatus || pricingInbound?.processStatus || 'missing'}, feeId=${id(latest.feeId)}, feeStatus=${latest.feeStatus}, feeDetails=${rows(details).length};确认和发送成功后应同步生成 APPROVED + PUBLISHED 的 FBA_PRICING 来源`)
return null
}
const feeSourceId = id(published.sourceFeeId)