This commit is contained in:
2026-08-27 17:16:33 +08:00
parent 61a97cd057
commit 76c24867a4
19 changed files with 474 additions and 107 deletions
@@ -31,6 +31,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.ArrayList;
import java.util.stream.Collectors;
@Service
@@ -73,7 +74,16 @@ public class InboundPlanService {
return detail(customerId, existing);
}
validateOrders(orders);
return createPlan(customerId, selectedOrderId, orders);
}
private InboundPlanResponse createPlan(String customerId, Long selectedOrderId,
List<SourceOrderSnapshot> orders) {
String containerNo = trimToNull(orders.get(0).containerNo());
if (containerNo == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Inbound order container number is empty");
}
LocalDateTime now = LocalDateTime.now();
InboundPlan plan = new InboundPlan();
plan.setId(IdWorker.getId());
@@ -128,21 +138,47 @@ public class InboundPlanService {
if (bookingId == null) throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "来源柜预订 ID 不能为空");
List<InboundPlanOrderMapper.ContainerOrderRef> refs = orderMapper.lockContainerOrders(bookingId);
if (refs.isEmpty()) throw new ResponseStatusException(HttpStatus.NOT_FOUND, "来源柜没有尾程订单");
boolean hasEligible = refs.stream().anyMatch(ref -> "PENDING_ASSIGNMENT".equals(ref.currentStatus())
|| "DESTINATION_ASSIGNED".equals(ref.currentStatus()));
if (!hasEligible) {
List<InboundPlanResponse> replay = refs.stream().map(ref -> {
InboundPlan existing = planMapper.findBySourceOrder(ref.customerId(), ref.orderId());
if (existing == null) throw new ResponseStatusException(HttpStatus.CONFLICT, "来源柜转换状态不一致");
return detail(ref.customerId(), existing);
}).toList();
return replay;
List<InboundPlan> existingPlans = refs.stream()
.map(ref -> planMapper.findBySourceOrder(ref.customerId(), ref.orderId()))
.toList();
long existingCount = existingPlans.stream().filter(Objects::nonNull).count();
if (existingCount == refs.size()) {
List<InboundPlanResponse> replay = new ArrayList<>(refs.size());
for (int index = 0; index < refs.size(); index++) {
replay.add(detail(refs.get(index).customerId(), existingPlans.get(index)));
}
return List.copyOf(replay);
}
if (existingCount != 0) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "来源柜仅部分尾程订单已有入库计划");
}
if (refs.stream().anyMatch(ref -> !("PENDING_ASSIGNMENT".equals(ref.currentStatus())
|| "DESTINATION_ASSIGNED".equals(ref.currentStatus())))) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "来源柜存在不能转换的尾程订单");
}
return refs.stream().map(ref -> convert(ref.customerId(), ref.orderId())).toList();
List<List<SourceOrderSnapshot>> snapshots = new ArrayList<>(refs.size());
String containerNo = null;
for (InboundPlanOrderMapper.ContainerOrderRef ref : refs) {
List<SourceOrderSnapshot> orders = orderMapper.lockOrder(ref.customerId(), ref.orderId());
if (orders == null || orders.isEmpty()) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "来源柜订单在锁定后不存在");
}
validateOrders(orders);
String currentContainerNo = trimToNull(orders.get(0).containerNo());
if (containerNo == null) containerNo = currentContainerNo;
if (!Objects.equals(containerNo, currentContainerNo)) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "来源柜内尾程订单柜号不一致");
}
snapshots.add(orders);
}
List<InboundPlanResponse> created = new ArrayList<>(refs.size());
for (int index = 0; index < refs.size(); index++) {
InboundPlanOrderMapper.ContainerOrderRef ref = refs.get(index);
created.add(createPlan(ref.customerId(), ref.orderId(), snapshots.get(index)));
}
return List.copyOf(created);
}