From 1e66fc6c226d613b7a7b7915908c7ab06f56ba4e Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Wed, 9 Sep 2026 19:07:13 +0800 Subject: [PATCH] fix: enforce dropship whole-pallet receiving --- .../pda/service/ReceivingContainerService.java | 3 +++ .../ReceivingContainerServiceBehaviorTest.java | 16 ++++++++++++++++ ...nbound-measurement-box-code-contract.test.mjs | 1 + .../inbound-measurement.mjs | 4 ++-- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/ReceivingContainerService.java b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/ReceivingContainerService.java index 741d5eeae..84c787670 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/ReceivingContainerService.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/service/ReceivingContainerService.java @@ -289,6 +289,9 @@ public class ReceivingContainerService { ReceivingContainerSession session = requireSigned(operatorKey); String customerId = session.getCustomerId(); InboundRef ref = requireInbound(customerId, session.getContainerNo(), request.inboundCode()); + if ("ONE_CLICK_DROPSHIP".equals(ref.order().getOrderType())) { + throw conflict("One-click dropship inbound must be operated by complete source pallet"); + } if (!"FBA".equals(destinationType(ref.line(), ref.order()))) { throw conflict("OVERSEAS destination must use carton-by-carton scanning; bulk count is forbidden"); } diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/ReceivingContainerServiceBehaviorTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/ReceivingContainerServiceBehaviorTest.java index 2209e5f16..2d65eb5a1 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/ReceivingContainerServiceBehaviorTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/service/ReceivingContainerServiceBehaviorTest.java @@ -364,6 +364,22 @@ class ReceivingContainerServiceBehaviorTest { verifyNoInteractions(warehouse); } + @Test + void dropshipFbaBulkReceiveIsRejectedBeforeWarehouseCalls() { + stubCurrent("FBA", "CONT-A"); + LastlegOrder dropshipOrder = order("FBA"); + dropshipOrder.setOrderType("ONE_CLICK_DROPSHIP"); + when(orders.selectById(1L)).thenReturn(dropshipOrder); + + assertThatThrownBy(() -> service.receiveBulk("7", "receiver", + new ReceivingContainerRequests.BulkReceive("IN-1", "PAL-1", 1, "dropship-bulk-key"))) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("complete source pallet"); + + verifyNoInteractions(warehouse); + verifyNoInteractions(workflow); + } + @Test void crossContainerCartonAndMismatchedPalletAreRejectedBeforeReservation() { stubCurrent("OVERSEAS", "CONT-A"); diff --git a/scripts/admin-test-env-modules/inbound-measurement-box-code-contract.test.mjs b/scripts/admin-test-env-modules/inbound-measurement-box-code-contract.test.mjs index 40c1a906d..53f5a01c9 100644 --- a/scripts/admin-test-env-modules/inbound-measurement-box-code-contract.test.mjs +++ b/scripts/admin-test-env-modules/inbound-measurement-box-code-contract.test.mjs @@ -177,6 +177,7 @@ async function exerciseSystemPalletScenario(fault = '') { } const sealed = await completeDropshipPalletization(context, { inboundId: '82', inboundCode: 'CODE', warehouseId: '83', measurement: { actualPackageCount: 2 } }) assert.deepEqual(sealed.sealedCartonMarks, ['CODE#2-1', 'CODE#2-2']) + assert.deepEqual(sealed.sealedSourcePalletNos, ['DP-260909-0001']) return checks } diff --git a/scripts/admin-test-env-modules/inbound-measurement.mjs b/scripts/admin-test-env-modules/inbound-measurement.mjs index 5d24a901b..403c03a5e 100644 --- a/scripts/admin-test-env-modules/inbound-measurement.mjs +++ b/scripts/admin-test-env-modules/inbound-measurement.mjs @@ -257,7 +257,7 @@ export async function completeDropshipPalletization(context, { inboundId, inboun context.assert(MODULE, '完成后重放不重开任务或新建空托', sealedReplayResponse, sealedReplay?.taskStatus === 'COMPLETED' && palletSnapshot(sealedReplay) === palletSnapshot(sealed), `taskStatus=${sealedReplay?.taskStatus || 'missing'}, palletNo=${palletNo}`, OPTIONS) - return { ...sealed, sealedCartonMarks } + return { ...sealed, sealedCartonMarks, sealedSourcePalletNos: [palletNo] } } async function provisionWarehouseResources(context, { inboundId, tenantId, warehouseId, palletCount }) { @@ -1074,7 +1074,7 @@ export async function run(context) { }) sealedCartonMarks = sealed?.taskStatus === 'COMPLETED' ? sealed.sealedCartonMarks : [] sealedSourcePalletNos = sealed?.taskStatus === 'COMPLETED' - ? (sealed.pallets || []).map((item) => item?.palletNo).filter(Boolean) : [] + ? (sealed.sealedSourcePalletNos || []).filter(Boolean) : [] completed = await waitForCompletedMeasurement(context, measurementPath, ['WAIT_SPLIT'], 10) finalResponse = completed.response finalMeasurement = context.apiSuccess(MODULE, '合托后回查一件代发入仓单', finalResponse,