From 660e284e2515f1180b22dc87152e6912e7b80ec3 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Fri, 4 Sep 2026 13:28:57 +0800 Subject: [PATCH] fix: reserve pallet block from declared volume --- .../MeasurementLocationOccupationService.java | 13 ++++++---- ...surementLocationOccupationServiceTest.java | 24 +++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/firstleg/src/main/java/com/baiyue/firstleg/service/MeasurementLocationOccupationService.java b/firstleg/src/main/java/com/baiyue/firstleg/service/MeasurementLocationOccupationService.java index 940f8b1b7..1d7ce7f44 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/service/MeasurementLocationOccupationService.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/service/MeasurementLocationOccupationService.java @@ -40,7 +40,7 @@ public class MeasurementLocationOccupationService { long weightResultId, int weightVersion) { InboundOrderEntity order = requireOrder(tenantId, inboundId); long warehouseId = requireWarehouse(order); - BigDecimal volume = requireVolume(order); + BigDecimal volume = requireVolume(tenantId, inboundId, order); var confirmedWeights = confirmedWeights(tenantId, inboundId); int requiredSlotCount = requiredSlotCount(volume, confirmedWeights.size()); int packageCount = requirePackageCount(order); @@ -95,7 +95,7 @@ public class MeasurementLocationOccupationService { InboundOrderEntity order = requireOrder(tenantId, inboundId); long warehouseId = requireWarehouse(order); var confirmedWeights = confirmedWeights(tenantId, inboundId); - int requiredSlotCount = requiredSlotCount(requireVolume(order), confirmedWeights.size()); + int requiredSlotCount = requiredSlotCount(requireVolume(tenantId, inboundId, order), confirmedWeights.size()); var current = allocations.list(tenantId, inboundId); requireActiveBlock(current, warehouseId); if (current.size() < requiredSlotCount) { @@ -166,9 +166,14 @@ public class MeasurementLocationOccupationService { return order.getWarehouseId(); } - private static BigDecimal requireVolume(InboundOrderEntity order) { + private BigDecimal requireVolume(long tenantId, long inboundId, InboundOrderEntity order) { + var measurement = measurements.findLatestMeasurement(tenantId, inboundId); + if (measurement != null && measurement.getOriginalVolumeCbm() != null + && measurement.getOriginalVolumeCbm().signum() > 0) { + return measurement.getOriginalVolumeCbm(); + } if (order.getActualVolumeCbm() == null || order.getActualVolumeCbm().signum() <= 0) { - throw new BizException(ResultCode.CONFLICT, "入库单缺少有效实测体积"); + throw new BizException(ResultCode.CONFLICT, "入库单缺少有效客户申报体积"); } return order.getActualVolumeCbm(); } diff --git a/firstleg/src/test/java/com/baiyue/firstleg/service/MeasurementLocationOccupationServiceTest.java b/firstleg/src/test/java/com/baiyue/firstleg/service/MeasurementLocationOccupationServiceTest.java index adbd31d79..b51217813 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/service/MeasurementLocationOccupationServiceTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/service/MeasurementLocationOccupationServiceTest.java @@ -5,6 +5,7 @@ import com.baiyue.common.core.exception.BizException; import com.baiyue.firstleg.client.WarehousePalletLocationClient; import com.baiyue.firstleg.config.InboundProperties; import com.baiyue.firstleg.entity.InboundOrderEntity; +import com.baiyue.firstleg.entity.InboundMeasurementEntity; import com.baiyue.firstleg.entity.InboundWeightResultEntity; import com.baiyue.firstleg.repository.InboundMeasurementRepository; import com.baiyue.firstleg.repository.InboundPalletAllocationRepository; @@ -136,6 +137,29 @@ class MeasurementLocationOccupationServiceTest { verify(allocations).bindConfirmedWeights(BUSINESS_TENANT, INBOUND, twoWeights); } + @Test + void reservesByCustomerDeclaredVolumeBeforeMeasuredVolumeIsFrozen() { + InboundOrderEntity inbound = inbound(); + inbound.setActualVolumeCbm(null); + InboundMeasurementEntity measurement = new InboundMeasurementEntity(); + measurement.setOriginalVolumeCbm(new BigDecimal("2.5000")); + when(workflow.findOwned(BUSINESS_TENANT, INBOUND)).thenReturn(inbound); + when(measurements.findLatestMeasurement(BUSINESS_TENANT, INBOUND)).thenReturn(measurement); + when(measurements.listWeights(BUSINESS_TENANT, INBOUND)) + .thenReturn(confirmedWeights().subList(0, 2)); + when(warehouse.reserveBlock(org.mockito.ArgumentMatchers.eq("internal-token"), + org.mockito.ArgumentMatchers.any())).thenReturn(ApiResponse.success(block("RESERVED", 3))); + when(warehouse.confirmBlock(org.mockito.ArgumentMatchers.eq("internal-token"), + org.mockito.ArgumentMatchers.any())).thenReturn(ApiResponse.success(block("OCCUPIED", 3))); + + service.ensureForConfirmedWeight(BUSINESS_TENANT, INBOUND, OPERATOR, MEASUREMENT, 3); + + verify(warehouse).reserveBlock(org.mockito.ArgumentMatchers.eq("internal-token"), + org.mockito.ArgumentMatchers.argThat(request -> request.requiredSlotCount() == 3)); + verify(allocations).replaceBlock(BUSINESS_TENANT, INBOUND, WAREHOUSE, + 20, new BigDecimal("2.5000"), block("OCCUPIED", 3)); + } + @Test void rejectsConfirmedWeightWithoutConfirmationTimeInsteadOfDroppingIt() { InboundWeightResultEntity weight = confirmedWeights().get(0);