Skip to content

Map Supply Policy

Map raw rows into the scenario's supply policy table: the rules for supply at each location, how much is available, and at what per-unit cost.

This is the input side of supply. Pair it with Map Supply State when you also need to preserve what got used in a baseline.

When to use this

  • Always, when supply is part of a scenario
  • Network Optimization reads this table directly. Capacity becomes the upper bound on per-(location, product) supply, and the unit cost becomes what it pays

Without it the optimizer has no constraint on supply and nothing to charge for it, and the run stops: a missing supply policy is one of its three refusals.

What you need

  • An upstream Import Data node carrying one row per (location, product) you supply from
  • A column identifying the supplier or supply location, matching a location identifier
  • A per-unit supply cost, a purchase or production rate. If you only have realized totals, use Map Supply State instead. This table needs a rate

Field mapping

Fields are matched by name unless you set them. When the workflow runs, every field you have not set a column for is matched against the headers listed below, case-insensitively and ignoring spaces around the header, and a space inside your header reads as an underscore, so Site Name matches site_name. Setting a column for one field fixes that field only; the others keep following your file's headers, so a renamed column is still found. A required field that no column supplies — no header matched, or you set none or one your table lacks — is reported once, with the headers your table does have.

Set mappings in the node's panel. Connect an upstream table and select the mapping node. A field matched by name is marked Matched by name; pick a column to set it yourself, and Match by name puts it back. Match all by name clears every field you set. Required fields without a match are marked in the panel.

Reshape rows in a Script first. A mapping node only says which column is which field. To drop rows, recode values, or split or combine columns, connect a Script node before it and map the columns the Script returns.

Same for every row. A file with no unit column still states its unit: in Quantity Unit, pick Same for every row and type the unit, such as units, and every row is in it. Over MCP, set it in field_mappings as "quantity_unit": "__const__:units". Quantity Unit is required on every row with Capacity or Unit Supply Cost, and the panel marks it required once one of those is mapped.

Field Type Required Example What it is Auto-detected headers
Location text Yes Warehouse A Where supply originates. Must match a Location name. location, loc, name, id, location_id, loc_id
Product text Yes Widget Product or SKU this rule applies to. Required — name it even in a single-product scenario. Must match a Product name. product, sku, item, material, product_id
Capacity number No 1000.0 Maximum quantity available from this location — the optimizer's upper bound. Zero closes supply at this location. Blank = unconstrained. Must be greater than or equal to 0. Its unit goes in Quantity Unit. capacity, max_flow, max_quantity, max_volume, quantity
Quantity Unit text No units Unit the capacity and the supply cost per unit are in. Required on every row that carries one. A unit other than the scenario's needs a conversion for the product. quantity_unit, qty_unit, unit, uom
Unit Supply Cost number No 5.0 Cost to supply one unit, in the scenario currency. Optimization requires a value on every row — set 0 only when the supply is genuinely free. Must be greater than or equal to 0. unit_supply_cost, cost_per_unit, unit_cost, procurement_rate

How it works

Each row becomes a supply policy record. Network Optimization treats capacity as the maximum it may source from that (location, product) and the unit supply cost as the price it pays. Cost to Serve does not read this table. It allocates the realized total on supply state, and a rate is not a cost to it.

A column called quantity auto-detects to Capacity here, and it usually should not. An observed quantity is the state side, and capacity is an upper bound. In the node's panel, set Capacity to Not mapped, or to the column that holds the real limit, and wire the observed quantity to Map Supply State.

Workflow wiring

For an optimization, wire the policy side beside the other tables Network Optimization needs: locations, products, lanes and the demand policy.

flowchart LR
    n1["Import Data (locations.csv)"] --> n2["Map Locations"]
    n3["Import Data (products.csv)"] --> n4["Map Products"]
    n5["Import Data (lanes.csv)"] --> n6["Map Lanes"]
    n7["Import Data (supply.csv)"] --> n8["Map Supply Policy"]
    n9["Import Data (demand.csv)"] --> n10["Map Demand Policy"]
    n2 & n4 & n6 & n8 & n10 --> n11["Create Scenario"]
    n11 --> n12["Network Optimization"]
    n12 --> n13["Create Scenario (optimized)"]

For a baseline that also preserves observed history, fan the same file out to both:

flowchart LR
    n1["Import Data (supply.csv)"] --> n2["Map Supply Policy"]
    n1 --> n3["Map Supply State"]
    n4["Import Data (locations.csv)"] --> n5["Map Locations"]
    n6["Import Data (products.csv)"] --> n7["Map Products"]
    n2 & n3 & n5 & n7 --> n8["Create Scenario"]

Common mistakes

  • Mapping an observed total cost to Unit Supply Cost. It is per unit. A realized total belongs on Map Supply State as Realized Supply Cost.
  • Wiring only Map Supply State. The optimizer reads this table and never reads state. Without it the run stops.
  • Mapping an observed quantity to Capacity. Capacity is an upper limit. Set it only from data that really is one.

Messages this node can show

The table this node makes is checked again with the rest of the scenario when Create Scenario assembles it: see messages about the scenario.

A run gives this node 5 minutes. A node that takes longer stops with Time limit reached.

Like every node, it can also stop on the checks before a run and the run's limits.