From 390862b2dd9d9e163cff108422cd21dba04c90f2 Mon Sep 17 00:00:00 2001 From: zhouz <> Date: Wed, 22 Jul 2026 16:05:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8=E9=94=81=E5=AE=9A?= =?UTF-8?q?=E5=BA=93=E5=AD=98=E5=BF=AB=E7=85=A7=E4=BF=9D=E5=AD=98=E5=87=BA?= =?UTF-8?q?=E5=BA=93=E6=98=8E=E7=BB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iostorinv/IostorInvServiceImpl.java | 24 ++++++++++--------- .../IostorInvServiceLocalSpringTest.java | 14 ++++++++--- .../sql/iostorinv/create-outbound.sql | 4 ++-- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImpl.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImpl.java index 028633bc..f77aac66 100644 --- a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImpl.java +++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImpl.java @@ -54,7 +54,7 @@ public class IostorInvServiceImpl implements IostorInvService { @Override @Transactional(rollbackFor = Exception.class) public String createOutbound(IostorInvCreateReqVO reqVO) { - validateAndLockInventory(reqVO); + Map inventorySnapshot = validateAndLockInventory(reqVO); String ruleCode = "IO_CODE"; CodeGenerateReqDTO codeGenerateReqDTO = new CodeGenerateReqDTO(); @@ -95,24 +95,25 @@ public class IostorInvServiceImpl implements IostorInvService { detailDO.setIostorinvdtlId(IdUtil.fastSimpleUUID()); detailDO.setIostorinvId(iostorInv.getIostorinvId()); detailDO.setSeqNo(index + 1); - detailDO.setMaterialCode(detail.getMaterialCode()); - detailDO.setMaterialId(detail.getMaterialId()); - detailDO.setPcsn(detail.getPcsn()); + AvailableInventoryRespVO inventory = inventorySnapshot.get(detail.getGroupId()); + detailDO.setMaterialCode(inventory == null ? detail.getMaterialCode() : inventory.getMaterialCode()); + detailDO.setMaterialId(inventory == null ? detail.getMaterialId() : inventory.getMaterialId()); + detailDO.setPcsn(inventory == null ? detail.getPcsn() : inventory.getPcsn()); detailDO.setPlanQty(detail.getPlanQty()); detailDO.setUnassignQty(detail.getPlanQty()); detailDO.setAssignQty(BigDecimal.ZERO); - detailDO.setQtyUnitId(detail.getQtyUnitId()); - detailDO.setQtyUnitName(detail.getQtyUnitName()); - detailDO.setSourceBillCode(detail.getSourceBillCode()); - detailDO.setSourceBillType(detail.getSourceBillType()); - detailDO.setSourceBilldtlId(detail.getSourceBilldtlId()); + detailDO.setQtyUnitId(inventory == null ? detail.getQtyUnitId() : inventory.getQtyUnitId()); + detailDO.setQtyUnitName(inventory == null ? detail.getQtyUnitName() : inventory.getQtyUnitName()); + detailDO.setSourceBillCode(inventory == null ? detail.getSourceBillCode() : inventory.getExtCode()); + detailDO.setSourceBillType(inventory == null ? detail.getSourceBillType() : inventory.getExtType()); + detailDO.setSourceBilldtlId(inventory == null ? detail.getSourceBilldtlId() : inventory.getExtDtlCode()); detailDO.setRemark(detail.getRemark()); iostorinvDtlMapper.insert(detailDO); } return iostorInv.getIostorinvId(); } - private void validateAndLockInventory(IostorInvCreateReqVO reqVO) { + private Map validateAndLockInventory(IostorInvCreateReqVO reqVO) { List inventoryDetails = new ArrayList<>(); Set requestedGroupIds = new HashSet<>(); Set vehicleCodes = new LinkedHashSet<>(); @@ -132,7 +133,7 @@ public class IostorInvServiceImpl implements IostorInvService { vehicleCodes.add(detail.getVehicleCode()); } if (inventoryDetails.isEmpty()) { - return; + return Collections.emptyMap(); } List lockedRows = @@ -158,6 +159,7 @@ public class IostorInvServiceImpl implements IostorInvService { } } // 建单仅验证库存快照;库存占用和冻结数量由后续分配流程处理。 + return lockedByGroupId; } @Override diff --git a/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceLocalSpringTest.java b/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceLocalSpringTest.java index 63ef240d..37f76725 100644 --- a/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceLocalSpringTest.java +++ b/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceLocalSpringTest.java @@ -63,7 +63,7 @@ class IostorInvServiceLocalSpringTest { } @Test - void shouldCreateOutboundHeaderAndDetailsInOneTransaction() { + void shouldCreateOutboundUsingLockedInventoryIdentityInsteadOfClientUnitAndSource() { String id = iostorInvService.createOutbound(buildRequest()); assertNotNull(id); @@ -101,10 +101,10 @@ class IostorInvServiceLocalSpringTest { assertEquals(id, details.get(1).headerId()); assertEquals(new DetailRow(details.get(0).detailId(), id, 1, "MAT-01", "MID-01", "PCSN-01", new BigDecimal("12.500"), BigDecimal.ZERO.setScale(3), new BigDecimal("12.500"), - "KG", "千克", "SRC-01", "ORDER", "SRC-DTL-01", "明细一"), details.get(0)); + "DB-KG", "数据库千克", "DB-SRC-01", "DB-TYPE", "DB-DTL-01", "明细一"), details.get(0)); assertEquals(new DetailRow(details.get(1).detailId(), id, 2, "MAT-02", "MID-02", "PCSN-02", new BigDecimal("7.250"), BigDecimal.ZERO.setScale(3), new BigDecimal("7.250"), - "KG", "千克", "SRC-02", "ORDER", "SRC-DTL-02", "明细二"), details.get(1)); + "DB-KG", "数据库千克", "DB-SRC-02", "DB-TYPE", "DB-DTL-02", "明细二"), details.get(1)); } @Test @@ -200,6 +200,14 @@ class IostorInvServiceLocalSpringTest { assertInventoryRejected(buildRequest()); } + @Test + void shouldRejectInventoryChangedToPartiallyFrozenBelowRequestedQuantity() { + jdbcTemplate.update("UPDATE wms_group_plate SET qty = 10, frozen_qty = 6 WHERE group_id = 101"); + IostorInvCreateReqVO request = buildRequest(); + request.getDetails().get(0).setPlanQty(new BigDecimal("5")); + assertInventoryRejected(request); + } + private void assertInventoryRejected(IostorInvCreateReqVO request) { ServiceException ex = assertThrows(ServiceException.class, () -> iostorInvService.createOutbound(request)); assertEquals("出库库存已变化,请刷新后重新选择完整箱库存", ex.getMessage()); diff --git a/nl-module-wms/nl-module-wms-server/src/test/resources/sql/iostorinv/create-outbound.sql b/nl-module-wms/nl-module-wms-server/src/test/resources/sql/iostorinv/create-outbound.sql index fa130195..2d00a69e 100644 --- a/nl-module-wms/nl-module-wms-server/src/test/resources/sql/iostorinv/create-outbound.sql +++ b/nl-module-wms/nl-module-wms-server/src/test/resources/sql/iostorinv/create-outbound.sql @@ -32,6 +32,6 @@ CREATE TABLE wms_group_plate (group_id BIGINT PRIMARY KEY, vehicle_code VARCHAR( INSERT INTO base_materialbase VALUES ('MID-01','物料一',FALSE), ('MID-02','物料二',FALSE); INSERT INTO wms_structattr VALUES ('S1','BOX-01','STOR-01','S01','一号仓',FALSE), ('S2','BOX-02','STOR-01','S01','一号仓',FALSE), ('S3','BOX-X','STOR-02','S02','二号仓',FALSE); INSERT INTO wms_group_plate VALUES - (101,'BOX-01','可用','MID-01','MAT-01','PCSN-01',12.500,NULL,'KG','千克',NULL,NULL,NULL,FALSE), - (102,'BOX-02','可用','MID-02','MAT-02','PCSN-02',8.000,0.750,'KG','千克',NULL,NULL,NULL,FALSE), + (101,'BOX-01','可用','MID-01','MAT-01','PCSN-01',12.500,NULL,'DB-KG','数据库千克','DB-SRC-01','DB-TYPE','DB-DTL-01',FALSE), + (102,'BOX-02','可用','MID-02','MAT-02','PCSN-02',8.000,0.750,'DB-KG','数据库千克','DB-SRC-02','DB-TYPE','DB-DTL-02',FALSE), (103,'BOX-X','可用','MID-01','MAT-01','PCSN-X',5.000,0,'KG','千克',NULL,NULL,NULL,FALSE);