云
12 小时以前 3ff6604c75c887f4056ee03545d204bc9323286c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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;
    }
}