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
+ + ",不允许重复使用");
}
}
}