This commit is contained in:
2026-09-15 14:30:47 +08:00
parent a474ca4d93
commit d1a00b8e01
18 changed files with 141 additions and 30 deletions
@@ -31,6 +31,12 @@ class SmartDispatchOpenApiContractTest {
assertTrue(yaml.contains("platform:overseas-warehouse:inbound-order:smart-dispatch"));
assertTrue(yaml.contains("SmartDispatchPreArrange"));
assertTrue(yaml.contains("SmartDispatchCandidate"));
String preArrangeSchema = yaml.substring(yaml.indexOf(" SmartDispatchPreArrange:"),
yaml.indexOf(" SmartDispatchDraftPallet:"));
String updateSchema = yaml.substring(yaml.indexOf(" DispatchUpdate:"),
yaml.indexOf(" DeliveryTransfer:"));
assertFalse(preArrangeSchema.contains("route:"));
assertFalse(updateSchema.contains("route:"));
assertTrue(yaml.contains("name: planIds"));
String planIdsParameter = yaml.substring(yaml.indexOf("name: planIds"),
yaml.indexOf("name: orderNo", yaml.indexOf("name: planIds")));
@@ -53,7 +53,7 @@ class SmartDispatchControllerTest {
@Test
void preArrangeResolvesSingleCustomerAndAuthenticatedOperator() {
DispatchRequests.PreArrange request = new DispatchRequests.PreArrange(
List.of(10L, 11L), "ONT8 -> LAX9", "APT-1", "SUCCESS", "PENDING");
List.of(10L, 11L), "APT-1", "SUCCESS", "PENDING");
when(service.resolveCustomerScopeForPallets(List.of(10L, 11L))).thenReturn("100");
controller.preArrange(platform(), request);
@@ -101,6 +101,7 @@ class DispatchServiceTest {
assertNotNull(DispatchService.class.getMethod("preArrange", String.class, String.class,
DispatchRequests.PreArrange.class).getAnnotation(Transactional.class));
when(candidates.lockSelected("100", List.of(10L))).thenReturn(List.of(candidate(10L, null, "ONT8")));
when(items.findByDispatchOrder(eq("100"), any())).thenReturn(List.of(item(11L, "ONT8")));
var result = service.preArrange("100", "7", new DispatchRequests.PreArrange(List.of(10L), null,
null, null, null));
@@ -119,6 +120,22 @@ class DispatchServiceTest {
verify(items).insert(any(DispatchItem.class));
}
@Test
void preArrangeBuildsCommaSeparatedDistinctFbaRouteFromAssignedPallets() {
when(candidates.lockSelected("100", List.of(10L, 11L, 12L))).thenReturn(List.of(
candidate(10L, null, "ONT8"), candidate(11L, null, "ABE4"), candidate(12L, null, "ONT8")));
when(items.findByDispatchOrder(eq("100"), any())).thenReturn(List.of(
item(21L, "ONT8"), item(22L, "ABE4"), item(23L, "ONT8")));
DispatchResponse result = service.preArrange("100", "7",
new DispatchRequests.PreArrange(List.of(10L, 11L, 12L), null, null, null));
assertEquals("ONT8,ABE4", result.route());
ArgumentCaptor<DispatchOrder> dispatch = ArgumentCaptor.forClass(DispatchOrder.class);
verify(orders).insert(dispatch.capture());
assertEquals("ONT8,ABE4", dispatch.getValue().getRoute());
}
@Test
void movingPalletIntoDraftImmediatelyCreatesExpiringExclusiveLock() {
when(candidates.lockSelected("100", List.of(10L))).thenReturn(List.of(candidate(10L, null, "ONT8")));
@@ -197,7 +214,7 @@ class DispatchServiceTest {
when(locks.lockActive("100", "PLAN:10")).thenReturn(lock);
when(drafts.lockActive("draft-1", "7")).thenReturn(draft);
service.preArrange("100", "7", new DispatchRequests.PreArrange(List.of(10L), null, null, null, null, "draft-1"));
service.preArrange("100", "7", new DispatchRequests.PreArrange(List.of(10L), null, null, null, "draft-1"));
assertNotNull(lock.getDispatchOrderId());
assertEquals("draft-1", lock.getDraftToken());
@@ -326,13 +343,18 @@ class DispatchServiceTest {
dispatch.setId(1L); dispatch.setCustomerId("100"); dispatch.setDispatchNo("PC1");
dispatch.setStatus(DispatchService.PENDING_DEPARTURE);
when(orders.lockGlobalByDispatchNo("PC1")).thenReturn(dispatch);
DispatchRequests.Update request = new DispatchRequests.Update("ABC-1", "Driver", null, null, null,
DispatchItem ont8 = item(11L, "ONT8");
DispatchItem abe4 = item(12L, "ABE4");
when(items.findByDispatchOrder("100", 1L)).thenReturn(List.of(ont8, abe4, item(13L, "ONT8")));
DispatchRequests.Update request = new DispatchRequests.Update("ABC-1", "Driver", null, null,
null, null, null, LocalDateTime.now());
DispatchResponse result = service.update("PC1", request);
assertEquals(DispatchService.PENDING_DEPARTURE, dispatch.getStatus());
assertEquals("ABC-1", result.vehiclePlate());
assertEquals("ONT8,ABE4", result.route());
assertEquals("ONT8,ABE4", dispatch.getRoute());
verify(orders).updateById(dispatch);
verify(items).findByDispatchOrder("100", 1L);
}
@@ -343,7 +365,7 @@ class DispatchServiceTest {
dispatch.setId(1L); dispatch.setCustomerId("100"); dispatch.setDispatchNo("PC1");
dispatch.setStatus("DEPARTED");
when(orders.lockGlobalByDispatchNo("PC1")).thenReturn(dispatch);
DispatchRequests.Update request = new DispatchRequests.Update(null, null, null, null, null,
DispatchRequests.Update request = new DispatchRequests.Update(null, null, null, null,
null, null, null, null);
ResponseStatusException exception = assertThrows(ResponseStatusException.class,
@@ -442,4 +464,11 @@ class DispatchServiceTest {
"LIP1-P001", destination, destination, destination, destination, packageCount,
new BigDecimal("1.2000"), warehousePalletId == null ? "PLAN" : "RECEIVED");
}
private DispatchItem item(long id, String fbaWarehouseCode) {
DispatchItem item = new DispatchItem();
item.setId(id);
item.setFbaWarehouseCode(fbaWarehouseCode);
return item;
}
}