package com.aps.macroplanner.variable;

import com.google.ortools.linearsolver.MPSolver;
import com.aps.macroplanner.data.*;
import com.aps.macroplanner.model.MacroPlannerModel;

/**
 * 库存松弛变量构建器 — 创建 MinInvQtyUnder, MaxInvQtyOver, InvQtyUnderTarget 变量。
 *
 * <p>仅在对应库存规格定义时才创建对应的松弛变量
 * (例如: 没有定义 MaxLevel 则不创建 MaxInvQtyOver)。</p>
 *
 * <h3>MinInvQtyUnder[productId_spId_periodIndex]</h3>
 * <ul><li>含义: 低于最小库存的量</li><li>范围: [0, +∞)</li></ul>
 *
 * <h3>MaxInvQtyOver[productId_spId_periodIndex]</h3>
 * <ul><li>含义: 超过最大库存的量</li><li>范围: [0, +∞)</li></ul>
 *
 * <h3>InvQtyUnderTarget[productId_spId_periodIndex]</h3>
 * <ul><li>含义: 低于目标库存的量</li><li>范围: [0, +∞)</li></ul>
 */
public class InventorySlackVariableBuilder {

    public static void create(MacroPlannerModel model, TestDataBuilder data) {
        double inf = MPSolver.infinity();
        for (InventorySpec spec : data.getInventorySpecs()) {
            String key = spec.getKey();
            if (spec.hasMinLevel() || spec.hasMinLevelInDays()) {
                model.getMinInvQtyUnderVars().put(key,
                        model.getSolver().makeNumVar(0.0, inf, "MinInvUnder_" + key));
            }
            if (spec.hasMaxLevel() || spec.hasMaxLevelInDays()) {
                model.getMaxInvQtyOverVars().put(key,
                        model.getSolver().makeNumVar(0.0, inf, "MaxInvOver_" + key));
            }
            if (spec.hasTarget() || spec.hasTargetInDays()) {
                model.getInvQtyUnderTargetVars().put(key,
                        model.getSolver().makeNumVar(0.0, inf, "InvUnderTarget_" + key));
            }
        }
    }
}