From c15e67c83394c1734eb4e9802d8f343c6076efc1 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 13 五月 2026 16:16:45 +0800
Subject: [PATCH] Merge branch 'dev_New_pro' into dev_宁夏_英泽防锈

---
 src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java |  181 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 180 insertions(+), 1 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
index 35cdb27..d0dab50 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
@@ -1,18 +1,29 @@
 package com.ruoyi.production.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.production.bean.dto.ProductionBomStructureDto;
 import com.ruoyi.production.bean.vo.ProductionBomStructureVo;
 import com.ruoyi.production.mapper.ProductionBomStructureMapper;
+import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
+import com.ruoyi.production.mapper.ProductionOrderBomMapper;
+import com.ruoyi.production.mapper.ProductionOrderMapper;
+import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper;
 import com.ruoyi.production.pojo.ProductionBomStructure;
+import com.ruoyi.production.pojo.ProductionOperationTask;
+import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.pojo.ProductionOrderBom;
+import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
 import com.ruoyi.production.service.ProductionBomStructureService;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -26,7 +37,11 @@
 @RequiredArgsConstructor()
 public class ProductionBomStructureServiceImpl extends ServiceImpl<ProductionBomStructureMapper, ProductionBomStructure> implements ProductionBomStructureService {
 
-    private  final ProductionBomStructureMapper productionBomStructureMapper;
+    private final ProductionBomStructureMapper productionBomStructureMapper;
+    private final ProductionOrderBomMapper productionOrderBomMapper;
+    private final ProductionOrderMapper productionOrderMapper;
+    private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper;
+    private final ProductionOperationTaskMapper productionOperationTaskMapper;
 
     /**
      * 鏍规嵁BOM鏌ヨ骞剁粍瑁呯粨鏋勬爲銆�
@@ -136,9 +151,173 @@
         if (!updateList.isEmpty()) {
             this.updateBatchById(updateList);
         }
+        syncDemandedQuantityAndTaskPlanQuantity(orderBomId, dto.getProductionOrderId());
         return true;
     }
 
+    private void syncDemandedQuantityAndTaskPlanQuantity(Long orderBomId, Long productionOrderId) {
+        if (orderBomId == null) {
+            return;
+        }
+        ProductionOrderBom orderBom = productionOrderBomMapper.selectById(orderBomId);
+        if (orderBom == null) {
+            return;
+        }
+        Long currentProductionOrderId = productionOrderId != null ? productionOrderId : orderBom.getProductionOrderId();
+        if (currentProductionOrderId == null) {
+            return;
+        }
+        ProductionOrder productionOrder = productionOrderMapper.selectById(currentProductionOrderId);
+        if (productionOrder == null) {
+            return;
+        }
+
+        BigDecimal orderQuantity = defaultDecimal(productionOrder.getQuantity());
+        List<ProductionBomStructure> structureList = this.list(
+                Wrappers.<ProductionBomStructure>lambdaQuery()
+                        .eq(ProductionBomStructure::getProductionOrderBomId, orderBomId)
+                        .orderByAsc(ProductionBomStructure::getId));
+        syncStructureDemandedQuantity(structureList, orderQuantity);
+        syncTaskPlanQuantity(
+                currentProductionOrderId,
+                structureList,
+                orderQuantity,
+                orderBom.getProductModelId() != null ? orderBom.getProductModelId() : productionOrder.getProductModelId());
+    }
+
+    private void syncStructureDemandedQuantity(List<ProductionBomStructure> structureList, BigDecimal orderQuantity) {
+        if (structureList == null || structureList.isEmpty()) {
+            return;
+        }
+        List<ProductionBomStructure> updateList = new ArrayList<>();
+        for (ProductionBomStructure structure : structureList) {
+            if (structure == null || structure.getId() == null) {
+                continue;
+            }
+            BigDecimal demandedQuantity = defaultDecimal(structure.getUnitQuantity()).multiply(orderQuantity);
+            if (compareDecimal(structure.getDemandedQuantity(), demandedQuantity) == 0) {
+                continue;
+            }
+            ProductionBomStructure update = new ProductionBomStructure();
+            update.setId(structure.getId());
+            update.setDemandedQuantity(demandedQuantity);
+            updateList.add(update);
+            structure.setDemandedQuantity(demandedQuantity);
+        }
+        if (!updateList.isEmpty()) {
+            this.updateBatchById(updateList);
+        }
+    }
+
+    private void syncTaskPlanQuantity(Long productionOrderId,
+                                      List<ProductionBomStructure> structureList,
+                                      BigDecimal orderQuantity,
+                                      Long rootProductModelId) {
+        List<ProductionOperationTask> taskList = productionOperationTaskMapper.selectList(
+                Wrappers.<ProductionOperationTask>lambdaQuery()
+                        .eq(ProductionOperationTask::getProductionOrderId, productionOrderId)
+                        .orderByAsc(ProductionOperationTask::getId));
+        if (taskList == null || taskList.isEmpty()) {
+            return;
+        }
+
+        Set<Long> routingOperationIds = taskList.stream()
+                .map(ProductionOperationTask::getProductionOrderRoutingOperationId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+        if (routingOperationIds.isEmpty()) {
+            return;
+        }
+
+        Map<Long, ProductionOrderRoutingOperation> routingOperationMap = productionOrderRoutingOperationMapper
+                .selectBatchIds(routingOperationIds)
+                .stream()
+                .filter(item -> item != null && item.getId() != null)
+                .collect(Collectors.toMap(ProductionOrderRoutingOperation::getId, item -> item, (left, right) -> left));
+        Map<String, BigDecimal> demandedQuantityMap = buildOperationDemandedQuantityMap(structureList, rootProductModelId, orderQuantity);
+
+        for (ProductionOperationTask task : taskList) {
+            if (task == null || task.getId() == null || task.getProductionOrderRoutingOperationId() == null) {
+                continue;
+            }
+            ProductionOrderRoutingOperation routingOperation = routingOperationMap.get(task.getProductionOrderRoutingOperationId());
+            if (routingOperation == null || routingOperation.getTechnologyRoutingOperationId() == null) {
+                continue;
+            }
+            BigDecimal planQuantity = resolveTaskPlanQuantity(routingOperation, demandedQuantityMap, orderQuantity);
+            if (compareDecimal(task.getPlanQuantity(), planQuantity) == 0) {
+                continue;
+            }
+            ProductionOperationTask update = new ProductionOperationTask();
+            update.setId(task.getId());
+            update.setPlanQuantity(planQuantity);
+            productionOperationTaskMapper.updateById(update);
+        }
+    }
+
+    private Map<String, BigDecimal> buildOperationDemandedQuantityMap(List<ProductionBomStructure> structureList,
+                                                                      Long rootProductModelId,
+                                                                      BigDecimal orderQuantity) {
+        if (structureList == null || structureList.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        Map<Long, ProductionBomStructure> structureById = structureList.stream()
+                .filter(item -> item != null && item.getId() != null)
+                .collect(Collectors.toMap(ProductionBomStructure::getId, item -> item, (left, right) -> left));
+        Map<String, BigDecimal> demandedQuantityMap = new HashMap<>();
+        for (ProductionBomStructure bomStructure : structureList) {
+            if (bomStructure == null || bomStructure.getTechnologyOperationId() == null || bomStructure.getUnitQuantity() == null) {
+                continue;
+            }
+            Long outputProductModelId = resolveOutputProductModelId(bomStructure, structureById, rootProductModelId);
+            String key = buildOperationDemandedQuantityKey(bomStructure.getTechnologyOperationId(), outputProductModelId);
+            demandedQuantityMap.merge(key, bomStructure.getUnitQuantity().multiply(orderQuantity), BigDecimal::add);
+        }
+        return demandedQuantityMap;
+    }
+
+    private BigDecimal resolveTaskPlanQuantity(ProductionOrderRoutingOperation routingOperation,
+                                               Map<String, BigDecimal> demandedQuantityMap,
+                                               BigDecimal orderQuantity) {
+        if (routingOperation == null || demandedQuantityMap == null || demandedQuantityMap.isEmpty()) {
+            return orderQuantity;
+        }
+        String key = buildOperationDemandedQuantityKey(
+                routingOperation.getTechnologyOperationId(),
+                routingOperation.getProductModelId());
+        BigDecimal planQuantity = demandedQuantityMap.get(key);
+        return planQuantity != null ? planQuantity : orderQuantity;
+    }
+
+    private String buildOperationDemandedQuantityKey(Long operationId, Long outputProductModelId) {
+        return String.valueOf(operationId) + "#" + String.valueOf(outputProductModelId);
+    }
+
+    private Long resolveOutputProductModelId(ProductionBomStructure bomStructure,
+                                             Map<Long, ProductionBomStructure> structureById,
+                                             Long rootProductModelId) {
+        if (bomStructure == null) {
+            return rootProductModelId;
+        }
+        Long parentId = bomStructure.getParentId();
+        if (parentId == null) {
+            return rootProductModelId != null ? rootProductModelId : bomStructure.getProductModelId();
+        }
+        ProductionBomStructure parent = structureById.get(parentId);
+        if (parent != null && parent.getProductModelId() != null) {
+            return parent.getProductModelId();
+        }
+        return rootProductModelId != null ? rootProductModelId : bomStructure.getProductModelId();
+    }
+
+    private BigDecimal defaultDecimal(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
+    }
+
+    private int compareDecimal(BigDecimal left, BigDecimal right) {
+        return defaultDecimal(left).compareTo(defaultDecimal(right));
+    }
+
     /**
      * 灏嗘爲褰㈢粨鏋勬媿骞虫垚鍒楄〃锛屼究浜庣粺涓�淇濆瓨銆�
      */

--
Gitblit v1.9.3