The Inventory Supply Plan page at portal.cremecollective.com/admin/analytics/inventory is a direct replacement for the Tableau "Inventory Supply Plan" dashboard previously used by the Creme Collective team. It is designed to answer one core question for each brand: does current inventory cover projected demand over the next 3 to 6 months, and by how much?
For Sweed, the page shows one row per SKU. Each row includes the current inventory position (on-hand, committed, in-transit), trailing sales usage over the past 12 months broken down by month, a 6-month forward demand forecast, and the resulting shortage figures.
| Column group | What it means |
|---|---|
| On Hand | Units physically in Camelot's warehouse attributed to this SKU and client. |
| Committed | Units already reserved against open outbound orders — not yet shipped but spoken for. |
| In Transit | Units inbound to the warehouse, not yet available for fulfillment. |
| Inventory | Net available stock: On Hand minus Committed. |
| 1M – 12M Usage | Actual units shipped in each of the past 12 calendar months. |
| 6M Usage / 12M Usage | Total units shipped over the trailing 6 and 12 months respectively. |
| Forecast Month 1–6 | Projected units needed each month for the next 6 months. |
| 3M Demand / 6M Demand | Sum of forecasted units over the next 3 and 6 months. |
| 3M Shortage / 6M Shortage | How far short current inventory falls against the 3M and 6M demand forecast. Zero means inventory covers demand. |
All data originates from Camelot 3PL Cloud — the warehouse management system Creme Collective uses for fulfillment. DataStudios accesses Camelot via its OData API, a standard interface that exposes warehouse data as queryable web endpoints.
Two Camelot endpoints feed the Sweed supply plan:
| Camelot endpoint | What it contains | Load method | Frequency |
|---|---|---|---|
| SalesDetailByBrand | Every shipped order line, by brand. This is the source of all historical sales and usage data. | Delete rows for dates in the payload, then re-insert. Handles late corrections to shipped orders. | Daily, ~2:00 AM ET |
| InventoryByItemWhseSummary | Current inventory levels per SKU per warehouse. On-hand, reserved, inbound quantities. | Full replacement — previous data is discarded and today's snapshot is loaded fresh. | Daily, ~2:00 AM ET |
The pipeline runs automatically each night. Today's run (May 21, 2026) completed in 134 minutes, ingesting 48,880 sales lines and 1,489 inventory records across all Creme Collective brands.
Data passes through four layers between Camelot and the portal. Each layer applies transformations to clean, enrich, or compute on the raw data.
SalesDetailByBrand — shipped order lines by brand, paginated, ~49K records for all Creme brands.InventoryByItemWhseSummary — current inventory snapshot per SKU/warehouse, ~1.5K records.
bronze_camelot.salesdetailbybrand — raw sales lines as received from the API, no transformations applied.bronze_camelot.inventorybyitemwhsesummary — raw inventory snapshot. Fully replaced each run.bronze_camelot.sales_analysis_report_historical — static historical sales table loaded once, covering periods before the current pipeline was live.
silver_camelot.sales_detail_by_brand — deduplication of pending sales lines (handles a known Camelot API quirk where pending orders can appear multiple times), address enrichment, and column standardisation.silver_camelot.inventory_by_item_whse_summary — renamed columns, units of measure standardised, metadata added.
gold_camelot.sales_analysis_report — current and historical sales combined, with address gaps filled from the most recent known address per customer. This is the foundation for all usage and forecast calculations.gold_camelot.supply_plan_forecast — one row per SKU per brand per day. Contains all trailing usage metrics, 6-month forward forecast, and inventory position. Written by a Python model that runs after dbt. This is the table the portal reads directly.
gold_camelot.supply_plan_forecast for the selected client. Always shows the most recent day's data. Column layout is driven by a metadata table (gold_camelot.tableau_column_mapping) so columns can be reordered or renamed without a code change.
The forecast is computed once per day for each SKU. It uses only actual shipped sales history from Camelot — no external demand signals or manual overrides. The method is a trailing average with compound growth projection.
gold_camelot.sales_analysis_report.Sweed-specific: tester SKU consolidation. Sweed sells products both as standard units and as tester units (SKU prefix T-, e.g. T-552 alongside 552). For forecasting purposes, tester sales are merged into the base SKU before calculating usage — so the forecast for SKU 552 reflects total sell-through of that product regardless of whether it was sold as a tester or a standard unit. This matches how supply planning should work: a tester unit consumes the same physical product as a standard unit.
Camelot tracks Sweed under two client codes: SWEED (wholesale / retail orders) and SWEED DTC (direct-to-consumer / internet orders). The portal shows them as separate rows in the client dropdown. Before deciding how to treat inventory across these two codes, we analysed the underlying data to understand whether they represent one physical stock pool or two separate ones.
During this analysis, a significant issue was identified in the current data. The four inventory position columns — On Hand, Committed, In Transit, and Inventory — are hardcoded to zero for every SKU and every brand in the portal today.
This is not a data availability problem. Camelot provides real inventory figures through the InventoryByItemWhseSummary API endpoint, and this data is ingested into the database every night. The issue is that the transformation step that builds the supply plan table reads the sales data correctly but substitutes zeros instead of looking up the inventory figures.
The usage and forecast columns are not affected by this issue — those are computed correctly from sales history. Only the inventory position and shortage columns are wrong.
The transformation that builds the supply plan table will be updated to look up real inventory figures from silver_camelot.inventory_by_item_whse_summary instead of substituting zeros. The following rules apply:
| Column | Source field | Logic |
|---|---|---|
| On Hand | qty_on_hand | Sum across SWEED + SWEED DTC, grouped by SKU. |
| Committed | qty_reserved | Sum across SWEED + SWEED DTC, grouped by SKU. |
| In Transit | qty_inbound | Sum across SWEED + SWEED DTC, grouped by SKU. |
| Inventory | qty_on_hand − qty_reserved | Net uncommitted stock available for fulfillment. |
SKUs with no inventory record (discontinued lines, non-stockable items, artwork files, work orders) will remain at zero — which is the correct value for those items.
Tester SKUs (prefix T-) are stripped before the inventory lookup, consistent with how tester sales are handled in the forecast. A tester unit's stock is counted toward the base SKU's on-hand total.
The fix will take effect starting with the next nightly pipeline run following deployment. No manual data entry or reprocessing is required.
| Limitation | Detail | Status |
|---|---|---|
| No historical inventory data | Camelot's API only returns today's inventory. The supply plan table stores a daily snapshot going back to January 2026, but all historical rows have inventory = 0 because the data was never available. The portal always shows the latest snapshot, so this does not affect what users see today. If trend analysis on inventory position over time is needed in the future, a separate mechanism to log daily inventory snapshots would need to be built. | Accepted |
| Fixed growth rate | The 2.5% monthly growth assumption applied to all Sweed SKUs does not reflect actual SKU-level trends. A declining product will show an upward forecast. Future improvement: derive per-SKU trend from the trailing 12 months of sales data. | Future |
| No seasonality | The forecast uses trailing averages without adjusting for seasonal patterns. SKUs with strong Q4 demand will be underforecasted in Q3 models and overforecasted in Q1 models. | Future |
| Non-stockable SKUs in forecast | A small number of Sweed SKUs represent non-physical items (shipping boxes, brochures, artwork files, work orders) that were fulfilled through Camelot and appear in sales history. These are included in the forecast with zero inventory, which is correct but adds noise to the report. A SKU exclusion list can be added if needed. | Accepted |
| Inventory position is zeroed | All inventory columns currently show zero due to the issue described in Section 6. This is being corrected. | Fix in progress |
| Camelot client code split | Camelot's administrative split of Sweed stock between SWEED and SWEED DTC client codes does not reflect a physical separation. The combined inventory approach (Section 5) is an approximation of the true available stock. If Camelot ever formally segregates the two pools, this logic will need revisiting. | Monitored |