4 天以前 741918a903e17b2ec7522556d2c043b8d35dd8a1
src/main/java/com/ruoyi/production/util/TaskPlanQuantityUtil.java
@@ -1,131 +1,14 @@
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);
    }
    /**
     * 解析工序输出节点
     */
    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;
    }
    /**
     * 解析输出产品规格ID
     */
    public Long resolveOutputProductModelId(ProductionBomStructure outputNode, Long rootProductModelId) {
        if (outputNode == null) {
            return rootProductModelId;
        }
        return outputNode.getProductModelId() != null ? outputNode.getProductModelId() : rootProductModelId;
    }
    /**
     * 默认BigDecimal值