优化
This commit is contained in:
@@ -5,6 +5,7 @@ import jakarta.annotation.Resource;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.dto.FbaPricingDtos.FeeSnapshotResponse;
|
||||
import com.baiyue.firstleg.entity.CarrierFbaRateEntity;
|
||||
import com.baiyue.firstleg.dto.FbaPricingDtos.AdjustFeeRequest;
|
||||
import com.baiyue.firstleg.domain.PricingDestinationType;
|
||||
import com.baiyue.firstleg.domain.PricingTaxMode;
|
||||
@@ -278,29 +279,33 @@ public class FbaPricingService {
|
||||
if ("COMPLETED".equals(token.getStatus())) {
|
||||
return new ContainerFeeRecalculationResult(ContainerFeeRecalculationStatus.REPLAYED, 0);
|
||||
}
|
||||
BigDecimal aggregate = members.stream().map(ContainerFeeMember::chargeableQuantity)
|
||||
List<ContainerFeeMember> regionalMembers = members.stream()
|
||||
.filter(member -> priceModel(member.current()) == PriceModel.REGION_WEIGHT_TIER)
|
||||
.toList();
|
||||
List<ContainerFeeMember> unlockedRegionalMembers = regionalMembers.stream()
|
||||
.filter(member -> !member.locked()).toList();
|
||||
if (unlockedRegionalMembers.isEmpty()) {
|
||||
complete(token, containerBookingId, now);
|
||||
return new ContainerFeeRecalculationResult(ContainerFeeRecalculationStatus.NOT_APPLICABLE, 0);
|
||||
}
|
||||
BigDecimal aggregate = regionalMembers.stream().map(ContainerFeeMember::chargeableQuantity)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
List<ContainerTierAmountAllocator.Member> allocationMembers = members.stream()
|
||||
List<ContainerTierAmountAllocator.Member> allocationMembers = regionalMembers.stream()
|
||||
.map(member -> new ContainerTierAmountAllocator.Member(member.inbound().getId(), member.chargeableQuantity()))
|
||||
.toList();
|
||||
List<ContainerFeeQuote> quotes = new ArrayList<>();
|
||||
for (ContainerFeeMember member : unlockedMembers) {
|
||||
for (ContainerFeeMember member : unlockedRegionalMembers) {
|
||||
PricingPolicy policy = pricingPolicy(member.inbound(), now);
|
||||
ActivePriceBookEstimator.Estimate estimate = priceBookEstimator.estimate(tenantId, new EstimateRequest(
|
||||
member.inbound().getWarehouseId(), member.inbound().getChannelCode(), member.inbound().getDestinationCode(),
|
||||
destinationType(member.inbound()), member.inbound().getDestinationWarehouseId(),
|
||||
member.inbound().getDestinationName(), null, pricingTaxMode(member.inbound()), policy.chargeMode(),
|
||||
aggregate, BigDecimal.ZERO));
|
||||
if (estimate.priceModel() != PriceModel.REGION_WEIGHT_TIER) {
|
||||
throw conflict("柜内区域阶梯报价模型已变化,请重新试算费用后重试");
|
||||
}
|
||||
quotes.add(new ContainerFeeQuote(member, policy, estimate));
|
||||
}
|
||||
boolean regionalTier = quotes.stream().anyMatch(quote -> quote.estimate().priceModel() == PriceModel.REGION_WEIGHT_TIER);
|
||||
if (!regionalTier) {
|
||||
complete(token, containerBookingId, now);
|
||||
return new ContainerFeeRecalculationResult(ContainerFeeRecalculationStatus.NOT_APPLICABLE, 0);
|
||||
}
|
||||
if (quotes.stream().anyMatch(quote -> quote.estimate().priceModel() != PriceModel.REGION_WEIGHT_TIER)) {
|
||||
throw conflict("柜内客户费用报价模型不一致,不能重算阶梯费用");
|
||||
}
|
||||
for (ContainerFeeQuote quote : quotes) {
|
||||
ContainerTierAmountAllocator.Allocation allocation = containerTierAllocator.allocate(
|
||||
allocationMembers, quote.estimate().unitPrice());
|
||||
@@ -312,6 +317,18 @@ public class FbaPricingService {
|
||||
return new ContainerFeeRecalculationResult(ContainerFeeRecalculationStatus.RECALCULATED, quotes.size());
|
||||
}
|
||||
|
||||
private PriceModel priceModel(InboundFeeEntity fee) {
|
||||
CarrierFbaRateEntity rate = repository.findRate(fee.getCarrierRateId());
|
||||
if (rate == null || !StringUtils.hasText(rate.getPriceModel())) {
|
||||
throw conflict("费用快照引用的报价模型不存在,不能重算阶梯费用");
|
||||
}
|
||||
try {
|
||||
return PriceModel.valueOf(rate.getPriceModel());
|
||||
} catch (IllegalArgumentException exception) {
|
||||
throw conflict("费用快照引用的报价模型无效,不能重算阶梯费用");
|
||||
}
|
||||
}
|
||||
|
||||
private void persistContainerRecalculation(long tenantId, ContainerFeeQuote quote,
|
||||
BigDecimal subtotal, LocalDateTime now) {
|
||||
ContainerFeeMember member = quote.member();
|
||||
|
||||
@@ -66,7 +66,7 @@ paths:
|
||||
/api/platform/v1/first-leg/loading-plans/{planId}/confirm:
|
||||
post:
|
||||
summary: 原子确认整份预装计划
|
||||
description: 以 loadingPlanId 为唯一范围,原子确认全部已分配入库预装票据。要求计划已 push 且仍为 EDITING、稳定 bridge 完整、真实订舱已关联并为 RELEASED;真实集装箱号可在PDA确认装柜完成前补录。任一票不满足均不写入。成功后唯一创建待领取 PDA task,claim 后才推进 LOADING。同一 Idempotency-Key 与相同请求精确重放原响应,不同 Key 重复确认返回业务冲突。
|
||||
description: 以 loadingPlanId 为唯一范围,原子确认全部已分配入库预装票据。要求计划已 push 且仍为 EDITING、稳定 bridge 完整、真实订舱已关联并为 RELEASED,且真实集装箱号已经补录。任一条件不满足均不写入,也不创建 PDA task。成功后唯一创建待领取 PDA task,claim 后才推进 LOADING。同一 Idempotency-Key 与相同请求精确重放原响应,不同 Key 重复确认返回业务冲突。
|
||||
x-permission: platform:firstleg:preload:edit
|
||||
parameters: [{$ref: '#/components/parameters/PlanId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
requestBody:
|
||||
@@ -329,11 +329,11 @@ components:
|
||||
pdaTaskStatus: {type: string, nullable: true, description: PDA task 当前状态}
|
||||
confirmationStatus: {type: string, enum: [PENDING, PARTIALLY_CONFIRMED, CONFIRMED], description: 整份计划的预装确认状态}
|
||||
canConfirm: {type: boolean, description: 当前是否可调用计划级确认接口}
|
||||
readyForPda: {type: boolean, description: PDA 创建前置条件是否全部满足;不依赖真实集装箱号,task 已创建后仍为 true}
|
||||
readyForPda: {type: boolean, description: PDA 创建前置条件是否全部满足,包含真实集装箱号已录入}
|
||||
blockingReasons:
|
||||
type: array
|
||||
description: 阻止计划确认的稳定原因码
|
||||
items: {type: string, enum: [LOADING_PLAN_NOT_EDITING, PRELOAD_LINK_MISSING, OCEAN_BOOKING_NOT_LINKED, OCEAN_BOOKING_NOT_RELEASED, PDA_TASK_ALREADY_CREATED, PRELOAD_ALREADY_CONFIRMED]}
|
||||
items: {type: string, enum: [LOADING_PLAN_NOT_EDITING, PRELOAD_LINK_MISSING, CONTAINER_NO_MISSING, OCEAN_BOOKING_NOT_LINKED, OCEAN_BOOKING_NOT_RELEASED, PDA_TASK_ALREADY_CREATED, PRELOAD_ALREADY_CONFIRMED]}
|
||||
ConfirmPreloadRequest:
|
||||
type: object
|
||||
required: [expectedVersion, operationReason]
|
||||
|
||||
Reference in New Issue
Block a user