Map Demand History
Map raw rows into demand history: a dated series of past demand, one quantity per (location, product, date).
Create Scenario saves the series as the scenario's demand history table, like any other mapped table, so a scenario built from a history keeps the series it was built from. For the single-period realized outcome, use Map Demand State, which has no date axis.
XYZ Segmentation reads the series off the scenario and classifies each item by how variable its demand is. So Import Data → Map Demand History → Create Scenario → XYZ Segmentation → Create Scenario, with Map Locations and Map Products wired into the first Create Scenario, produces an answer from this file and the places and products it names, saved beside the history it came from.
When to use this¶
- You have demand observations spread over time (months, weeks, days) and want them saved on the scenario in their dated form
- You want to know which products have steady demand and which erratic, with XYZ Segmentation
What you need¶
- An upstream Import Data node with one row per (location, product, date) observation
- A date column, a quantity column, and the unit the quantity is in
- A Map Locations wired into the same Create Scenario, holding every location the history names. A row naming a location that is not there stops Create Scenario and names the row
- A Map Products wired into the same Create Scenario, holding every product the history names. A row naming a product that is not there stops Create Scenario and names the row
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 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 "unit": "__const__:units". Unit is required on every row with Quantity, and the panel marks it required once it is mapped.
| Field | Type | Required | Example | What it is | Auto-detected headers |
|---|---|---|---|---|---|
| Location | text | Yes | Store 1 |
Where the demand was observed. Must match a Location name. | location, loc, name, id, location_id, loc_id |
| Product | text | Yes | Widget |
Product or SKU observed. Required — name the product even in a single-product scenario. Must match a Product name. | product, sku, item, material, product_id |
| Date | text | Yes | 2025-01-01 |
Observation date, stored as YYYY-MM-DD. Dates written DD.MM.YYYY, DD/MM/YYYY or MM/DD/YYYY, and Excel date numbers, are converted; the Read as setting under this field decides a column like 01/02/2026. Several rows for one location, product and date are kept, and an analysis adds them up in its period. | date, ds, period, month, observed_at, timestamp |
| Quantity | number | Yes | 120.0 |
Observed demand quantity on this date. Its unit goes in Unit. | quantity, qty, amount, volume, units |
| Unit | text | Yes | units |
Unit the quantity is expressed in. A unit other than the scenario's needs a conversion for the product. | unit, uom, quantity_unit, qty_unit |
How it works¶
Each row becomes one observation. Rows sharing a (location, product) form one series, and the series' unit travels with it. The records reach Create Scenario like any other Map node's and are saved there as the demand history table. The unit is required, so this node refuses a row that leaves it blank. Create Scenario holds every row's unit to the scenario's Unit as it does every other quantity: a unit with no conversion to the scenario's unit for the row's product is refused there. Several rows for one location, product and date are kept as they are; an analysis reading the series adds them up in its period.
Dates¶
Dates are saved as YYYY-MM-DD. A date written 13.01.2026, 13/01/2026, 01/13/2026 or 20260113, or an Excel date number such as 46023, is converted when the node runs. A time after the date is dropped.
A date like 01/02/2026 could be 1 February or 2 January. The node reads the whole column to decide: one date such as 13/01/2026 settles it as day first. A dotted date (13.01.2026) is read day first unless you choose an order, and does not decide the column for the other dates. When nothing in the column settles it, or the column holds both orders, the node stops and names the rows; the run report's Choose date format opens the node at its Date field. To decide it yourself, set Read as under the Date field to Day First (01/02 is 1 February) or Month First (01/02 is 2 January). A chosen order applies to dotted dates too, and every date that does not fit it is reported by row.
You see this before you run. With the Date field mapped to a column of an uploaded file, the field shows a few of your dates as the node will read them (01/02/2025 → 1 Feb 2025), and the row that settled the order. It reads the whole file to say so, so it answers as the run will. When another node sits between the file and this one, it changes the rows, and the run decides.
A value that is not a date stops the node too, naming its row and value.
Workflow wiring¶
flowchart LR
n1["Import Data (demand_history.csv)"] --> n2["Map Demand History"]
n4["Import Data (locations.csv)"] --> n5["Map Locations"]
n2 --> n3["Create Scenario"]
n5 --> n3
n6["Import Data (products.csv)"] --> n7["Map Products"]
n7 --> n3
Common mistakes¶
- Using Map Demand State for a time series. That table is single-period and carries no date.
- Leaving the unit blank. A quantity with no unit is refused, not read as the scenario's unit. A history in cases and pallets is fine once the conversions relate both to the scenario's unit; totals and XYZ Segmentation then read it in that unit.
Messages this node can show¶
- Date not readable
- Day and month order unclear
- Field matches several columns
- Mapped table empty
- Number outside its allowed bound
- Required field absent
- Row doesn’t fit its table
- Text padded with spaces
- Value not a plain number
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.