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<MesProRouteProcessDO> 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<Long, BigDecimal> targetQuantities(List<MesProRouteProcessDO> processes, BigDecimal quantity) {
|
var sorted = new ArrayList<>(processes);
|
sorted.sort(Comparator.comparing(MesProRouteProcessDO::getSort, Comparator.nullsLast(Comparator.naturalOrder())));
|
Map<Long, BigDecimal> 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;
|
}
|
}
|