From 40475388e1a81c9da0ad49d3755f84ce4b8ec668 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Wed, 4 Nov 2026 13:55:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=A7=81=E4=BA=BA=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E6=8C=89=E5=AE=9E=E9=99=85=E6=94=B6=E8=B4=A7=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=BA=93=E5=AD=98=E5=87=AD=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/InboundStockReceiptService.java | 3 +- .../InboundStockReceiptServiceTest.java | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/InboundStockReceiptService.java b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/InboundStockReceiptService.java index d656b34c0..bf71bc5dc 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/InboundStockReceiptService.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/InboundStockReceiptService.java @@ -273,7 +273,8 @@ public class InboundStockReceiptService { throw conflict("Stock-in requires picked packages and an assigned warehouse pallet"); } String destinationCode = first(line.getDestinationWarehouseCode(), order.getFbaWarehouseCode()); - if (destinationCode == null && trim(line.getDestinationWarehouseId()) == null) { + if (destinationCode == null && trim(line.getDestinationWarehouseId()) == null + && (!"OVERSEAS".equals(line.getDestinationType()) || trim(line.getDestinationWarehouseName()) == null)) { throw conflict("Destination warehouse ID or code is required for stock-in"); } if (destinationCode == null) destinationCode = ""; diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/InboundStockReceiptServiceTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/InboundStockReceiptServiceTest.java index 5422fd790..2a783e272 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/InboundStockReceiptServiceTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/InboundStockReceiptServiceTest.java @@ -26,6 +26,8 @@ import com.baiyue.lastleg.dropship.model.DropshipPalletSnapshot; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -37,6 +39,7 @@ import java.time.LocalDateTime; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; @@ -202,6 +205,55 @@ class InboundStockReceiptServiceTest { assertEquals(2001L, request.getValue().palletId()); } + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void privateAddressStocksActualCartonsWithoutAMasterDestinationWarehouse(boolean allowPartial) { + Fixture fixture = fixture(allowPartial ? 4 : 1, 1, 1, allowPartial ? 4 : 1); + fixture.line.setDestinationType("OVERSEAS"); + fixture.line.setDestinationWarehouseId(null); + fixture.line.setDestinationWarehouseCode(null); + fixture.line.setDestinationWarehouseName("私人地址 A"); + fixture.order.setDestinationType("OVERSEAS"); + fixture.order.setFbaWarehouseCode(null); + when(orders.selectBatchIds(any())).thenReturn(List.of(fixture.order)); + when(workflowRepository.cartons(1L)).thenReturn(List.of(receivedCarton(1L, fixture.pallet, "SKU-1"))); + when(inventory.stockIn(eq("100"), eq("operator"), any(InventoryCommandRequests.StockIn.class))) + .thenReturn(new InventoryCommandResponse(8L, "STOCK_IN", 9L, 10L, 1, 0, 0, 0, false, false)); + + service.stockIn("100", fixture.plan, fixture.task, List.of(fixture.line), + List.of(fixture.allocation), List.of(fixture.pallet), LocalDateTime.now(), allowPartial); + + ArgumentCaptor request = ArgumentCaptor.forClass(InventoryCommandRequests.StockIn.class); + verify(inventory).stockIn(eq("100"), eq("operator"), request.capture()); + assertNull(request.getValue().destinationWarehouseId()); + assertEquals("", request.getValue().destinationWarehouseCode()); + assertEquals("私人地址 A", request.getValue().destinationWarehouseName()); + assertEquals("900", request.getValue().overseasWarehouseId()); + assertEquals(2001L, request.getValue().palletId()); + assertEquals(1L, request.getValue().packages()); + verify(receipts).insert(any(InboundStockReceipt.class)); + } + + @Test + void privateAddressCannotStockInWithoutANamedDestination() { + Fixture fixture = fixture(1, 1, 1, 1); + fixture.line.setDestinationType("OVERSEAS"); + fixture.line.setDestinationWarehouseId(null); + fixture.line.setDestinationWarehouseCode(null); + fixture.line.setDestinationWarehouseName(" "); + fixture.order.setFbaWarehouseCode(null); + when(orders.selectBatchIds(any())).thenReturn(List.of(fixture.order)); + when(workflowRepository.cartons(1L)).thenReturn(List.of(receivedCarton(1L, fixture.pallet, "SKU-1"))); + + ResponseStatusException failure = assertThrows(ResponseStatusException.class, + () -> service.stockIn("100", fixture.plan, fixture.task, List.of(fixture.line), + List.of(fixture.allocation), List.of(fixture.pallet), LocalDateTime.now())); + + assertEquals("Destination warehouse ID or code is required for stock-in", failure.getReason()); + verify(inventory, never()).stockIn(any(), any(), any()); + verify(receipts, never()).insert(any(InboundStockReceipt.class)); + } + /** 同票现场调整打托后,两种 SKU 的实托归属仍由箱码决定。 */ @Test void overseasCompleteReceiptKeepsReversedSkuPalletAssignments() {