This commit is contained in:
2026-09-18 09:59:07 +08:00
parent 13a8dde0a5
commit 4f59f7bd28
45 changed files with 358 additions and 157 deletions
@@ -12,6 +12,7 @@ import com.baiyue.lastleg.mapper.LastlegOrderManualNodeHistoryMapper;
import com.baiyue.lastleg.mapper.LastlegOrderManualNodeMapper;
import com.baiyue.lastleg.mapper.LastlegOrderMapper;
import com.baiyue.lastleg.mapper.LastlegOrderOperationLogMapper;
import com.baiyue.lastleg.inventory.command.service.InventoryCommandService;
import com.fasterxml.jackson.databind.json.JsonMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -48,6 +49,7 @@ class LastlegOrderCommandServiceTest {
@Mock LastlegOrderManualNodeHistoryMapper manualNodeHistory;
@Mock LastlegOrderOperationLogMapper operationLogs;
@Mock InboundOrderDetainedOutboxService detainedOutbox;
@Mock InventoryCommandService inventory;
LastlegOrderCommandService service;
@BeforeEach
@@ -60,12 +62,14 @@ class LastlegOrderCommandServiceTest {
ReflectionTestUtils.setField(service, "manualNodeHistory", manualNodeHistory);
ReflectionTestUtils.setField(service, "operationLogs", operationLogs);
ReflectionTestUtils.setField(service, "detainedOutbox", detainedOutbox);
ReflectionTestUtils.setField(service, "inventory", inventory);
ReflectionTestUtils.setField(service, "objectMapper", JsonMapper.builder().findAndAddModules().build());
}
@Test
void holdsOnlySelectedOrderWithVersionAndImmutableHistory() {
LastlegOrder order = order(11L, 3);
order.setCurrentStatus("INBOUND_COMPLETED");
when(orders.selectById(11L)).thenReturn(order);
when(orders.lockById("100", 11L)).thenReturn(order);
when(orders.updateHold(eq("100"), eq(11L), eq(true), eq(true), eq("海关查验"), eq(3),
@@ -80,9 +84,42 @@ class LastlegOrderCommandServiceTest {
verify(orders).updateHold(eq("100"), eq(11L), eq(true), eq(true), eq("海关查验"), eq(3), any());
verify(holdHistory).insert(any(LastlegOrderHoldHistory.class));
verify(commands).insert(any(LastlegOrderCommandRecord.class));
verify(inventory).holdInboundOrderInventory("100", "900", 11L, "LL-11", "海关查验");
verify(orders, never()).lockContainerOrders(any());
}
@Test
void releasingHoldMovesOrderInventoryBackToAvailable() {
LastlegOrder order = order(11L, 3);
order.setCurrentStatus("INBOUND_COMPLETED");
order.setDetained(true);
when(orders.selectById(11L)).thenReturn(order);
when(orders.lockById("100", 11L)).thenReturn(order);
when(orders.updateHold(eq("100"), eq(11L), eq(false), eq(false), eq("质检通过"), eq(3),
any(LocalDateTime.class))).thenReturn(1);
service.hold("100", 11L, "release-11",
new LastlegOrderCommandDtos.HoldRequest(false, false, "质检通过", 3), "900", "管理员");
verify(inventory).releaseInboundOrderHold("100", "900", 11L, "LL-11", "质检通过");
}
@Test
void rejectsNewHoldBeforeInboundCompletion() {
LastlegOrder order = order(11L, 3);
when(orders.selectById(11L)).thenReturn(order);
when(orders.lockById("100", 11L)).thenReturn(order);
ResponseStatusException error = assertThrows(ResponseStatusException.class, () -> service.hold("100", 11L,
"hold-before-inbound", new LastlegOrderCommandDtos.HoldRequest(true, false, "待入库", 3),
"900", "管理员"));
assertEquals(409, error.getStatusCode().value());
assertEquals("货物完成入库后才能暂扣", error.getReason());
verify(orders, never()).updateHold(anyString(), anyLong(), anyBoolean(), anyBoolean(),
nullable(String.class), anyInt(), any(LocalDateTime.class));
}
@Test
void rejectsStaleHoldWithoutAnyWrite() {
LastlegOrder order = order(11L, 4);
@@ -49,7 +49,6 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -69,7 +68,6 @@ class LastlegOrderServiceTest {
@Mock InboundPlanCartonMapper cartons;
@Mock FbaWarehouseValidator fbaWarehouses;
@Mock InventoryCommandService inventory;
@Mock InboundOrderDetainedOutboxService detainedOutbox;
@Mock ReceivingWarehouseOperationMapper receivingWarehouseOperations;
@Mock ContainerArrivalTimeOperationMapper containerArrivalTimeOperations;
@Mock WarehouseResourceGateway warehouseResourceGateway;
@@ -116,7 +114,6 @@ class LastlegOrderServiceTest {
Long.parseLong(invocation.getArgument(0)), invocation.getArgument(1), invocation.getArgument(2),
"US", "CA"));
ReflectionTestUtils.setField(service, "inventory", inventory);
ReflectionTestUtils.setField(service, "detainedOutbox", detainedOutbox);
ReflectionTestUtils.setField(service, "receivingWarehouseOperations", receivingWarehouseOperations);
ReflectionTestUtils.setField(service, "containerArrivalTimeOperations", containerArrivalTimeOperations);
ReflectionTestUtils.setField(service, "warehouseResourceGateway", warehouseResourceGateway);
@@ -559,40 +556,6 @@ class LastlegOrderServiceTest {
assertEquals("NYEXX2609060063", result.records().get(2).inboundCode());
}
@Test
void holdingBeforeInboundPersistsTheOrderMarkerAndOperationRemark() {
LastlegOrder order = order(11L, "100", "PENDING_INBOUND", null);
when(orders.selectOne(any())).thenReturn(order);
when(orders.lockById("100", 11L)).thenReturn(order);
service.setDetained("100", 11L, new LastlegOrderRequests.SetDetained(true, "等待质检"), "operator");
assertTrue(order.getDetained());
verify(orders).updateById(order);
ArgumentCaptor<com.baiyue.lastleg.entity.LastlegOrderOperationLog> operation =
ArgumentCaptor.forClass(com.baiyue.lastleg.entity.LastlegOrderOperationLog.class);
verify(operations).insert(operation.capture());
assertEquals("暂扣", operation.getValue().getOperationNode());
assertEquals("等待质检", operation.getValue().getResult());
verify(detainedOutbox).publish(eq(order), eq(true), eq("等待质检"), isNull(), eq("operator"), any(), anyLong());
verify(inventory, never()).releaseInboundOrderHold(any(), any(), anyLong(), any(), any());
}
@Test
void releasingAfterInboundMovesAllOrderHeldInventoryToAvailable() {
LastlegOrder order = order(11L, "100", "INBOUND_COMPLETED", "IP-1");
order.setOrderNo("LM-1");
order.setDetained(true);
when(orders.selectOne(any())).thenReturn(order);
when(orders.lockById("100", 11L)).thenReturn(order);
service.setDetained("100", 11L, new LastlegOrderRequests.SetDetained(false, "质检通过"), "operator");
verify(inventory).releaseInboundOrderHold("100", "operator", 11L, "LM-1", "质检通过");
assertEquals(false, order.getDetained());
verify(detainedOutbox).publish(eq(order), eq(false), eq("质检通过"), isNull(), eq("operator"), any(), anyLong());
}
private static LastlegOrder order(long id, String customerId, String status, String inboundOrderNo) {
LastlegOrder order = new LastlegOrder();
order.setId(id);