From fdb70db6f610f21c8604a8a8cec0230dea4d8ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E9=B8=BF=E5=B1=95?= <18031053041@163.com> Date: Wed, 15 Apr 2026 10:06:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E6=9E=B6=E6=95=B0=E9=87=8F=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StockShelfOrderApplicationService.java | 52 +++++++++++++----- .../ReceiptMaterialDetailImpl.java | 55 +++++++++++++++---- 2 files changed, 81 insertions(+), 26 deletions(-) diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockShelfOrder/StockShelfOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockShelfOrder/StockShelfOrderApplicationService.java index 21906dc2e..5f17c83ab 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockShelfOrder/StockShelfOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockShelfOrder/StockShelfOrderApplicationService.java @@ -522,8 +522,8 @@ public class StockShelfOrderApplicationService { } /** - * 扁平化明细:主行保留父子结构;展示「已上架」= 主行累计 + 各子行累计(不含 parent_copy 镜像行,避免与主行重复)。 - * 上架状态按「汇总已上架 qtySum」与主行计划量比较推导,与域服务分批/完成上架的 1/2/3/4/5 含义一致。 + * 扁平化明细:主行保留父子结构;主行「已上架数量」与上架状态仍按主行+子行汇总(与分批场景一致)。 + * 主行净重/毛重/体积/面积不再用主+子汇总覆盖,保留库表主行单行值(子行仍为自身行明细)。 * * @param shelfOrderCompleted 上架单是否已整单完成(status=3);为 true 时少上为 4,与域服务完成口径一致 */ @@ -553,17 +553,9 @@ public class StockShelfOrderApplicationService { continue; } BigDecimal qtySum = sumAlreadyShelvesUnderPlanParent(parent, allNodes); - BigDecimal netSum = sumAlreadyShelfMetricUnderPlanParent(parent, allNodes, ShelfMaterialDetailPO::getAlreadyShelvesNetWeight); - BigDecimal grossSum = sumAlreadyShelfMetricUnderPlanParent(parent, allNodes, ShelfMaterialDetailPO::getAlreadyShelvesGrossWeight); - BigDecimal volSum = sumAlreadyShelfMetricUnderPlanParent(parent, allNodes, ShelfMaterialDetailPO::getAlreadyShelvesVolume); - BigDecimal areaSum = sumAlreadyShelfMetricUnderPlanParent(parent, allNodes, ShelfMaterialDetailPO::getAlreadyShelvesArea); Integer derived = deriveShelfStatusFromAggregatedVsPlan(qtySum, parent.getQuantity(), shelfOrderCompleted); parent.setAlreadyShelvesQuantity(qtySum); - parent.setAlreadyShelvesNetWeight(netSum); - parent.setAlreadyShelvesGrossWeight(grossSum); - parent.setAlreadyShelvesVolume(volSum); - parent.setAlreadyShelvesArea(areaSum); if (derived != null) { parent.setShelvesStatus(derived); } @@ -724,6 +716,36 @@ public class StockShelfOrderApplicationService { return sum; } + /** + * 计划主行维度累计(重量/体面积):主行库表单行 + 树下 level=2 子行。 + * 待上架展示用「计划 − 已上架」时,子行需按整卡扣减;主行接口字段不再汇总后仍用此合计参与计算。 + */ + private static BigDecimal sumShelfPlanRowAggregatedAlreadyMetric(ShelfMaterialDetailPO planParent, + Function alreadyGetter) { + if (planParent == null || alreadyGetter == null) { + return BigDecimal.ZERO; + } + BigDecimal base = alreadyGetter.apply(planParent); + BigDecimal sum = base != null ? base : BigDecimal.ZERO; + List ch = planParent.getChildren(); + if (CollectionUtils.isEmpty(ch)) { + return sum; + } + for (ShelfMaterialDetailPO c : ch) { + if (c == null || c.getLevel() == null || c.getLevel() != 2) { + continue; + } + if (planParent.getUniqueId() != null && planParent.getUniqueId().equals(c.getUniqueId())) { + continue; + } + BigDecimal v = alreadyGetter.apply(c); + if (v != null) { + sum = sum.add(v); + } + } + return sum; + } + /** 计划父行:level=1 自身;level=2 则按 parent_unique_id 定位主计划行(对齐收货 {@code resolveReceiptPlanParentRow}) */ private static ShelfMaterialDetailPO resolveShelfPlanParentRow(ShelfMaterialDetailPO db, List dbList) { @@ -1072,12 +1094,12 @@ public class StockShelfOrderApplicationService { BigDecimal alreadyVol = d.getAlreadyShelvesVolume() != null ? d.getAlreadyShelvesVolume() : BigDecimal.ZERO; BigDecimal alreadyArea = d.getAlreadyShelvesArea() != null ? d.getAlreadyShelvesArea() : BigDecimal.ZERO; - // level=2 子行:与收货一致,用计划主行汇总后的累计已上架(flatten 后主行已为主+子合计) + // level=2 子行:计划为整张卡;已上架量用主行+子行 DB 累计之和(主行自身字段不再汇总时仍按整卡扣计划) if (planParent != null && d.getLevel() != null && d.getLevel() == 2) { - alreadyNet = planParent.getAlreadyShelvesNetWeight() != null ? planParent.getAlreadyShelvesNetWeight() : BigDecimal.ZERO; - alreadyGross = planParent.getAlreadyShelvesGrossWeight() != null ? planParent.getAlreadyShelvesGrossWeight() : BigDecimal.ZERO; - alreadyVol = planParent.getAlreadyShelvesVolume() != null ? planParent.getAlreadyShelvesVolume() : BigDecimal.ZERO; - alreadyArea = planParent.getAlreadyShelvesArea() != null ? planParent.getAlreadyShelvesArea() : BigDecimal.ZERO; + alreadyNet = sumShelfPlanRowAggregatedAlreadyMetric(planParent, ShelfMaterialDetailPO::getAlreadyShelvesNetWeight); + alreadyGross = sumShelfPlanRowAggregatedAlreadyMetric(planParent, ShelfMaterialDetailPO::getAlreadyShelvesGrossWeight); + alreadyVol = sumShelfPlanRowAggregatedAlreadyMetric(planParent, ShelfMaterialDetailPO::getAlreadyShelvesVolume); + alreadyArea = sumShelfPlanRowAggregatedAlreadyMetric(planParent, ShelfMaterialDetailPO::getAlreadyShelvesArea); } // 参考收货:只对「有计划值」的字段覆盖 total*,否则保留原 total* diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java index e6ba18b33..5fa17dd3b 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java @@ -407,6 +407,8 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl receiptMaterialDetailList = new ArrayList<>(); @@ -416,7 +418,7 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl children = receiptMaterialDetailDO.getChildren(); if (!CollectionUtils.isEmpty(children)) { for (ReceiptMaterialDetailDO child : children) { - generateAndValidateBatchNumber(child, shipperId); + generateAndValidateBatchNumber(child, shipperId, currentInOrderNumber); } } } @@ -1235,9 +1261,11 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl wrapper = new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() .eq(MaterialInventory::getShipperId, shipperId) .eq(MaterialInventory::getMaterialBaseInfoId, materialBaseInfoId) .eq(MaterialInventory::getBatchNumber, batchNumber) - .eq(MaterialInventory::getDelFlag, 1); + .eq(MaterialInventory::getDelFlag, 1) + .eq(MaterialInventory::getInOrderNumber, currentInOrderNumber); // 如果库存属性值不为空,需要精确匹配;如果为空,查询库存属性值为空或null的记录 if (materialStatusCode != null && !materialStatusCode.trim().isEmpty()) { wrapper.eq(MaterialInventory::getMaterialStatusCode, materialStatusCode); } else { - // 如果库存属性值为空,查询库存属性值为null或空字符串的记录 wrapper.and(w -> w.isNull(MaterialInventory::getMaterialStatusCode) .or() .eq(MaterialInventory::getMaterialStatusCode, "")); @@ -1274,12 +1306,13 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl existingInventoryList = materialInventoryMapper.selectList(wrapper); - // 如果存在相同的货主+商品+库存属性值+批次号的记录,抛出异常 if (!CollectionUtils.isEmpty(existingInventoryList)) { String statusCodeDesc = (materialStatusCode != null && !materialStatusCode.trim().isEmpty()) ? ",库存属性值:" + materialStatusCode : ",库存属性值:空"; - throw new ServiceException("批次号【" + batchNumber + "】已存在,货主ID【" + shipperId + "】+商品ID【" + materialBaseInfoId + "】" + statusCodeDesc + "相同的记录不允许使用重复的批次号"); + throw new ServiceException("批次号【" + batchNumber + "】在本入库单「" + currentInOrderNumber + + "」下已存在库存,货主ID【" + shipperId + "】+商品ID【" + materialBaseInfoId + "】" + statusCodeDesc + + ",不允许重复使用"); } } }