From 2fe868bc511fafbff63f3b1aa781bd119cfa16c3 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, 1 Apr 2026 13:46:05 +0800
Subject: [PATCH] =?UTF-8?q?PC=E6=94=B6=E8=B4=A7=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../StockReceiptOrderApplicationService.java | 143 +++++++++++-------
.../StockReceiptOrderDomainService.java | 63 +++++++-
.../StockReceiptOrderAssembler.java | 74 ++++++++-
3 files changed, 219 insertions(+), 61 deletions(-)
diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockReceiptOrder/StockReceiptOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockReceiptOrder/StockReceiptOrderApplicationService.java
index 1cc9ccce4..e3b07e8e7 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockReceiptOrder/StockReceiptOrderApplicationService.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockReceiptOrder/StockReceiptOrderApplicationService.java
@@ -1663,8 +1663,9 @@ public class StockReceiptOrderApplicationService {
}
/**
- * 本次收货的毛/净重、体积、面积增量:优先 receipt*;否则 total*。
+ * 本次收货的毛/净重、体积、面积增量:优先 receipt*(界面本次填写);否则 total*。
* total* 与 PC 回显对齐后可能为「累计实绩」:若 total > 本单收货前累计则增量=差;相等则 0;小于累计则视为「本次增量」原值。
+ *
主项/子项数量各自独立:主行 {@code receiptQuantity}、子行 {@code receiptQuantity} 即用户填写的件数,不做计划比例分摊。
*/
private static BigDecimal pickThisReceiptMetricIncrement(BigDecimal receiptField, BigDecimal totalField,
BigDecimal dbAlreadyBeforeThisReceipt) {
@@ -1747,14 +1748,49 @@ public class StockReceiptOrderApplicationService {
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
+ // 未传 receiptQuantity 但传了称重/体积(常见于 PC 子行):仍视为有收货,否则会走「无收货」分支不写主项累计
+ BigDecimal dbParentNetForGate = receiptMaterialDetailPO.getAlreadyReceiptNetWeight() != null
+ ? receiptMaterialDetailPO.getAlreadyReceiptNetWeight() : BigDecimal.ZERO;
+ BigDecimal dbParentGrossForGate = receiptMaterialDetailPO.getAlreadyReceiptGrossWeight() != null
+ ? receiptMaterialDetailPO.getAlreadyReceiptGrossWeight() : BigDecimal.ZERO;
+ boolean hasReceiptByMetrics = pickThisReceiptMetricIncrement(
+ receiptMaterialDetailDO.getReceiptNetWeight(),
+ receiptMaterialDetailDO.getTotalNetWeight(),
+ dbParentNetForGate).compareTo(BigDecimal.ZERO) > 0
+ || pickThisReceiptMetricIncrement(
+ receiptMaterialDetailDO.getReceiptGrossWeight(),
+ receiptMaterialDetailDO.getTotalGrossWeight(),
+ dbParentGrossForGate).compareTo(BigDecimal.ZERO) > 0;
+ if (!hasReceiptByMetrics && !CollectionUtils.isEmpty(children)) {
+ for (ReceiptMaterialDetailDO c : children) {
+ if (c == null) {
+ continue;
+ }
+ ReceiptMaterialDetailPO cdb = receiptMaterialDetailDbMap.get(c.getMaterialDetailId());
+ if (cdb == null && c.getUniqueId() != null) {
+ cdb = receiptMaterialDetailDbMapByUniqueId.get(c.getUniqueId());
+ }
+ BigDecimal cDbNet = cdb != null && cdb.getAlreadyReceiptNetWeight() != null
+ ? cdb.getAlreadyReceiptNetWeight() : BigDecimal.ZERO;
+ BigDecimal cDbGross = cdb != null && cdb.getAlreadyReceiptGrossWeight() != null
+ ? cdb.getAlreadyReceiptGrossWeight() : BigDecimal.ZERO;
+ if (pickThisReceiptMetricIncrement(c.getReceiptNetWeight(), c.getTotalNetWeight(), cDbNet).compareTo(BigDecimal.ZERO) > 0
+ || pickThisReceiptMetricIncrement(c.getReceiptGrossWeight(), c.getTotalGrossWeight(), cDbGross).compareTo(BigDecimal.ZERO) > 0) {
+ hasReceiptByMetrics = true;
+ break;
+ }
+ }
+ }
// 主项和子项收货数量均为 0 时仍保留该明细参与流程,避免多条平铺明细被“丢失”(batchReceiptUpdate、syncUpdateInMaterialDetail 等需感知全部明细)
- boolean hasReceipt = receiptQuantity.compareTo(BigDecimal.ZERO) > 0 || childrenTotalQuantity.compareTo(BigDecimal.ZERO) > 0;
- BigDecimal mainItemActualQuantity = BigDecimal.ZERO;//主项自身当前作业收货数(不包含子项)
- BigDecimal orderLevelQuantity = BigDecimal.ZERO;//主项+子项合计,用于收货单级汇总
+ boolean hasReceipt = receiptQuantity.compareTo(BigDecimal.ZERO) > 0 || childrenTotalQuantity.compareTo(BigDecimal.ZERO) > 0
+ || hasReceiptByMetrics;
+ BigDecimal mainItemActualQuantity = BigDecimal.ZERO;//主项自身当前作业收货数(不含子项合计)
List returnReceiptMaterialDetailDOChildList = new ArrayList<>();
if (hasReceipt) {
//判断收否收货 第一次收货创建 更多属性 序列号
- if (receiptMaterialDetailPO.getReceiptQuantity().compareTo(BigDecimal.ZERO) == 0){
+ BigDecimal poReceiptQty = receiptMaterialDetailPO.getReceiptQuantity() != null
+ ? receiptMaterialDetailPO.getReceiptQuantity() : BigDecimal.ZERO;
+ if (poReceiptQty.compareTo(BigDecimal.ZERO) == 0){
//收货后 设置该记录不允许被修改
receiptMaterialDetailDO.setAllowModify(2);
//设置物料状态及容器信息
@@ -1764,14 +1800,6 @@ public class StockReceiptOrderApplicationService {
// 统一口径:PDA 上传的 receiptQuantity 视为“本次收货量”,不再按累计值覆盖
BigDecimal newChildrenTotalQuantity = BigDecimal.ZERO;
BigDecimal existingChildrenIncrement = BigDecimal.ZERO;
- BigDecimal newChildrenGrossTotal = BigDecimal.ZERO;
- BigDecimal existingChildrenGrossIncrement = BigDecimal.ZERO;
- BigDecimal newChildrenNetTotal = BigDecimal.ZERO;
- BigDecimal existingChildrenNetIncrement = BigDecimal.ZERO;
- BigDecimal newChildrenVolTotal = BigDecimal.ZERO;
- BigDecimal existingChildrenVolIncrement = BigDecimal.ZERO;
- BigDecimal newChildrenAreaTotal = BigDecimal.ZERO;
- BigDecimal existingChildrenAreaIncrement = BigDecimal.ZERO;
List receiptMaterialDetailDOChildList = receiptMaterialDetailDO.getChildren();
if (!CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)){
for (ReceiptMaterialDetailDO receiptMaterialDetailDOChild : receiptMaterialDetailDOChildList){
@@ -1794,22 +1822,20 @@ public class StockReceiptOrderApplicationService {
BigDecimal childNet = pickThisReceiptMetricIncrement(receiptMaterialDetailDOChild.getReceiptNetWeight(), receiptMaterialDetailDOChild.getTotalNetWeight(), childDbAlreadyNet);
BigDecimal childVol = pickThisReceiptMetricIncrement(receiptMaterialDetailDOChild.getReceiptVolume(), receiptMaterialDetailDOChild.getTotalVolume(), childDbAlreadyVol);
BigDecimal childArea = pickThisReceiptMetricIncrement(receiptMaterialDetailDOChild.getReceiptArea(), receiptMaterialDetailDOChild.getTotalArea(), childDbAlreadyArea);
+ // PC 端子行常只回填 totalNetWeight/totalGrossWeight,不回传 receiptQuantity;用本次称重增量兜底为件数(与千克等重量计量物料一致)
+ if (childQty.compareTo(BigDecimal.ZERO) == 0 && childNet.compareTo(BigDecimal.ZERO) > 0) {
+ childQty = childNet;
+ }
+ if (childQty.compareTo(BigDecimal.ZERO) == 0 && childGross.compareTo(BigDecimal.ZERO) > 0) {
+ childQty = childGross;
+ }
if (receiptMaterialDetailPOChildDb == null) {
- // 新子项:累加其本次收货量
+ // 新子项:累加其本次收货量(毛净重体面积仅落子行,不再汇总到主行)
newChildrenTotalQuantity = newChildrenTotalQuantity.add(childQty);
- newChildrenGrossTotal = newChildrenGrossTotal.add(childGross);
- newChildrenNetTotal = newChildrenNetTotal.add(childNet);
- newChildrenVolTotal = newChildrenVolTotal.add(childVol);
- newChildrenAreaTotal = newChildrenAreaTotal.add(childArea);
} else {
// 已存在子项:累加其本次收货量
existingChildrenIncrement = existingChildrenIncrement.add(childQty);
- existingChildrenGrossIncrement = existingChildrenGrossIncrement.add(childGross);
- existingChildrenNetIncrement = existingChildrenNetIncrement.add(childNet);
- existingChildrenVolIncrement = existingChildrenVolIncrement.add(childVol);
- existingChildrenAreaIncrement = existingChildrenAreaIncrement.add(childArea);
}
- BigDecimal childReceiptQty = receiptMaterialDetailDOChild.getReceiptQuantity() != null ? receiptMaterialDetailDOChild.getReceiptQuantity() : BigDecimal.ZERO;
ReceiptMaterialDetailDO returnReceiptMaterialDetailDOChild = new ReceiptMaterialDetailDO();
if (receiptMaterialDetailPOChildDb != null){
// 子项已存在:用 DB 数据 + PDA 收货数据组装,保证不同明细独立收货不被丢失
@@ -1842,6 +1868,9 @@ public class StockReceiptOrderApplicationService {
returnReceiptMaterialDetailDOChild.setAlreadyReceiptNetWeight(childNet);
returnReceiptMaterialDetailDOChild.setAlreadyReceiptVolume(childVol);
returnReceiptMaterialDetailDOChild.setAlreadyReceiptArea(childArea);
+ // 与已存在子项分支一致:累计收货数量必须显式赋值。仅从父项 copy 会得到父项已收或 0;
+ // batchReceiptUpdate 内 alignPersistedReceiptQuantityToCumulative 用 alreadyReceiptQuantity 写入 receipt_quantity。
+ returnReceiptMaterialDetailDOChild.setAlreadyReceiptQuantity(childQty);
}
// PC 端读 total*:与累计实绩一致(与 already_receipt_* 同步)
returnReceiptMaterialDetailDOChild.setTotalNetWeight(returnReceiptMaterialDetailDOChild.getAlreadyReceiptNetWeight());
@@ -1856,16 +1885,17 @@ public class StockReceiptOrderApplicationService {
}
returnReceiptMaterialDetailDOChild.setMaterialDetailSerialNumberList(receiptMaterialDetailDOChild.getMaterialDetailSerialNumberList());
returnReceiptMaterialDetailDOChild.setMaterialMoreDetailList(receiptMaterialDetailDOChild.getMaterialMoreDetailList());
+ if (returnReceiptMaterialDetailDOChild.getAlreadyReceiptQuantity() != null) {
+ returnReceiptMaterialDetailDOChild.setReceiptQuantity(returnReceiptMaterialDetailDOChild.getAlreadyReceiptQuantity());
+ }
+ // 子项不展示/不落库计划数量(与主项计划区分),避免与主行 1100 重复
+ returnReceiptMaterialDetailDOChild.setQuantity(null);
returnReceiptMaterialDetailDOChildList.add(returnReceiptMaterialDetailDOChild);
- orderLevelQuantity = orderLevelQuantity.add(childReceiptQty);
}
}
- // 主项本次收货增量 = 主项 receiptQuantity(含 assignFirstChildToParentAndRemove 合并的第一条子项)+ 其余子项合计
- // 无子项时使用主项 receiptQuantity
+ // 主行本次收货量 = 仅主行填写的 receiptQuantity;子项各行单独一行落库,不累加到主行 RECEIPT/ALREADY_RECEIPT
BigDecimal childrenTotalIncrement = newChildrenTotalQuantity.add(existingChildrenIncrement);
- mainItemActualQuantity = CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)
- ? receiptQuantity
- : receiptQuantity.add(childrenTotalIncrement);
+ mainItemActualQuantity = receiptQuantity;
BigDecimal dbParentBeforeGross = receiptMaterialDetailPO.getAlreadyReceiptGrossWeight() != null ? receiptMaterialDetailPO.getAlreadyReceiptGrossWeight() : BigDecimal.ZERO;
BigDecimal dbParentBeforeNet = receiptMaterialDetailPO.getAlreadyReceiptNetWeight() != null ? receiptMaterialDetailPO.getAlreadyReceiptNetWeight() : BigDecimal.ZERO;
BigDecimal dbParentBeforeVol = receiptMaterialDetailPO.getAlreadyReceiptVolume() != null ? receiptMaterialDetailPO.getAlreadyReceiptVolume() : BigDecimal.ZERO;
@@ -1874,24 +1904,15 @@ public class StockReceiptOrderApplicationService {
BigDecimal parentReceiptNet = pickThisReceiptMetricIncrement(receiptMaterialDetailDO.getReceiptNetWeight(), receiptMaterialDetailDO.getTotalNetWeight(), dbParentBeforeNet);
BigDecimal parentReceiptVol = pickThisReceiptMetricIncrement(receiptMaterialDetailDO.getReceiptVolume(), receiptMaterialDetailDO.getTotalVolume(), dbParentBeforeVol);
BigDecimal parentReceiptArea = pickThisReceiptMetricIncrement(receiptMaterialDetailDO.getReceiptArea(), receiptMaterialDetailDO.getTotalArea(), dbParentBeforeArea);
- BigDecimal childrenGrossIncrement = newChildrenGrossTotal.add(existingChildrenGrossIncrement);
- BigDecimal childrenNetIncrement = newChildrenNetTotal.add(existingChildrenNetIncrement);
- BigDecimal childrenVolIncrement = newChildrenVolTotal.add(existingChildrenVolIncrement);
- BigDecimal childrenAreaIncrement = newChildrenAreaTotal.add(existingChildrenAreaIncrement);
- BigDecimal mainGrossIncrement = CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)
- ? parentReceiptGross
- : parentReceiptGross.add(childrenGrossIncrement);
- BigDecimal mainNetIncrement = CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)
- ? parentReceiptNet
- : parentReceiptNet.add(childrenNetIncrement);
- BigDecimal mainVolIncrement = CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)
- ? parentReceiptVol
- : parentReceiptVol.add(childrenVolIncrement);
- BigDecimal mainAreaIncrement = CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)
- ? parentReceiptArea
- : parentReceiptArea.add(childrenAreaIncrement);
- //主项已收货数量 = 原有 + 主项本次收货增量
- receiptMaterialDetailDO.setAlreadyReceiptQuantity(receiptMaterialDetailPO.getAlreadyReceiptQuantity().add(mainItemActualQuantity));
+ // 主行 already_* 只累计主行本行毛净重体面积;子行各自落子行记录,避免主行重复叠加子行导致与数量口径不一致
+ BigDecimal mainGrossIncrement = parentReceiptGross;
+ BigDecimal mainNetIncrement = parentReceiptNet;
+ BigDecimal mainVolIncrement = parentReceiptVol;
+ BigDecimal mainAreaIncrement = parentReceiptArea;
+ //主项已收货数量 = 原有 + 主项本次收货增量(PO 字段可能为 null,须兜底否则落库 already/receipt_quantity 为空)
+ BigDecimal dbParentAlreadyQty = receiptMaterialDetailPO.getAlreadyReceiptQuantity() != null
+ ? receiptMaterialDetailPO.getAlreadyReceiptQuantity() : BigDecimal.ZERO;
+ receiptMaterialDetailDO.setAlreadyReceiptQuantity(dbParentAlreadyQty.add(mainItemActualQuantity));
BigDecimal dbParentAlreadyGross = receiptMaterialDetailPO.getAlreadyReceiptGrossWeight() != null ? receiptMaterialDetailPO.getAlreadyReceiptGrossWeight() : BigDecimal.ZERO;
receiptMaterialDetailDO.setAlreadyReceiptGrossWeight(dbParentAlreadyGross.add(mainGrossIncrement));
BigDecimal dbParentAlreadyNet = receiptMaterialDetailPO.getAlreadyReceiptNetWeight() != null ? receiptMaterialDetailPO.getAlreadyReceiptNetWeight() : BigDecimal.ZERO;
@@ -1905,18 +1926,32 @@ public class StockReceiptOrderApplicationService {
receiptMaterialDetailDO.setTotalGrossWeight(receiptMaterialDetailDO.getAlreadyReceiptGrossWeight());
receiptMaterialDetailDO.setTotalVolume(receiptMaterialDetailDO.getAlreadyReceiptVolume());
receiptMaterialDetailDO.setTotalArea(receiptMaterialDetailDO.getAlreadyReceiptArea());
- //记录本次收货单收货总数(主项+子项合计,用于收货单级统计)
- orderLevelQuantity = mainItemActualQuantity;
+ // 收货单级本次实收:主行 + 所有子行(与 stock_receipt_order.actualQuantity 一致)
+ BigDecimal orderLevelQuantity = mainItemActualQuantity.add(childrenTotalIncrement);
totalActualQuantity = totalActualQuantity.add(orderLevelQuantity);
- //判断收货数量是否大于计划数量
- Integer receiptStatus = judgeReceiptQuantity(receiptMaterialDetailDO.getAlreadyReceiptQuantity(), receiptMaterialDetailPO.getQuantity());
+ // 主行收货状态:按「主行+子行」合计与计划数量比较(子行无单独计划数量)
+ BigDecimal groupReceived = receiptMaterialDetailDO.getAlreadyReceiptQuantity() != null
+ ? receiptMaterialDetailDO.getAlreadyReceiptQuantity() : BigDecimal.ZERO;
+ if (!CollectionUtils.isEmpty(returnReceiptMaterialDetailDOChildList)) {
+ for (ReceiptMaterialDetailDO ch : returnReceiptMaterialDetailDOChildList) {
+ BigDecimal ca = ch.getAlreadyReceiptQuantity() != null ? ch.getAlreadyReceiptQuantity() : BigDecimal.ZERO;
+ groupReceived = groupReceived.add(ca);
+ }
+ }
+ Integer receiptStatus = judgeReceiptQuantity(groupReceived, receiptMaterialDetailPO.getQuantity());
receiptMaterialDetailDO.setReceiptStatus(receiptStatus);
+ if (!CollectionUtils.isEmpty(returnReceiptMaterialDetailDOChildList)) {
+ for (ReceiptMaterialDetailDO ch : returnReceiptMaterialDetailDOChildList) {
+ ch.setReceiptStatus(receiptStatus);
+ }
+ }
if (receiptStatus > 2){
totalActualReceiptMaterialQuantity += 1;
}
} else {
// 收货为 0 的明细:保持已收货数量和状态不变,仍加入列表以保持明细完整
- receiptMaterialDetailDO.setAlreadyReceiptQuantity(receiptMaterialDetailPO.getAlreadyReceiptQuantity());
+ receiptMaterialDetailDO.setAlreadyReceiptQuantity(receiptMaterialDetailPO.getAlreadyReceiptQuantity() != null
+ ? receiptMaterialDetailPO.getAlreadyReceiptQuantity() : BigDecimal.ZERO);
receiptMaterialDetailDO.setAlreadyReceiptGrossWeight(receiptMaterialDetailPO.getAlreadyReceiptGrossWeight());
receiptMaterialDetailDO.setAlreadyReceiptNetWeight(receiptMaterialDetailPO.getAlreadyReceiptNetWeight());
receiptMaterialDetailDO.setAlreadyReceiptVolume(receiptMaterialDetailPO.getAlreadyReceiptVolume());
@@ -1930,6 +1965,10 @@ public class StockReceiptOrderApplicationService {
returnReceiptMaterialDetailDO.setTotalGrossWeight(receiptMaterialDetailDO.getTotalGrossWeight());
returnReceiptMaterialDetailDO.setTotalVolume(receiptMaterialDetailDO.getTotalVolume());
returnReceiptMaterialDetailDO.setTotalArea(receiptMaterialDetailDO.getTotalArea());
+ BigDecimal parentRetAlreadyQty = receiptMaterialDetailDO.getAlreadyReceiptQuantity() != null
+ ? receiptMaterialDetailDO.getAlreadyReceiptQuantity() : BigDecimal.ZERO;
+ returnReceiptMaterialDetailDO.setAlreadyReceiptQuantity(parentRetAlreadyQty);
+ returnReceiptMaterialDetailDO.setReceiptQuantity(parentRetAlreadyQty);
if (receiptMaterialDetailPO.getReceiptStatus() == 1){
//一级列表 首次收货
//是否开启了序列号管理
diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java
index e66c27f13..fb68d7b01 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java
@@ -724,6 +724,8 @@ public class StockReceiptOrderDomainService {
/**
* 收货单完成时:按累计已收与计划数量比较,更新明细 receipt_status(3 正常收完 / 4 少收 / 5 超收)
+ * PC 主子行拆分收货时:计划数量只在主行(level=1),子行 quantity 常为 0;须按「主行已收 + 其下子行已收」与主行计划比较,
+ * 主、子行使用同一状态,避免主行判少收、子行判超收。
*/
private void updateReceiptMaterialDetailReceiptStatusWhenOrderCompleted(StockReceiptOrderPO stockReceiptOrderPO,
LoginUser loginUser, String userRealName) {
@@ -738,15 +740,68 @@ public class StockReceiptOrderDomainService {
if (CollectionUtils.isEmpty(details)) {
return;
}
+ Map> childrenByParentUniqueId = new HashMap<>();
for (ReceiptMaterialDetail d : details) {
- d.setReceiptStatus(resolveReceiptDetailStatusOnOrderComplete(d.getAlreadyReceiptQuantity(), d.getQuantity()));
- d.setUpdateBy(loginUser.getUserid());
- d.setUpdateByName(userRealName);
- d.setUpdateTime(updateTime);
+ if (isReceiptDetailChildRow(d) && d.getParentUniqueId() != null) {
+ childrenByParentUniqueId.computeIfAbsent(d.getParentUniqueId(), k -> new ArrayList<>()).add(d);
+ }
+ }
+ Set parentUniqueIdsInOrder = details.stream()
+ .filter(d -> !isReceiptDetailChildRow(d))
+ .map(ReceiptMaterialDetail::getUniqueId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+ for (ReceiptMaterialDetail parent : details) {
+ if (isReceiptDetailChildRow(parent)) {
+ continue;
+ }
+ Integer status;
+ List children = parent.getUniqueId() == null ? null
+ : childrenByParentUniqueId.get(parent.getUniqueId());
+ if (!CollectionUtils.isEmpty(children)) {
+ BigDecimal groupReceived = nz(parent.getAlreadyReceiptQuantity());
+ for (ReceiptMaterialDetail ch : children) {
+ groupReceived = groupReceived.add(nz(ch.getAlreadyReceiptQuantity()));
+ }
+ status = resolveReceiptDetailStatusOnOrderComplete(groupReceived, parent.getQuantity());
+ } else {
+ status = resolveReceiptDetailStatusOnOrderComplete(parent.getAlreadyReceiptQuantity(), parent.getQuantity());
+ }
+ parent.setReceiptStatus(status);
+ parent.setUpdateBy(loginUser.getUserid());
+ parent.setUpdateByName(userRealName);
+ parent.setUpdateTime(updateTime);
+ if (!CollectionUtils.isEmpty(children)) {
+ for (ReceiptMaterialDetail ch : children) {
+ ch.setReceiptStatus(status);
+ ch.setUpdateBy(loginUser.getUserid());
+ ch.setUpdateByName(userRealName);
+ ch.setUpdateTime(updateTime);
+ }
+ }
+ }
+ // 子行的 parent_unique_id 在本单明细中找不到对应主行时:无法按组合计,仍按单行口径更新
+ for (ReceiptMaterialDetail d : details) {
+ if (isReceiptDetailChildRow(d) && d.getParentUniqueId() != null
+ && !parentUniqueIdsInOrder.contains(d.getParentUniqueId())) {
+ d.setReceiptStatus(resolveReceiptDetailStatusOnOrderComplete(d.getAlreadyReceiptQuantity(), d.getQuantity()));
+ d.setUpdateBy(loginUser.getUserid());
+ d.setUpdateByName(userRealName);
+ d.setUpdateTime(updateTime);
+ }
}
receiptMaterialDetailService.updateBatchById(details);
}
+ private static boolean isReceiptDetailChildRow(ReceiptMaterialDetail d) {
+ return d.getLevel() != null && d.getLevel() == 2
+ && d.getParentUniqueId() != null && d.getParentUniqueId() != 0L;
+ }
+
+ private static BigDecimal nz(BigDecimal v) {
+ return v != null ? v : BigDecimal.ZERO;
+ }
+
/** 3=已收足 4=少收 5=超收 */
private static Integer resolveReceiptDetailStatusOnOrderComplete(BigDecimal alreadyReceiptQuantity, BigDecimal quantity) {
BigDecimal already = alreadyReceiptQuantity != null ? alreadyReceiptQuantity : BigDecimal.ZERO;
diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockReceiptOrder/StockReceiptOrderAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockReceiptOrder/StockReceiptOrderAssembler.java
index c97f85378..1a65ae878 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockReceiptOrder/StockReceiptOrderAssembler.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockReceiptOrder/StockReceiptOrderAssembler.java
@@ -1,12 +1,19 @@
package com.mhd.wms.interfaces.assember.stockReceiptOrder;
-import cn.hutool.json.JSONUtil;
import com.mhd.common.core.utils.IgnoreNullUtil;
import com.mhd.common.core.utils.bean.BeanUtils;
+import com.mhd.wms.domain.materialMoreDetail.repository.todo.MaterialMoreDetailDO;
+import com.mhd.wms.domain.receiptMaterialDetail.repository.todo.ReceiptMaterialDetailDO;
import com.mhd.wms.domain.stockReceiptOrder.repository.todo.StockReceiptOrderDO;
+import com.mhd.wms.interfaces.dto.materialMoreDetail.MaterialMoreDetailDTO;
+import com.mhd.wms.interfaces.dto.receiptMaterialDetail.ReceiptMaterialDetailDTO;
import com.mhd.wms.interfaces.dto.stockReceiptOrder.StockReceiptOrderDTO;
import org.springframework.stereotype.Component;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
/**
* 收货单Assembler
*
@@ -30,11 +37,68 @@ public class StockReceiptOrderAssembler {
}
/**
- * 转换实体
- */
+ * 编辑/收货提交:DTO → DO。
+ * Jackson/Hutool 对嵌套 {@code materialDetailList[].children} 与 {@code MaterialMoreDetailDTO}→DO 的中转易丢子行,
+ * 导致子项 {@code receiptQuantity} 为 null、不生成收货明细。此处显式递归拷贝,保证子树完整。
+ */
public StockReceiptOrderDO toDOByEdit(StockReceiptOrderDTO stockReceiptOrderDTO) {
- // 拷贝
- return JSONUtil.toBean(JSONUtil.toJsonStr(stockReceiptOrderDTO), StockReceiptOrderDO.class);
+ StockReceiptOrderDO target = new StockReceiptOrderDO();
+ String[] topIgnore = appendIgnores(IgnoreNullUtil.getNullPropertyNames(stockReceiptOrderDTO), "materialDetailList");
+ BeanUtils.copyProperties(stockReceiptOrderDTO, target, topIgnore);
+ target.setMaterialDetailList(convertMaterialDetailRows(stockReceiptOrderDTO.getMaterialDetailList()));
+ return target;
+ }
+
+ private static String[] appendIgnores(String[] base, String... extra) {
+ if (extra == null || extra.length == 0) {
+ return base;
+ }
+ String[] out = Arrays.copyOf(base, base.length + extra.length);
+ System.arraycopy(extra, 0, out, base.length, extra.length);
+ return out;
+ }
+
+ private static List convertMaterialDetailRows(List src) {
+ if (src == null) {
+ return null;
+ }
+ List list = new ArrayList<>(src.size());
+ for (ReceiptMaterialDetailDTO row : src) {
+ list.add(convertOneMaterialDetail(row));
+ }
+ return list;
+ }
+
+ private static ReceiptMaterialDetailDO convertOneMaterialDetail(ReceiptMaterialDetailDTO src) {
+ if (src == null) {
+ return null;
+ }
+ ReceiptMaterialDetailDO t = new ReceiptMaterialDetailDO();
+ String[] ignore = appendIgnores(IgnoreNullUtil.getNullPropertyNames(src),
+ "children", "materialMoreDetailList");
+ BeanUtils.copyProperties(src, t, ignore);
+ t.setMaterialMoreDetailList(convertMoreDetailList(src.getMaterialMoreDetailList()));
+ t.setChildren(convertMaterialDetailRows(src.getChildren()));
+ if (src.getMaterialDetailSerialNumberList() != null) {
+ t.setMaterialDetailSerialNumberList(new ArrayList<>(src.getMaterialDetailSerialNumberList()));
+ }
+ return t;
+ }
+
+ private static List convertMoreDetailList(List src) {
+ if (src == null) {
+ return null;
+ }
+ List list = new ArrayList<>(src.size());
+ for (MaterialMoreDetailDTO m : src) {
+ if (m == null) {
+ continue;
+ }
+ MaterialMoreDetailDO d = new MaterialMoreDetailDO();
+ BeanUtils.copyProperties(m, d, IgnoreNullUtil.getNullPropertyNames(m));
+ list.add(d);
+ }
+ return list;
}
}