fix: hide completed receiving containers

This commit is contained in:
2026-09-03 10:08:57 +08:00
parent 59add49408
commit 7359fbc093
2 changed files with 19 additions and 2 deletions
@@ -114,6 +114,7 @@ public class ReceivingContainerService {
.map(entry -> readiness(entry.getKey(), entry.getValue(), planFacts, lineFacts, overseasWarehouseId)) .map(entry -> readiness(entry.getKey(), entry.getValue(), planFacts, lineFacts, overseasWarehouseId))
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(ContainerReadiness::shippingReady) .filter(ContainerReadiness::shippingReady)
.filter(value -> !value.allPlansCompleted())
.filter(value -> !reservedByOthers.contains(activeContainerKey(value.containerNo()))) .filter(value -> !reservedByOthers.contains(activeContainerKey(value.containerNo())))
.map(value -> candidate(value, current)).toList(); .map(value -> candidate(value, current)).toList();
} }
@@ -453,6 +454,10 @@ public class ReceivingContainerService {
int planCount = matchedPlans.size(); int planCount = matchedPlans.size();
boolean allPlansReady = totalOrders > 0 && customers.size() == 1 && inboundCodes == totalOrders boolean allPlansReady = totalOrders > 0 && customers.size() == 1 && inboundCodes == totalOrders
&& plannedOrders == totalOrders && planCount == totalOrders; && plannedOrders == totalOrders && planCount == totalOrders;
List<InboundPlan> containerPlans = planFacts.stream()
.filter(plan -> containerNo.equals(plan.getContainerNo())).toList();
boolean allPlansCompleted = !containerPlans.isEmpty()
&& containerPlans.stream().allMatch(plan -> "COMPLETED".equals(plan.getStatus()));
String customerId = customers.size() == 1 ? customers.iterator().next() : null; String customerId = customers.size() == 1 ? customers.iterator().next() : null;
boolean shippingReady = customerId != null && shippingGates.receivingAvailable(customerId, containerNo) == 1; boolean shippingReady = customerId != null && shippingGates.receivingAvailable(customerId, containerNo) == 1;
boolean operable = allPlansReady && shippingReady; boolean operable = allPlansReady && shippingReady;
@@ -480,7 +485,7 @@ public class ReceivingContainerService {
inboundValues.stream().mapToInt(ReceivingContainerResponses.Inbound::totalPackages).sum(), inboundValues.stream().mapToInt(ReceivingContainerResponses.Inbound::totalPackages).sum(),
inboundValues.stream().mapToInt(ReceivingContainerResponses.Inbound::receivedPackages).sum()); inboundValues.stream().mapToInt(ReceivingContainerResponses.Inbound::receivedPackages).sum());
return new ContainerReadiness(sourceContainerBookingId, containerNo, totalOrders, inboundCodes, return new ContainerReadiness(sourceContainerBookingId, containerNo, totalOrders, inboundCodes,
totalOrders - inboundCodes, planCount, plannedOrders, pending, allPlansReady, shippingReady, operable, totalOrders - inboundCodes, planCount, plannedOrders, pending, allPlansReady, allPlansCompleted, shippingReady, operable,
blockReason, arrival, factHash, totals); blockReason, arrival, factHash, totals);
} }
@@ -983,7 +988,7 @@ public class ReceivingContainerService {
private record ContainerReadiness(String sourceContainerBookingId, String containerNo, private record ContainerReadiness(String sourceContainerBookingId, String containerNo,
int totalOrderCount, int inboundCodeCount, int missingInboundCodeCount, int totalOrderCount, int inboundCodeCount, int missingInboundCodeCount,
int planCount, int plannedInboundCodeCount, int pendingPlanCount, int planCount, int plannedInboundCodeCount, int pendingPlanCount,
boolean allPlansReady, boolean shippingReady, boolean operable, String blockReason, boolean allPlansReady, boolean allPlansCompleted, boolean shippingReady, boolean operable, String blockReason,
LocalDateTime plannedArrivalAt, String factHash, Totals totals) { } LocalDateTime plannedArrivalAt, String factHash, Totals totals) { }
private record PrepareCommand(String containerNo, String idempotencyKey) { } private record PrepareCommand(String containerNo, String idempotencyKey) { }
} }
@@ -190,6 +190,18 @@ class ReceivingContainerServiceBehaviorTest {
assertThat(service.candidates("7", 100L)).extracting("containerNo").containsExactly("CONT-A"); assertThat(service.candidates("7", 100L)).extracting("containerNo").containsExactly("CONT-A");
} }
@Test
void candidatesHideCompletedContainers() {
InboundPlan completed = plan("CONT-A");
completed.setStatus("COMPLETED");
when(plans.selectList(any())).thenReturn(List.of(completed));
when(lines.selectList(any())).thenReturn(List.of(line("FBA")));
when(orders.selectList(any())).thenReturn(List.of(
containerOrder(1L, "100", "CONT-A", "BOOKING-A", "IN-1")));
assertThat(service.candidates("7", 100L)).isEmpty();
}
@Test @Test
void partialContainerPlansRemainVisibleAndPrepareIsHardRejected() { void partialContainerPlansRemainVisibleAndPrepareIsHardRejected() {
InboundPlan firstPlan = plan("CONT-A"); InboundPlan firstPlan = plan("CONT-A");