feat: plan from published read model
This commit is contained in:
@@ -39,6 +39,11 @@ public final class SchedulingFacade {
|
||||
return applicationService.planInbound(warehouseId, request);
|
||||
}
|
||||
|
||||
public InboundPlanningResult planInboundFromPublishedSnapshot(String warehouseId, InboundRequest request) {
|
||||
requireAlgorithmMode();
|
||||
return applicationService.planInboundFromPublishedSnapshot(warehouseId, request);
|
||||
}
|
||||
|
||||
public InboundReservationOutcome reserveInbound(String reservationId, String warehouseId,
|
||||
String projectNo, InboundPlanningResult plan) {
|
||||
requireActiveMode();
|
||||
@@ -50,6 +55,11 @@ public final class SchedulingFacade {
|
||||
return applicationService.planOutbound(warehouseId, request);
|
||||
}
|
||||
|
||||
public OutboundPlan planOutboundFromPublishedSnapshot(String warehouseId, OutboundRequest request) {
|
||||
requireAlgorithmMode();
|
||||
return applicationService.planOutboundFromPublishedSnapshot(warehouseId, request);
|
||||
}
|
||||
|
||||
public TidyPlan planTidy(String warehouseId, Instant now) {
|
||||
requireAlgorithmMode();
|
||||
return applicationService.planTidy(warehouseId, now);
|
||||
|
||||
@@ -76,7 +76,21 @@ public final class WarehouseApplicationService {
|
||||
}
|
||||
|
||||
public InboundPlanningResult planInbound(String warehouseId, InboundRequest request) {
|
||||
repository.refreshChangedLanes(warehouseId);
|
||||
return planInbound(warehouseId, request, true);
|
||||
}
|
||||
|
||||
public InboundPlanningResult planInboundFromPublishedSnapshot(String warehouseId, InboundRequest request) {
|
||||
return planInbound(warehouseId, request, false);
|
||||
}
|
||||
|
||||
private InboundPlanningResult planInbound(String warehouseId, InboundRequest request, boolean refresh) {
|
||||
if (refresh) {
|
||||
repository.refreshChangedLanes(warehouseId);
|
||||
}
|
||||
return planInboundFromCurrentReadModel(warehouseId, request);
|
||||
}
|
||||
|
||||
private InboundPlanningResult planInboundFromCurrentReadModel(String warehouseId, InboundRequest request) {
|
||||
RepositoryPolicy policy = repository.loadPolicy(warehouseId);
|
||||
WarehouseSummary summary = repository.loadSummary(warehouseId);
|
||||
InboundRequest effectiveRequest = request;
|
||||
@@ -115,7 +129,21 @@ public final class WarehouseApplicationService {
|
||||
}
|
||||
|
||||
public OutboundPlan planOutbound(String warehouseId, OutboundRequest request) {
|
||||
repository.refreshChangedLanes(warehouseId);
|
||||
return planOutbound(warehouseId, request, true);
|
||||
}
|
||||
|
||||
public OutboundPlan planOutboundFromPublishedSnapshot(String warehouseId, OutboundRequest request) {
|
||||
return planOutbound(warehouseId, request, false);
|
||||
}
|
||||
|
||||
private OutboundPlan planOutbound(String warehouseId, OutboundRequest request, boolean refresh) {
|
||||
if (refresh) {
|
||||
repository.refreshChangedLanes(warehouseId);
|
||||
}
|
||||
return planOutboundFromCurrentReadModel(warehouseId, request);
|
||||
}
|
||||
|
||||
private OutboundPlan planOutboundFromCurrentReadModel(String warehouseId, OutboundRequest request) {
|
||||
RepositoryPolicy policy = repository.loadPolicy(warehouseId);
|
||||
WarehouseSummary summary = repository.loadSummary(warehouseId);
|
||||
OutboundRequest effectiveRequest = request.fifoToleranceMinutes() == null && policy.fifoToleranceMinutes() > 0
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.ruoyi.algorithm.integration;
|
||||
|
||||
import com.ruoyi.algorithm.inbound.BatchLaneMode;
|
||||
import com.ruoyi.algorithm.inbound.InboundRequest;
|
||||
import com.ruoyi.algorithm.outbound.OutboundRequest;
|
||||
import com.ruoyi.algorithm.service.WarehouseApplicationService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
class SchedulingFacadePublishedSnapshotTest {
|
||||
|
||||
@Test
|
||||
void shadowDelegatesPublishedInboundPlanning() {
|
||||
WarehouseApplicationService applicationService = mock(WarehouseApplicationService.class);
|
||||
AlgorithmProperties properties = new AlgorithmProperties();
|
||||
properties.setMode(SchedulingMode.SHADOW);
|
||||
SchedulingFacade facade = new SchedulingFacade(applicationService, properties);
|
||||
InboundRequest request = new InboundRequest("I-STABLE", "T", "P", "SKU", "L", 2,
|
||||
1, null, Set.of(), BatchLaneMode.OPEN);
|
||||
|
||||
facade.planInboundFromPublishedSnapshot("W1", request);
|
||||
|
||||
verify(applicationService).planInboundFromPublishedSnapshot("W1", request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void legacyRejectsPublishedOutboundPlanning() {
|
||||
WarehouseApplicationService applicationService = mock(WarehouseApplicationService.class);
|
||||
AlgorithmProperties properties = new AlgorithmProperties();
|
||||
properties.setMode(SchedulingMode.LEGACY);
|
||||
SchedulingFacade facade = new SchedulingFacade(applicationService, properties);
|
||||
OutboundRequest outboundRequest = new OutboundRequest("O-STABLE", null, "P", null,
|
||||
"OFF", null, 1, true);
|
||||
|
||||
assertThatThrownBy(() -> facade.planOutboundFromPublishedSnapshot("W1", outboundRequest))
|
||||
.hasMessageContaining("disabled in LEGACY mode");
|
||||
}
|
||||
}
|
||||
@@ -95,6 +95,31 @@ class WarehouseApplicationServiceTest {
|
||||
order.verify(repository).loadPolicy("W1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void publishedInboundReadsSnapshotWithoutRefreshingChangedLanes() {
|
||||
when(repository.pageCandidateLanes("W1", null, 100)).thenReturn(new LanePage(List.of(), null));
|
||||
|
||||
service.planInboundFromPublishedSnapshot("W1", inbound("I-STABLE"));
|
||||
|
||||
verify(repository, never()).refreshChangedLanes(any());
|
||||
verify(repository).loadPolicy("W1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void publishedOutboundReadsSnapshotWithoutRefreshingChangedLanes() {
|
||||
OutboundRequest outboundRequest = new OutboundRequest("O-STABLE", null, "P", null,
|
||||
"OFF", null, 1, true);
|
||||
when(repository.searchOutboundStock("W1",
|
||||
com.ruoyi.algorithm.repository.OutboundStockSearch.project("P", null))).thenReturn(List.of());
|
||||
when(repository.loadLaneSnapshots("W1", List.of())).thenReturn(List.of());
|
||||
when(repository.loadRelocationBuffers("W1", Set.of())).thenReturn(List.of());
|
||||
|
||||
service.planOutboundFromPublishedSnapshot("W1", outboundRequest);
|
||||
|
||||
verify(repository, never()).refreshChangedLanes(any());
|
||||
verify(repository).searchOutboundStock(eq("W1"), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void inboundDelegatesToPlannerLogsReadyAndNeverReservesDuringPlanning() {
|
||||
VersionToken version = VersionToken.numeric(7);
|
||||
|
||||
Reference in New Issue
Block a user