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值
|
*/
|
public BigDecimal defaultDecimal(BigDecimal value) {
|
return value == null ? BigDecimal.ZERO : value;
|
}
|
|
}
|