feat(firstleg): enforce pricing adjustment bounds

This commit is contained in:
2026-09-08 17:13:43 +08:00
parent 78a73a1b0e
commit 2e60f2cd77
11 changed files with 236 additions and 19 deletions
@@ -165,7 +165,7 @@ paths:
/api/platform/v1/inbounds/{inboundId}/fees/published:
put:
summary: 调整初算或已发布费用
description: 需要 firstleg:fba-pricing:adjust 权限;人工修改计费量、单价和附加费,小计与总额由服务端重算并生成新版本,不回退 WAIT_SPLIT 状态。调整 CALCULATED/CONFIRMED 时生成新的 CALCULATED 版本;调整 SENT 时生成新的 SENT 版本并发布调整事件。
description: 需要 firstleg:fba-pricing:adjust 权限;计费量只能在系统原计费量上下10%范围内(含边界),请求必须携带当前费用版本、必填原因及二次确认标志,越界或并发冲突返回A0409。小计与总额由服务端重算并生成新版本,不回退 WAIT_SPLIT 状态。调整 CALCULATED/CONFIRMED 时生成新的 CALCULATED 版本;调整 SENT 时生成新的 SENT 版本并发布调整事件。
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
requestBody:
required: true
@@ -330,6 +330,10 @@ components:
actualWeightKg: {type: number, nullable: true}
actualVolumeCbm: {type: number, nullable: true}
convertedQuantity: {type: number, nullable: true}
baselineChargeableQuantity: {type: number, description: 系统按权威测量与生效报价计算的原计费量,人工调整后保持不变}
lowerChargeableQuantity: {type: number, description: 允许人工调整的计费量下界,包含边界}
upperChargeableQuantity: {type: number, description: 允许人工调整的计费量上界,包含边界}
tolerancePercent: {type: number, enum: [10.00], description: 相对系统原计费量允许的上下偏差百分比}
chargeableQuantity: {type: number, nullable: true}
chargeUnit: {type: string, nullable: true}
unitPrice: {type: number, nullable: true}
@@ -466,16 +470,22 @@ components:
timestamp: {type: string, format: date-time, nullable: true}
AdjustFeeRequest:
type: object
required: [expectedFeeVersion, chargeableQuantity, unitPrice, additionalAmount, reason]
required: [expectedFeeVersion, chargeableQuantity, unitPrice, additionalAmount, reason, toleranceConfirmed]
properties:
expectedFeeVersion: {type: integer, minimum: 1}
chargeableQuantity: {type: number, minimum: 0, exclusiveMinimum: true, description: 计费量,单位沿用当前费用快照的 chargeUnit}
unitPrice: {type: number, minimum: 0, description: 人工确认单价}
additionalAmount: {type: number, minimum: 0, multipleOf: 0.01}
reason: {type: string, minLength: 1, maxLength: 500}
toleranceConfirmed: {type: boolean, enum: [true], description: 前端展示上下界并由操作员二次确认后固定传true;服务端仍会重新校验范围与版本}
CalculateRequest:
type: object
properties: {pricingAt: {type: string, format: date-time, description: 缺省为服务端当前时间}}
properties:
pricingAt: {type: string, format: date-time, description: 缺省为服务端当前时间}
selectedWeightKg: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true, description: 选定的权威重量快照}
selectedVolumeCbm: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true, description: 选定的权威体积快照}
weightSource: {type: string, maxLength: 32, nullable: true}
volumeSource: {type: string, maxLength: 32, nullable: true}
CustomerRuleVersionRequest:
type: object
required: [ruleCode, customerId, customerName, businessType, chargeMode, taxMode, conversionFactor, roundingScale, roundingMode, currency, effectiveFrom]
@@ -668,5 +678,6 @@ components:
destinationName: {type: string, maxLength: 128, nullable: true}
destinationRegion: {type: string, enum: [WEST, CENTRAL, EAST]}
pricingTaxMode: {$ref: '#/components/schemas/PricingTaxMode'}
chargeMode: {type: string, enum: [KG, CBM], description: 包税报价固定为KG;不包税报价必须与客户当前计费规则一致}
actualWeightKg: {type: number, minimum: 0}
actualVolumeCbm: {type: number, minimum: 0}