diff --git a/firstleg/src/main/java/com/baiyue/firstleg/entity/LoadingPlanItemEntity.java b/firstleg/src/main/java/com/baiyue/firstleg/entity/LoadingPlanItemEntity.java index 6e402cecf..0f12680ca 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/entity/LoadingPlanItemEntity.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/entity/LoadingPlanItemEntity.java @@ -13,6 +13,8 @@ public class LoadingPlanItemEntity { @TableField(exist=false) private Long activeInboundDetailId; @TableField(exist=false) private Integer pickedPackageCount; @TableField(exist=false) private Integer minPackageCount; + @TableField(exist=false) private Integer totalPackageCount; + @TableField(exist=false) private Integer remainingPackageCount; @TableField(exist=false) private Boolean canAdjust; @TableField(exist=false) private Boolean canRemove; private Long createdBy; private String createdByName; private LocalDateTime createdAt; diff --git a/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java b/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java index 8f9f0fd11..3419e04ef 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java @@ -847,16 +847,29 @@ public class SmartLoadingService { ContainerBookingEntity booking = requireBooking(plan.getContainerBookingId()); Candidate candidate = repository.candidate(planId, booking.getWarehouseId(), item.getInboundId(), item.getInboundDetailId()); - if (candidate == null) throw validation("调整箱数超过可用箱数"); int currentPackageCount = item.getPackageCount() == null ? 0 : item.getPackageCount(); - int remainingPackageCount = Math.max(0, candidate.availablePackageCount() == null - ? 0 : candidate.availablePackageCount()); - if (request.packageCount() > currentPackageCount - && request.packageCount() - currentPackageCount > remainingPackageCount) { + OrderCargoClient.CargoBinding cargo; + int maxPackageCount; + if (candidate == null) { + InboundOrderEntity inbound = repository.inbound(item.getAccountId(), item.getInboundId()); + if (inbound == null || !Set.of("PREPARING", "WAIT_MEASURE", "MEASURING", "MEASURE_PENDING", + "MEASURE_REJECTED", "WAIT_PRICING", "FEE_CONFIRMING", "INBOUNDING") + .contains(inbound.getProcessStatus())) { + throw validation("调整箱数超过可用箱数"); + } + cargo = loadCargo(item.getAccountId(), item.getOrderId(), item.getInboundDetailId()); + var snapshot = loadInboundSnapshot(item.getAccountId(), item.getOrderId()); + candidate = declaredCandidate(snapshot, item.getInboundId(), cargo, "WAIT_MEASURE"); + maxPackageCount = cargo.originalPackageCount() == null ? 0 : cargo.originalPackageCount(); + } else { + cargo = loadCargo(candidate); + maxPackageCount = currentPackageCount + Math.max(0, candidate.availablePackageCount() == null + ? 0 : candidate.availablePackageCount()); + } + if (request.packageCount() > maxPackageCount) { throw validation("调整箱数超过可用箱数"); } requireSameCustomerScope(booking, candidate); - OrderCargoClient.CargoBinding cargo = loadCargo(candidate); List others = new ArrayList<>(repository.items(planId)); others.removeIf(x -> Objects.equals(x.getId(), itemId)); checkRouteAndCapacity(booking, others, candidate, request.packageCount(), true); @@ -1246,9 +1259,13 @@ public class SmartLoadingService { } private OrderCargoClient.CargoBinding loadCargo(Candidate candidate) { + return loadCargo(candidate.accountId(), candidate.orderId(), candidate.inboundDetailId()); + } + + private OrderCargoClient.CargoBinding loadCargo(long accountId, long orderId, long inboundDetailId) { try { ApiResponse response = orderCargoClient.detail(internalToken, - candidate.accountId(), candidate.orderId(), candidate.inboundDetailId()); + accountId, orderId, inboundDetailId); if (response == null) { throw unavailable(); } @@ -1256,8 +1273,8 @@ public class SmartLoadingService { throw new BizException(ResultCode.of(response.code()), response.message()); } OrderCargoClient.CargoBinding cargo = response.data(); - if (cargo == null || !Objects.equals(cargo.cargoId(), candidate.inboundDetailId()) - || !Objects.equals(cargo.orderId(), candidate.orderId())) { + if (cargo == null || !Objects.equals(cargo.cargoId(), inboundDetailId) + || !Objects.equals(cargo.orderId(), orderId)) { throw conflict("订单货物明细返回与入库单不匹配"); } return cargo; @@ -1412,6 +1429,9 @@ public class SmartLoadingService { int picked = task.pickedByPlanItem().getOrDefault(item.getId(), 0); item.setPickedPackageCount(picked); item.setMinPackageCount(Math.max(1, picked)); + int total = adjustmentTotal(p.getId(), b.getWarehouseId(), item); + item.setTotalPackageCount(total); + item.setRemainingPackageCount(Math.max(0, total - item.getPackageCount())); item.setCanAdjust(mutable); item.setCanRemove(mutable && picked == 0); } @@ -1421,6 +1441,24 @@ public class SmartLoadingService { b.getContainerNo(),b.getVoyageNo(),p.getVersion(),mutable,mutable,blockedReason,finalStatus, task.taskId(),task.taskStatus(),task.taskVersion(),planCoLoadGroups(p.getId()),items); } + private int adjustmentTotal(long planId, long warehouseId, LoadingPlanItemEntity item) { + int current = item.getPackageCount() == null ? 0 : item.getPackageCount(); + Candidate measured = repository.candidate(planId, warehouseId, item.getInboundId(), item.getInboundDetailId()); + if (measured != null) { + return current + Math.max(0, measured.availablePackageCount() == null + ? 0 : measured.availablePackageCount()); + } + InboundOrderEntity inbound = repository.inbound(item.getAccountId(), item.getInboundId()); + if (inbound == null || !Set.of("PREPARING", "WAIT_MEASURE", "MEASURING", "MEASURE_PENDING", + "MEASURE_REJECTED", "WAIT_PRICING", "FEE_CONFIRMING", "INBOUNDING") + .contains(inbound.getProcessStatus())) return current; + try { + OrderCargoClient.CargoBinding cargo = loadCargo(item.getAccountId(), item.getOrderId(), item.getInboundDetailId()); + return Math.max(current, cargo.originalPackageCount() == null ? 0 : cargo.originalPackageCount()); + } catch (RuntimeException ignored) { + return current; + } + } private List planCoLoadGroups(long planId) { Map> grouped=repository.planColoadMembers(planId).stream() .collect(java.util.stream.Collectors.groupingBy(PlanColoadMemberRow::groupId,