package cn.iocoder.yudao.module.mes.service.pro.task.schedule; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService; import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderProcessService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; /** 预览与任务写入共用工序目标产量,前道产出覆盖后道收率损耗。 */ @Service public class MesProScheduleQuantityService { @Resource private MesProWorkOrderProcessService workOrderProcessService; @Resource private MesProRouteProcessService routeProcessService; @Resource private MesProRouteProductService routeProductService; public BigDecimal targetQuantity(MesProWorkOrderDO order, Long requestedRouteId, Long processId) { List processes = new ArrayList<>(); var saved = workOrderProcessService.getWorkOrderProcessListByWorkOrderId(order.getId()); if (!saved.isEmpty()) { for (var row : saved) processes.add(new MesProRouteProcessDO().setProcessId(row.getProcessId()) .setSort(row.getSort()).setYieldRate(row.getYieldRate())); } else { Long routeId = requestedRouteId != null ? requestedRouteId : order.getRouteId(); if (routeId == null) { var relation = routeProductService.getRouteProductByItemId(order.getProductId()); if (relation != null) routeId = relation.getRouteId(); } if (routeId != null) processes.addAll(routeProcessService.getRouteProcessListByRouteId(routeId)); } return targetQuantities(processes, order.getQuantity()).getOrDefault(processId, order.getQuantity()); } public static Map targetQuantities(List processes, BigDecimal quantity) { var sorted = new ArrayList<>(processes); sorted.sort(Comparator.comparing(MesProRouteProcessDO::getSort, Comparator.nullsLast(Comparator.naturalOrder()))); Map result = new HashMap<>(); BigDecimal cumulativeYield = BigDecimal.ONE; for (int i = sorted.size() - 1; i >= 0; i--) { var process = sorted.get(i); if (process.getProcessId() == null) continue; result.put(process.getProcessId(), quantity.divide(cumulativeYield, 0, RoundingMode.CEILING)); if (process.getYieldRate() != null && process.getYieldRate().signum() > 0) { cumulativeYield = cumulativeYield.multiply(process.getYieldRate()); } } return result; } }