Interactive demo · synthetic dataEvery record on this page is fabricated.

Order Export for Production Planning

Shopify has three plausible answers to “which warehouse”; this is how the export picks the one that ships.

The production code behind this demo is my own work — design, directing Claude Code from specs, the warehouse-attribution rule and the conservative stock verdict, requirements with the planning team, deployment and the handover to planners; it is developed further by Prada Dipa — LinkedIn profile, opens in a new tab and Luthfi Aditya — LinkedIn profile, opens in a new tab.

Read the case study

1  Which warehouse?

One fabricated order. One line of six units. Change what Shopify returns and watch the ladder pick a different rung — and the row split.

#MD-1041 · MERIDIAN WRAP DRESS · HARBOUR SAND / S/M · 6 UNITS

WHAT SHOPIFY RETURNED
THE ASSIGNED LOCATION’S RECORD
  1. 1Fulfillment.locationUSED

    where units were actually shipped from

  2. 2FulfillmentOrder.assignedLocationUSED

    where unfulfilled units are meant to ship from — live name preferred over the snapshot

  3. 3UnknownNOT REACHED

    the line still appears in the export, flagged, rather than being dropped

  4. 4inventory levelsNEVER

    never consulted — inventory says where stock sits, not where a unit shipped from

EXPORT ROWS FOR THIS LINE (2)

  • MERIDIAN Lowfield Warehouse

    4 units

    Fulfillment.location

  • MERIDIAN Northgate Studio

    2 units

    assignedLocation (live name)

Two rows, not one averaged row. Four units in MERIDIAN Lowfield Warehouse and two in MERIDIAN Northgate Studio is not the same fact as six units somewhere.

The fulfillment order still carries MERIDIAN Northgate Atelier as its snapshot name. The live record says MERIDIAN Northgate Studio, and the live name wins — otherwise the export would keep naming a warehouse that no longer exists.

2  Can we fill it from stock?

Three fabricated stock sheets, each kept in a different naming system, none of them Shopify’s. Normalisation is what makes them agree — and when it cannot, the answer is Review, never a guess.

THE ORDER KEY

STYLE
Meridian Wrap Dress→ meridian wrap dress
COLOUR
Harbour Sand→ harbour sand
SIZE
S/M→ s/m

SKU K61A2M104-HARBOUR SAND-S/M · the style id is parsed and then deliberately not used as a key

STOCK ROWS FOR THIS STYLE AND COLOUR

  • Stock Sheet — Lowfield12“S / M” → “s/m” · matched
  • Stock Sheet — Lowfield3“M/L” → “m/l”
  • Stock Sheet — Northgate4“S/M” → “s/m” · matched
  • Stock Sheet — Northgate2“m/l” → “m/l”

YES

Exact style, color, and size match.

Stock Sheet — Lowfield (12), Stock Sheet — Northgate (4)

3  Whose day is it?

The planners are in Bali. The store’s admin timezone is US Eastern. A bare date means two different sets of orders, so the range is converted to explicit UTC instants before the query is built.

2026-07-02

Asia/MakassarUTC+08:00what the planner meant

2026-07-01T16:00:00Z  →  2026-07-02T15:59:59Z

America/New_YorkUTC-04:00where the store's admin day would have drawn it

2026-07-02T04:00:00Z  →  2026-07-03T03:59:59Z

The pale strip on both bars is the stretch of time both days contain. Everything outside it belongs to one day and not the other.

The two windows are 12 hours apart. Any order created in that gap lands in one export and not the other — and nobody could reconcile the totals afterwards. That is the whole reason a bare date is never sent.

created_at:>='2026-07-01T16:00:00Z' created_at:<='2026-07-02T15:59:59Z'

4  The rows a planner downloads

Six fabricated orders, fourteen line items, 16 rows — one per line item per warehouse. Two lines split, so they take two rows each.

Export preview: one row per line item per warehouse, with the warehouse provenance and the stock verdict.
ORDERCUSTOMERPRODUCTQTYWAREHOUSESOURCESTOCK
#MD-10412026-07-01 10:15R. AnwarMeridian Wrap DressK61A2M104-HARBOUR SAND-S/M4MERIDIAN Lowfield WarehouseFulfillment.locationYESExact style, color, and size match.
#MD-10412026-07-01 10:15R. AnwarMeridian Wrap DressK61A2M104-HARBOUR SAND-S/M2MERIDIAN Northgate StudioassignedLocationYESExact style, color, and size match.
#MD-10412026-07-01 10:15R. AnwarGift WrappingGIFTWRAP-011MERIDIAN Lowfield WarehouseFulfillment.locationNONot a stock-tracked garment.
#MD-10422026-07-01 17:40S. WidjajaCoastline Linen ShirtK61C7S220-TIDAL BLUE/CHALK CLOUD-M/L3MERIDIAN Riverside StoreassignedLocationPARTIALPartial: 2 of 3 available.
#MD-10422026-07-01 17:40S. WidjajaDriftwood Wide Leg TrouserK61D1T318-DRIFTWOOD-M/L2MERIDIAN Lowfield WarehouseFulfillment.locationYESExact style, color, and size match.
#MD-10432026-07-02 09:05T. HalimEmber KaftanK61E4K402-EMBER SKY-X/L1UnknownUnknownNONo matching stock (style, color, size).
#MD-10432026-07-02 09:05T. HalimMeridian Wrap DressK61A2M104-CHALK CLOUD-S/M2MERIDIAN Northgate AtelierassignedLocationYESExact style, color, and size match.
#MD-10442026-07-02 22:22V. NurhadiCoastline Linen ShirtK61C7S220-TIDAL BLUE1MERIDIAN Lowfield WarehouseFulfillment.locationREVIEWIncomplete order attributes (size); check manually.
#MD-10442026-07-02 22:22V. NurhadiDriftwood Wide Leg TrouserK61D1T318-DRIFTWOOD-S/M3MERIDIAN Lowfield WarehouseFulfillment.locationYESExact style, color, and size match.
#MD-10442026-07-02 22:22V. NurhadiDriftwood Wide Leg TrouserK61D1T318-DRIFTWOOD-S/M1MERIDIAN Riverside StoreFulfillment.locationYESExact style, color, and size match.
#MD-10452026-07-03 11:11W. PrabowoMeridian Wrap DressK61A2M104-HARBOUR SAND-M/L10MERIDIAN Northgate StudioassignedLocationPARTIALPartial: 5 of 10 available.
#MD-10452026-07-03 11:11W. PrabowoEmber KaftanK61E4K402-EMBER SKY-M/L1MERIDIAN Northgate StudioFulfillment.locationYESExact style, color, and size match.
#MD-10452026-07-03 11:11W. PrabowoCoastline Linen ShirtK61C7S220-CORAL REEF-S/M2MERIDIAN Lowfield WarehouseFulfillment.locationNONo matching stock (style, color, size).
#MD-10462026-07-04 00:48Y. SutantoDriftwood Wide Leg TrouserK61D1T318-DRIFTWOOD-X/L5MERIDIAN Riverside StoreassignedLocationNONo matching stock (style, color, size).
#MD-10462026-07-04 00:48Y. SutantoMeridian Wrap DressK61A2M104-HARBOUR SAND-S/M1UnknownUnknownYESExact style, color, and size match.
#MD-10462026-07-04 00:48Y. SutantoEmber KaftanK61E4K402-EMBER SKY-S/M3MERIDIAN Lowfield WarehouseFulfillment.locationPARTIALPartial: 2 of 3 available.

The real export carries thirty-odd columns, half of them shipping and billing address fields. Those are not modelled here — there is no version of this page where inventing eighteen columns of address data is the right call.

What is real, and what is simulated

Runs in your browser

  • The warehouse preference ladder — Fulfillment.location, then FulfillmentOrder.assignedLocation preferring the live name over the snapshot, then Unknown. Inventory levels are never consulted
  • The fan-out that turns one split line into one row per location, and the merge and sort that order them
  • The garment SKU parser, the normaliser, and the fallback that decides where colour and size come from
  • The stock index over positive balances only, and the four verdicts — Yes with contributing locations sorted by balance, Partial with N of M, No, Review
  • The Asia/Makassar to explicit-UTC day-bound conversion, and the created_at fragment it produces

Ported from warehouse.py (154 lines), matcher.py (69), parsing.py (61), timezone.py (79) and the pure transform inside orders.py. The Python needs a Shopify request context and three Google Sheets to run, so there is no golden digest to diff against — instead every rule those modules state in prose is a test. 64 of them.

Simulated

  • Shopify's Admin GraphQL API, the two-pass cost-aware pagination around its 1000-point per-query cap, the retry and throttle handling, and the client-credentials token that refreshes every 24 hours
  • Google Sheets and the service account that reads the three stock sheets. The “sheets unreachable” switch below is an injected fault, not a real failure — but the degradation it triggers is the real code path
  • The auth chain in front of the app: IAP on Cloud Run, oauth2-proxy behind Caddy on the VM, both against a Workspace domain allow-list
  • Excel, CSV and Google Sheets output. The preview below is the row shape, not a file
  • The export's shipping and billing address columns, which are deliberately not modelled here
  • Every order, customer, product, SKU, barcode, location and stock row — all fabricated for this page