优化
This commit is contained in:
+21
-3
@@ -83,6 +83,9 @@ class InboundStockReceiptServiceTest {
|
||||
assertEquals(101L, request.getValue().inboundOrderId());
|
||||
assertEquals("IN-1", request.getValue().inboundCode());
|
||||
assertEquals("SKU-1", request.getValue().skuCode());
|
||||
assertEquals("Customer", request.getValue().customerName());
|
||||
assertEquals("900", request.getValue().overseasWarehouseId());
|
||||
assertEquals("Los Angeles", request.getValue().overseasWarehouseName());
|
||||
ArgumentCaptor<InboundStockReceipt> receipt = ArgumentCaptor.forClass(InboundStockReceipt.class);
|
||||
verify(receipts).insert(receipt.capture());
|
||||
assertEquals(5L, receipt.getValue().getReceivedPackages());
|
||||
@@ -210,16 +213,31 @@ class InboundStockReceiptServiceTest {
|
||||
assertEquals(10L, activationReceipts.getValue().get(0).getInventoryPositionId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsDomesticSourceWarehouseAsActualOverseasWarehouse() {
|
||||
Fixture fixture = fixture(5, 5, 5, 10);
|
||||
fixture.order.setOverseasWarehouseId(fixture.order.getSourceWarehouseId());
|
||||
fixture.plan.setOverseasWarehouseId(Long.valueOf(fixture.order.getSourceWarehouseId()));
|
||||
when(orders.selectBatchIds(any())).thenReturn(List.of(fixture.order));
|
||||
|
||||
assertThrows(ResponseStatusException.class, () -> service.stockIn("100", fixture.plan, fixture.task,
|
||||
List.of(fixture.line), List.of(fixture.allocation), List.of(fixture.pallet), LocalDateTime.now()));
|
||||
|
||||
verify(inventory, never()).stockIn(any(), any(), any());
|
||||
verify(receipts, never()).insert(any(InboundStockReceipt.class));
|
||||
}
|
||||
|
||||
private Fixture fixture(int required, int planned, int picked, int quantity) {
|
||||
InboundPlan plan = new InboundPlan(); plan.setId(1L); plan.setPlanNo("IP-1");
|
||||
InboundPlan plan = new InboundPlan(); plan.setId(1L); plan.setPlanNo("IP-1"); plan.setOverseasWarehouseId(900L);
|
||||
InboundPdaTask task = new InboundPdaTask(); task.setId(2L); task.setOperatorId("operator");
|
||||
InboundPlanLine line = new InboundPlanLine(); line.setId(12L); line.setPlanId(1L); line.setOrderId(101L);
|
||||
line.setInboundCode("IN-1"); line.setDestinationWarehouseId("WH-DEST");
|
||||
line.setDestinationWarehouseCode("ONT8"); line.setDestinationWarehouseName("ONT8");
|
||||
line.setRequiredPackageCount(required); line.setVolumeCbm(new BigDecimal("1.0"));
|
||||
LastlegOrder order = new LastlegOrder(); order.setId(101L); order.setCustomerId("100");
|
||||
order.setOrderNo("LMO-1"); order.setCustomerName("Customer"); order.setOverseasWarehouseId("OW-1");
|
||||
order.setOverseasWarehouseName("Warehouse"); order.setSourceEventId("evt-1"); order.setFbaWarehouseCode("ONT8");
|
||||
order.setOrderNo("LMO-1"); order.setCustomerName("Customer"); order.setSourceWarehouseId("100");
|
||||
order.setOverseasWarehouseId("900"); order.setOverseasWarehouseName("Los Angeles");
|
||||
order.setSourceEventId("evt-1"); order.setFbaWarehouseCode("ONT8");
|
||||
order.setCurrentStatus("INBOUND_PLANNED");
|
||||
org.mockito.Mockito.lenient().when(orders.lockById("100", 101L)).thenReturn(order);
|
||||
LastlegOrderDetail detail = detail(201L, "SKU-1", required, quantity);
|
||||
|
||||
+27
@@ -155,6 +155,33 @@ class ReceivingContainerServiceBehaviorTest {
|
||||
.containsExactly("CONT-A", "CONT-B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void candidatesHideContainersReservedByAnotherOperator() {
|
||||
InboundPlan available = plan("CONT-A");
|
||||
InboundPlan reserved = plan("CONT-B"); reserved.setId(3L);
|
||||
ReceivingContainerSession other = session("CONT-B", "WAIT_SIGN");
|
||||
other.setOperatorKey("8"); other.setActiveOperatorKey("OPERATOR:8");
|
||||
other.setActiveContainerKey("CONTAINER:CONT-B");
|
||||
when(plans.selectList(any())).thenReturn(List.of(available, reserved), List.of(available));
|
||||
when(lines.selectList(any())).thenReturn(List.of());
|
||||
when(sessions.findActiveContainers()).thenReturn(List.of(other));
|
||||
|
||||
assertThat(service.candidates("7", 100L)).extracting("containerNo").containsExactly("CONT-A");
|
||||
}
|
||||
|
||||
@Test
|
||||
void detailRejectsContainerReservedByAnotherOperator() {
|
||||
when(plans.selectList(any())).thenReturn(List.of(plan("CONT-B")));
|
||||
ReceivingContainerSession other = session("CONT-B", "SIGNED");
|
||||
other.setOperatorKey("8"); other.setActiveOperatorKey("OPERATOR:8");
|
||||
other.setActiveContainerKey("CONTAINER:CONT-B");
|
||||
when(sessions.findActiveByContainer("CONTAINER:CONT-B")).thenReturn(other);
|
||||
|
||||
assertThatThrownBy(() -> service.detail("7", 100L, "CONT-B"))
|
||||
.isInstanceOf(ResponseStatusException.class).hasMessageContaining("409");
|
||||
verifyNoInteractions(warehouse);
|
||||
}
|
||||
|
||||
@Test
|
||||
void waitSignSelectionAlreadyLocksAccountFromViewingAnotherContainer() {
|
||||
when(plans.selectList(any())).thenReturn(List.of(plan("CONT-B")));
|
||||
|
||||
+33
-2
@@ -72,8 +72,11 @@ class InventoryCommandServiceTest {
|
||||
verify(balances).updateById(balance.capture());
|
||||
assertEquals(12L, balance.getValue().getAvailablePackages());
|
||||
assertEquals("SKU-1", balance.getValue().getSkuCode());
|
||||
assertEquals("Customer 100", balance.getValue().getCustomerName());
|
||||
verify(positions).insert(any(InventoryPosition.class));
|
||||
verify(ledgers).insert(any(InventoryLedger.class));
|
||||
ArgumentCaptor<InventoryLedger> ledger = ArgumentCaptor.forClass(InventoryLedger.class);
|
||||
verify(ledgers).insert(ledger.capture());
|
||||
assertEquals("Customer 100", ledger.getValue().getCustomerName());
|
||||
verify(operations).updateById(any(InventoryOperation.class));
|
||||
}
|
||||
|
||||
@@ -152,6 +155,33 @@ class InventoryCommandServiceTest {
|
||||
verify(ledgers).insert(any(InventoryLedger.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void stockInRejectsMissingCustomerSnapshotBeforeInventoryMutation() {
|
||||
InventoryCommandRequests.StockIn request = new InventoryCommandRequests.StockIn(
|
||||
"100", null, "WH-1", "WH1", "Warehouse 1", "DEST-1", "ONT8", "ONT8",
|
||||
101L, "IN-1", "IN-CODE-1", "SKU-1", "Product 1", null, 300L, "PLT-1", null,
|
||||
null, null, 1, "ORD-1", "EVT-1", "missing-customer", null);
|
||||
|
||||
assertThrows(ResponseStatusException.class, () -> service.stockIn("100", "7", request));
|
||||
|
||||
verify(balances, never()).insert(any(InventoryBalance.class));
|
||||
verify(positions, never()).insert(any(InventoryPosition.class));
|
||||
verify(ledgers, never()).insert(any(InventoryLedger.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void stockInRejectsCustomerSnapshotDrift() {
|
||||
InventoryBalance balance = balance(200L, 4);
|
||||
balance.setCustomerName("Frozen customer");
|
||||
when(balances.lockDimension("100", "WH-1", "ONT8", 101L, "IN-CODE-1")).thenReturn(balance);
|
||||
|
||||
assertThrows(ResponseStatusException.class,
|
||||
() -> service.stockIn("100", "7", stockIn("IN-1", "customer-drift", 1, 1)));
|
||||
|
||||
verify(positions, never()).insert(any(InventoryPosition.class));
|
||||
verify(ledgers, never()).insert(any(InventoryLedger.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void holdRejectsWhenAvailablePackagesAreInsufficient() {
|
||||
InventoryBalance balance = balance(200L, 5);
|
||||
@@ -233,7 +263,8 @@ class InventoryCommandServiceTest {
|
||||
|
||||
private InventoryBalance balance(Long id, long available) {
|
||||
InventoryBalance value = new InventoryBalance();
|
||||
value.setId(id); value.setCustomerId("100"); value.setOverseasWarehouseId("WH-1");
|
||||
value.setId(id); value.setCustomerId("100"); value.setCustomerName("Customer 100");
|
||||
value.setOverseasWarehouseId("WH-1");
|
||||
value.setDestinationWarehouseCode("ONT8"); value.setInboundOrderId(101L);
|
||||
value.setInboundOrderNo("IN-1"); value.setInboundCode("IN-CODE-1");
|
||||
value.setAvailablePackages(available);
|
||||
|
||||
Reference in New Issue
Block a user