From 10b88a7ff17caf92f3d4e8a550c1085a70c2517a Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期四, 28 五月 2026 17:43:26 +0800
Subject: [PATCH] Merge dev_New_pro into dev_山西_晋和园_pro

---
 src/main/java/com/ruoyi/production/util/TaskPlanQuantityUtil.java |  137 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 137 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/util/TaskPlanQuantityUtil.java b/src/main/java/com/ruoyi/production/util/TaskPlanQuantityUtil.java
new file mode 100644
index 0000000..e82d7e4
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/util/TaskPlanQuantityUtil.java
@@ -0,0 +1,137 @@
+package com.ruoyi.production.util;
+
+import com.ruoyi.production.pojo.ProductionBomStructure;
+import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
+import com.ruoyi.technology.pojo.TechnologyRoutingOperation;
+import lombok.experimental.UtilityClass;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 宸ュ崟璁″垝鏁伴噺璁$畻宸ュ叿绫�
+ */
+@UtilityClass
+public class TaskPlanQuantityUtil {
+
+    /**
+     * 璁$畻宸ュ崟璁″垝鏁伴噺锛堜娇鐢� TechnologyRoutingOperation锛�
+     */
+    public BigDecimal resolveTaskPlanQuantity(TechnologyRoutingOperation sourceOperation,
+                                              Map<String, BigDecimal> operationDemandedQuantityMap,
+                                              ProductionOrder productionOrder,
+                                              Long rootProductModelId) {
+        if (sourceOperation == null || operationDemandedQuantityMap == null || operationDemandedQuantityMap.isEmpty()) {
+            return defaultDecimal(productionOrder == null ? null : productionOrder.getQuantity());
+        }
+        Long outputProductModelId = sourceOperation.getProductModelId() != null
+                ? sourceOperation.getProductModelId()
+                : rootProductModelId;
+        String key = buildOperationDemandedQuantityKey(sourceOperation.getTechnologyOperationId(), outputProductModelId);
+        BigDecimal planQuantity = operationDemandedQuantityMap.get(key);
+        return planQuantity != null ? planQuantity : defaultDecimal(productionOrder == null ? null : productionOrder.getQuantity());
+    }
+
+    /**
+     * 璁$畻宸ュ崟璁″垝鏁伴噺锛堜娇鐢� ProductionOrderRoutingOperation锛�
+     */
+    public BigDecimal resolveTaskPlanQuantity(ProductionOrderRoutingOperation routingOperation,
+                                              Map<String, BigDecimal> demandedQuantityMap,
+                                              BigDecimal orderQuantity,
+                                              Long rootProductModelId) {
+        if (routingOperation == null || demandedQuantityMap == null || demandedQuantityMap.isEmpty()) {
+            return orderQuantity;
+        }
+        Long outputProductModelId = routingOperation.getProductModelId() != null
+                ? routingOperation.getProductModelId()
+                : rootProductModelId;
+        String key = buildOperationDemandedQuantityKey(routingOperation.getTechnologyOperationId(), outputProductModelId);
+        BigDecimal planQuantity = demandedQuantityMap.get(key);
+        return planQuantity != null ? planQuantity : orderQuantity;
+    }
+
+    /**
+     * 鏋勫缓宸ュ簭闇�姹傞噺鏄犲皠琛�
+     */
+    public Map<String, BigDecimal> buildOperationDemandedQuantityMap(List<ProductionBomStructure> bomStructures, Long rootProductModelId) {
+        if (bomStructures == null || bomStructures.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        Map<Long, ProductionBomStructure> structureById = new HashMap<>();
+        for (ProductionBomStructure item : bomStructures) {
+            if (item != null && item.getId() != null) {
+                structureById.put(item.getId(), item);
+            }
+        }
+        Map<String, BigDecimal> demandedQuantityMap = new HashMap<>();
+        Set<String> mergedOutputNodeKeySet = new HashSet<>();
+        for (ProductionBomStructure bomStructure : bomStructures) {
+            if (bomStructure == null || bomStructure.getTechnologyOperationId() == null) {
+                continue;
+            }
+            ProductionBomStructure outputNode = resolveOperationOutputNode(bomStructure, structureById);
+            Long outputProductModelId = resolveOutputProductModelId(outputNode, rootProductModelId);
+            if (outputProductModelId == null) {
+                continue;
+            }
+            String mergedOutputNodeKey = buildOperationOutputNodeKey(bomStructure.getTechnologyOperationId(),
+                    outputNode == null ? null : outputNode.getId(), outputProductModelId);
+            if (!mergedOutputNodeKeySet.add(mergedOutputNodeKey)) {
+                continue;
+            }
+            BigDecimal demandedQuantity = defaultDecimal(outputNode == null ? null : outputNode.getDemandedQuantity());
+            String key = buildOperationDemandedQuantityKey(bomStructure.getTechnologyOperationId(), outputProductModelId);
+            demandedQuantityMap.merge(key, demandedQuantity, BigDecimal::add);
+        }
+        return demandedQuantityMap;
+    }
+
+    /**
+     * 鏋勫缓宸ュ簭闇�姹傞噺key
+     */
+    public String buildOperationDemandedQuantityKey(Long operationId, Long outputProductModelId) {
+        return String.valueOf(operationId) + "#" + String.valueOf(outputProductModelId);
+    }
+
+    /**
+     * 鏋勫缓杈撳嚭鑺傜偣key
+     */
+    public String buildOperationOutputNodeKey(Long operationId, Long outputNodeId, Long outputProductModelId) {
+        return String.valueOf(operationId) + "#" + String.valueOf(outputNodeId) + "#" + String.valueOf(outputProductModelId);
+    }
+
+    /**
+     * 瑙f瀽宸ュ簭杈撳嚭鑺傜偣
+     */
+    public ProductionBomStructure resolveOperationOutputNode(ProductionBomStructure bomStructure,
+                                                             Map<Long, ProductionBomStructure> structureById) {
+        if (bomStructure == null) {
+            return null;
+        }
+        if (bomStructure.getParentId() == null) {
+            return bomStructure;
+        }
+        ProductionBomStructure parent = structureById.get(bomStructure.getParentId());
+        return parent != null ? parent : bomStructure;
+    }
+
+    /**
+     * 瑙f瀽杈撳嚭浜у搧瑙勬牸ID
+     */
+    public Long resolveOutputProductModelId(ProductionBomStructure outputNode, Long rootProductModelId) {
+        if (outputNode == null) {
+            return rootProductModelId;
+        }
+        return outputNode.getProductModelId() != null ? outputNode.getProductModelId() : rootProductModelId;
+    }
+
+    /**
+     * 榛樿BigDecimal鍊�
+     */
+    public BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
+    }
+
+}

--
Gitblit v1.9.3