fix(firstleg): persist pricing conversion metadata
This commit is contained in:
@@ -69,7 +69,8 @@ public final class FbaPricingDtos {
|
||||
String businessType, String channelCode, Long carrierId, String carrierName,
|
||||
String destinationType, Long destinationWarehouseId, String destinationName, String destinationCode,
|
||||
String taxMode, String pricingTaxMode, String chargeMode,
|
||||
BigDecimal conversionFactor, Integer roundingScale, String roundingMode,
|
||||
@NotNull BigDecimal conversionFactor, @NotNull Integer roundingScale,
|
||||
@NotBlank String roundingMode,
|
||||
BigDecimal actualWeightKg, BigDecimal actualVolumeCbm,
|
||||
BigDecimal convertedQuantity, BigDecimal chargeableQuantity, String chargeUnit,
|
||||
BigDecimal unitPrice, BigDecimal subtotalAmount, BigDecimal additionalAmount,
|
||||
|
||||
@@ -69,7 +69,8 @@ public class ActivePriceBookEstimator {
|
||||
requireModel(rate, PriceModel.FBA_WAREHOUSE_RATE);
|
||||
var estimate = fbaEstimator.estimate(rate, request.actualWeightKg(), request.actualVolumeCbm());
|
||||
return new Estimate(versionId, channelCode, PriceModel.FBA_WAREHOUSE_RATE, request.pricingTaxMode(),
|
||||
rate, estimate.quantity(), estimate.unit(), estimate.unitPrice(), estimate.amount(), estimate.currency());
|
||||
rate, estimate.quantity(), estimate.unit(), estimate.unitPrice(), estimate.amount(), estimate.currency(),
|
||||
estimate.conversionFactor(), estimate.roundingScale(), estimate.roundingMode());
|
||||
}
|
||||
|
||||
private Estimate estimateRegion(long versionId, String channelCode, EstimateRequest request) {
|
||||
@@ -91,7 +92,8 @@ public class ActivePriceBookEstimator {
|
||||
var estimate = regionEstimator.estimate(tiers, request.actualWeightKg(), request.actualVolumeCbm());
|
||||
RateRow selected = estimate.rate();
|
||||
return new Estimate(versionId, channelCode, PriceModel.REGION_WEIGHT_TIER, request.pricingTaxMode(),
|
||||
selected, estimate.quantity(), "KG", estimate.unitPrice(), estimate.amount(), estimate.currency());
|
||||
selected, estimate.quantity(), "KG", estimate.unitPrice(), estimate.amount(), estimate.currency(),
|
||||
estimate.conversionFactor(), estimate.roundingScale(), estimate.roundingMode());
|
||||
}
|
||||
|
||||
private PriceRegion resolveWarehouseRegion(Long warehouseId) {
|
||||
@@ -146,6 +148,9 @@ public class ActivePriceBookEstimator {
|
||||
String chargeUnit,
|
||||
BigDecimal unitPrice,
|
||||
BigDecimal amount,
|
||||
String currency
|
||||
String currency,
|
||||
BigDecimal conversionFactor,
|
||||
int roundingScale,
|
||||
String roundingMode
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import java.math.RoundingMode;
|
||||
public class FbaWarehouseRateEstimator {
|
||||
private static final BigDecimal KG_PER_CBM = BigDecimal.valueOf(167);
|
||||
private static final BigDecimal KG_PER_BILLABLE_CBM = BigDecimal.valueOf(363);
|
||||
private static final int QUANTITY_SCALE = 6;
|
||||
private static final RoundingMode QUANTITY_ROUNDING_MODE = RoundingMode.HALF_UP;
|
||||
|
||||
public Estimate estimate(RateRow rate, BigDecimal actualWeightKg, BigDecimal actualVolumeCbm) {
|
||||
BigDecimal weight = nonNegative(actualWeightKg);
|
||||
@@ -19,14 +21,20 @@ public class FbaWarehouseRateEstimator {
|
||||
if (weight.signum() == 0 && volume.signum() == 0) {
|
||||
throw new BizException(ResultCode.VALIDATION_FAILED, "重量和体积至少填写一项且必须大于0");
|
||||
}
|
||||
BigDecimal conversionFactor = switch (rate.getChargeUnit()) {
|
||||
case "KG" -> KG_PER_CBM;
|
||||
case "CBM" -> KG_PER_BILLABLE_CBM;
|
||||
default -> throw new BizException(ResultCode.CONFLICT, "当前价格计费单位不受支持");
|
||||
};
|
||||
BigDecimal quantity = switch (rate.getChargeUnit()) {
|
||||
case "KG" -> weight.max(volume.multiply(KG_PER_CBM));
|
||||
case "CBM" -> volume.max(weight.divide(KG_PER_BILLABLE_CBM, 12, RoundingMode.HALF_UP));
|
||||
default -> throw new BizException(ResultCode.CONFLICT, "当前价格计费单位不受支持");
|
||||
};
|
||||
quantity = quantity.setScale(6, RoundingMode.HALF_UP);
|
||||
quantity = quantity.setScale(QUANTITY_SCALE, QUANTITY_ROUNDING_MODE);
|
||||
return new Estimate(quantity, rate.getChargeUnit(), rate.getUnitPrice(),
|
||||
quantity.multiply(rate.getUnitPrice()).setScale(2, RoundingMode.HALF_UP), rate.getCurrency());
|
||||
quantity.multiply(rate.getUnitPrice()).setScale(2, RoundingMode.HALF_UP), rate.getCurrency(),
|
||||
conversionFactor, QUANTITY_SCALE, QUANTITY_ROUNDING_MODE.name());
|
||||
}
|
||||
|
||||
private static BigDecimal nonNegative(BigDecimal value) {
|
||||
@@ -36,5 +44,6 @@ public class FbaWarehouseRateEstimator {
|
||||
}
|
||||
|
||||
public record Estimate(BigDecimal quantity, String unit, BigDecimal unitPrice,
|
||||
BigDecimal amount, String currency) {}
|
||||
BigDecimal amount, String currency, BigDecimal conversionFactor,
|
||||
int roundingScale, String roundingMode) {}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import java.util.List;
|
||||
@Component
|
||||
public class RegionWeightTierEstimator {
|
||||
private static final BigDecimal KG_PER_CBM = BigDecimal.valueOf(167);
|
||||
private static final int QUANTITY_SCALE = 6;
|
||||
private static final RoundingMode QUANTITY_ROUNDING_MODE = RoundingMode.HALF_UP;
|
||||
|
||||
public Estimate estimate(List<RateRow> tiers, BigDecimal actualWeightKg, BigDecimal actualVolumeCbm) {
|
||||
BigDecimal weight = nonNegative(actualWeightKg);
|
||||
@@ -20,7 +22,8 @@ public class RegionWeightTierEstimator {
|
||||
if (weight.signum() == 0 && volume.signum() == 0) {
|
||||
throw new BizException(ResultCode.VALIDATION_FAILED, "重量和体积至少填写一项且必须大于0");
|
||||
}
|
||||
BigDecimal quantity = weight.max(volume.multiply(KG_PER_CBM)).setScale(6, RoundingMode.HALF_UP);
|
||||
BigDecimal quantity = weight.max(volume.multiply(KG_PER_CBM))
|
||||
.setScale(QUANTITY_SCALE, QUANTITY_ROUNDING_MODE);
|
||||
RateRow selected = tiers.stream()
|
||||
.filter(rate -> "KG".equals(rate.getChargeUnit()) && rate.getWeightFromKg() != null)
|
||||
.filter(rate -> rate.getWeightFromKg().compareTo(quantity) <= 0)
|
||||
@@ -28,7 +31,8 @@ public class RegionWeightTierEstimator {
|
||||
.orElseThrow(() -> new BizException(ResultCode.VALIDATION_FAILED,
|
||||
"当前计费重量未达到该海派渠道的最低重量阶梯"));
|
||||
return new Estimate(selected, quantity, selected.getUnitPrice(),
|
||||
quantity.multiply(selected.getUnitPrice()).setScale(2, RoundingMode.HALF_UP), selected.getCurrency());
|
||||
quantity.multiply(selected.getUnitPrice()).setScale(2, RoundingMode.HALF_UP), selected.getCurrency(),
|
||||
KG_PER_CBM, QUANTITY_SCALE, QUANTITY_ROUNDING_MODE.name());
|
||||
}
|
||||
|
||||
private static BigDecimal nonNegative(BigDecimal value) {
|
||||
@@ -38,5 +42,6 @@ public class RegionWeightTierEstimator {
|
||||
}
|
||||
|
||||
public record Estimate(RateRow rate, BigDecimal quantity, BigDecimal unitPrice, BigDecimal amount,
|
||||
String currency) {}
|
||||
String currency, BigDecimal conversionFactor, int roundingScale,
|
||||
String roundingMode) {}
|
||||
}
|
||||
|
||||
@@ -318,7 +318,8 @@ public class FbaPricingService {
|
||||
fee.setRuleCode(null); fee.setCustomerId(inbound.getCustomerId());
|
||||
fee.setCustomerName(inbound.getCustomerName()); fee.setBusinessType(inbound.getBusinessType());
|
||||
fee.setTaxMode(inbound.getTaxMode()); fee.setPricingTaxMode(inbound.getPricingTaxMode());
|
||||
fee.setRoundingScale(null); fee.setRoundingMode(null); fee.setRuleEffectiveFrom(null);
|
||||
fee.setRoundingScale(estimate.roundingScale()); fee.setRoundingMode(estimate.roundingMode());
|
||||
fee.setRuleEffectiveFrom(null);
|
||||
fee.setRuleEffectiveTo(null); fee.setRateCode(rate.getRateCode());
|
||||
fee.setOriginWarehouseId(rate.getOriginWarehouseId()); fee.setOriginWarehouseName(rate.getOriginWarehouseName());
|
||||
fee.setChannelCode(rate.getChannelCode()); fee.setCarrierId(null);
|
||||
@@ -326,7 +327,7 @@ public class FbaPricingService {
|
||||
fee.setDestinationWarehouseId(inbound.getDestinationWarehouseId()); fee.setDestinationName(inbound.getDestinationName());
|
||||
fee.setDestinationCode(inbound.getDestinationCode());
|
||||
fee.setRateEffectiveFrom(rate.getEffectiveFrom()); fee.setRateEffectiveTo(rate.getEffectiveTo());
|
||||
fee.setChargeMode(estimate.chargeUnit()); fee.setConversionFactor(null);
|
||||
fee.setChargeMode(estimate.chargeUnit()); fee.setConversionFactor(estimate.conversionFactor());
|
||||
fee.setActualWeightKg(weight); fee.setActualVolumeCbm(volume); fee.setConvertedQuantity(converted);
|
||||
fee.setChargeableQuantity(chargeable); fee.setChargeUnit(estimate.chargeUnit()); fee.setCurrency(rate.getCurrency());
|
||||
fee.setSubtotalAmount(subtotal); fee.setAdditionalAmount(additional); fee.setTotalAmount(total);
|
||||
|
||||
Reference in New Issue
Block a user