1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package cn.iocoder.yudao.module.mes.service.pro.task.schedule;
 
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
 
/** 在一次排产预览内分配库存快照,防止多个工单重复使用同一库存。 */
final class MesScheduleMaterialCheck {
    private MesScheduleMaterialCheck() {}
 
    static Map<Long, BigDecimal> allocate(Map<Long, BigDecimal> available, Map<Long, BigDecimal> required) {
        var remaining = new HashMap<>(available);
        required.forEach((itemId, quantity) -> {
            if (itemId == null || quantity == null || quantity.signum() <= 0)
                throw new IllegalArgumentException("工单 BOM 物料或需求数量无效");
            var stock = remaining.getOrDefault(itemId, BigDecimal.ZERO);
            if (stock.compareTo(quantity) < 0)
                throw new IllegalArgumentException("物料#" + itemId + "缺料:需求 " + quantity.stripTrailingZeros().toPlainString()
                        + ",可用 " + stock.stripTrailingZeros().toPlainString());
            remaining.put(itemId, stock.subtract(quantity));
        });
        return remaining;
    }
}