This commit is contained in:
2026-08-13 20:00:30 +08:00
parent 50251240f4
commit 5bc62a109e
28 changed files with 602 additions and 176 deletions
@@ -130,11 +130,11 @@ async function createManualFee(context, resource, feeItem, direction, amount, ba
chargeableWeightKg: detail?.chargeableWeightKg ?? null, chargeableVolumeCbm: detail?.chargeableVolumeCbm ?? null }
}
async function calculateAutomaticFee(context, resource) {
if (context.financeFixtureHooks?.calculateAutomaticFee) return context.financeFixtureHooks.calculateAutomaticFee(context, resource)
async function loadPublishedAutomaticFee(context, resource) {
if (context.financeFixtureHooks?.loadPublishedAutomaticFee) return context.financeFixtureHooks.loadPublishedAutomaticFee(context, resource)
const pricingInboundResponse = await context.request('GET',
`/api/platform/inbounds/${encodeURIComponent(resource.inboundId)}?tenantId=${encodeURIComponent(resource.tenantId)}`)
const pricingInbound = context.apiSuccess(MODULE, '计费前回读入库主表计费快照', pricingInboundResponse,
const pricingInbound = context.apiSuccess(MODULE, '回读审核完成后的入库主表状态', pricingInboundResponse,
`inboundId=${resource.inboundId}`, OPTIONS)
const pricingSummary = pricingInbound?.summary || {}
const actualWeightKg = Number(pricingSummary.actualGrossWeightKg ?? pricingSummary.actualWeightKg)
@@ -144,31 +144,33 @@ async function calculateAutomaticFee(context, resource) {
`服务端计费实际读取 fl_inbound_order.actual_gross_weight_kg/actual_volume_cbm;inboundId=${resource.inboundId}, actualWeightKg=${actualWeightKg || 'missing'}, actualVolumeCbm=${actualVolumeCbm || 'missing'};测量表有值但主表未同步`)
return null
}
const base = `/api/platform/v1/inbounds/${encodeURIComponent(resource.inboundId)}/fees`
const query = `tenantId=${encodeURIComponent(resource.tenantId)}`
const calculateResponse = await request(context, 'POST', `${base}/calculate?${query}`, {})
const calculated = context.apiSuccess(MODULE, '按审核测量快照执行真实自动计费', calculateResponse,
`orderId=${resource.orderId}, inboundId=${resource.inboundId}`, OPTIONS)
const feeSourceId = id(calculated?.feeId)
const billingBasis = calculated?.chargeUnit === 'KG' ? 'WEIGHT_KG'
: calculated?.chargeUnit === 'CBM' ? 'VOLUME_CBM' : null
const responseWeightKg = Number(calculated?.actualWeightKg)
const responseVolumeCbm = Number(calculated?.actualVolumeCbm)
context.assert(MODULE, '自动费用返回来源、金额和计费依据', calculateResponse,
Boolean(feeSourceId) && Boolean(billingBasis) && Number(calculated?.totalAmount) >= 0
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,
`inboundId=${resource.inboundId}`, OPTIONS)
const published = rows(details).find((item) => item?.sourceType === 'FBA_PRICING'
&& item?.reviewStatus === 'APPROVED' && item?.publicationStatus === 'PUBLISHED'
&& 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 不重复试算/确认/发布`)
return null
}
const feeSourceId = id(published.sourceFeeId)
const billingBasis = published.chargeUnit === 'KG' ? 'WEIGHT_KG'
: published.chargeUnit === 'CBM' ? 'VOLUME_CBM' : null
const responseWeightKg = Number(published.actualGrossWeightKg ?? actualWeightKg)
const responseVolumeCbm = Number(published.actualVolumeCbm ?? actualVolumeCbm)
context.assert(MODULE, '已发布自动费用来源、金额和计费依据完整', listResponse,
Boolean(feeSourceId) && Boolean(billingBasis) && Number(published.amount) >= 0
&& responseWeightKg > 0 && responseVolumeCbm > 0,
`feeSourceId=${feeSourceId || 'missing'}, chargeUnit=${calculated?.chargeUnit || 'missing'}, amount=${calculated?.totalAmount ?? 'missing'}, actualWeightKg=${responseWeightKg || 'missing'}, actualVolumeCbm=${responseVolumeCbm || 'missing'}`, OPTIONS)
`feeSourceId=${feeSourceId || 'missing'}, detailId=${id(published.id) || 'missing'}, chargeUnit=${published.chargeUnit || 'missing'}, amount=${published.amount ?? 'missing'}, actualWeightKg=${responseWeightKg || 'missing'}, actualVolumeCbm=${responseVolumeCbm || 'missing'}`, OPTIONS)
if (!feeSourceId || !billingBasis) return null
const confirmResponse = await request(context, 'POST', `${base}/confirm?${query}`)
const confirmed = context.apiSuccess(MODULE, '确认真实自动费用快照', confirmResponse, '', OPTIONS)
const sendResponse = await request(context, 'POST', `${base}/send?${query}`)
const sent = context.apiSuccess(MODULE, '发布真实自动费用来源', sendResponse, '', OPTIONS)
return { feeSourceId, orderId: id(resource.orderId), inboundId: id(resource.inboundId), sourceType: 'FBA_PRICING',
direction: 'RECEIVABLE', currency: sent?.currency || confirmed?.currency || calculated.currency,
amount: Number(sent?.totalAmount ?? confirmed?.totalAmount ?? calculated.totalAmount),
businessDate: String(sent?.sentAt || confirmed?.confirmedAt || calculated.calculatedAt || '').slice(0, 10),
billingBasis, chargeableQuantity: sent?.chargeableQuantity ?? calculated.chargeableQuantity,
chargeUnit: sent?.chargeUnit || calculated.chargeUnit,
direction: 'RECEIVABLE', currency: published.currency,
amount: Number(published.amount), businessDate: String(published.businessDate || published.publishedAt || '').slice(0, 10),
billingBasis, chargeableQuantity: published.chargeableQuantity,
chargeUnit: published.chargeUnit,
actualWeightKg: responseWeightKg, actualVolumeCbm: responseVolumeCbm }
}
@@ -328,7 +330,7 @@ export async function run(context) {
}
const fixtures = []
for (const resource of measured.slice(0, 4)) {
const fee = await calculateAutomaticFee(context, resource)
const fee = await loadPublishedAutomaticFee(context, resource)
if (fee) fixtures.push(fee)
}
for (const basis of ['WEIGHT_KG', 'VOLUME_CBM']) {