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 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 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 buildOperationDemandedQuantityMap(List bomStructures, Long rootProductModelId) { if (bomStructures == null || bomStructures.isEmpty()) { return Collections.emptyMap(); } Map structureById = new HashMap<>(); for (ProductionBomStructure item : bomStructures) { if (item != null && item.getId() != null) { structureById.put(item.getId(), item); } } Map demandedQuantityMap = new HashMap<>(); Set 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 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值 */ public BigDecimal defaultDecimal(BigDecimal value) { return value == null ? BigDecimal.ZERO : value; } }