offdataai
Supply Chain & Logistics · data model template

Inventory Analytics data model

Kimball warehouse for inventory: a daily periodic inventory snapshot at product/location/lot grain, a transaction-grain movement fact for receipts/issues/transfers, and a stockout fact quantifying lost sales over conformed product/location/supplier/uom/lot dimensions.

Inventory analytics covering daily stock positions, inventory movements, and stockout events across locations and lots — a Kimball star schema with conformed product (SCD2), location, supplier, unit-of-measure, and lot dimensions for stock-on-hand, turns, days-of-supply, and availability reporting. It is a Kimball dimensional model: fact tables at a declared grain surrounded by conformed dimensions, ready for BI tools and a semantic layer.

KimballSupply Chain & LogisticsSOXGMP
13
tables
128
columns
22
relationships
0
PII columns

Opening the template creates a project with the ERD, platform-native DDL, a dbt project and documentation already generated (recommended platform: Snowflake). Edit it in plain English or on the canvas, then ship it to any supported warehouse.

Subject areas

stock_positionmovementsavailabilityrecord_accuracyconformed_dimensions

Design decisions

  • Daily snapshot plus transaction movements (twin facts)

    Stock on hand is semi-additive and needed daily for turns and days-of-supply, while movements are fully additive transactions; modeling both lets queries reconcile balances against flows.

  • Lot as a conformed dimension

    Batch/lot tracking is required for expiry, recall, and FEFO control; modeling the lot as its own dimension supports both snapshot and movement facts without repeating lot attributes.

  • Dedicated stockout fact

    Service-level and lost-sales reporting needs a record per stockout occurrence with duration and unmet demand, which would not be expressible from snapshot or movement grains alone.

  • Product modeled as SCD2

    Reorder points, ABC class, and standard cost change over time and must align with the product version in effect at each snapshot and movement for accurate valuation history.

Tables in the Inventory Analytics model

Every table with its grain, columns, types and keys. PK marks a primary key, BK a business key and PII a column classified as personal data, which gets a masking strategy by default.

Fact tables (4)

fct_inventory_snapshot

Grain: one row per product per location per lot per day (periodic snapshot)

Daily inventory position snapshot — semi-additive stock levels.

ColumnTypeKeys
date_keybigint
product_keybigint
location_keybigint
lot_keybigint
uom_keybigint
owner_keybigint
on_hand_quantityinteger
available_quantityinteger
allocated_quantityinteger
quarantine_quantityinteger
in_transit_quantityinteger
inventory_valuedecimal
standard_costdecimal
days_of_supplydecimal
inventory_turnsdecimal
is_below_reorder_pointboolean
is_excessboolean

fct_inventory_movement

Grain: one row per inventory movement transaction

Transaction-grain movement fact — additive receipts, issues, transfers.

ColumnTypeKeys
inventory_movement_keybigintPK
date_keybigint
product_keybigint
location_keybigint
supplier_keybigint
lot_keybigint
uom_keybigint
movement_type_keybigint
adjustment_reason_keybigint
transaction_idvarchar
reference_documentvarchar
quantityinteger
unit_costdecimal
extended_costdecimal
running_balanceinteger
is_adjustmentboolean

fct_stockout

Grain: one row per stockout occurrence

Transaction-grain stockout fact quantifying lost sales and service impact.

ColumnTypeKeys
stockout_keybigintPK
date_keybigint
product_keybigint
location_keybigint
recovery_date_keybigint
stockout_idvarchar
duration_hoursdecimal
unmet_demand_quantityinteger
lost_sales_amountdecimal
backorder_quantityinteger
root_causevarchar
is_recoveredboolean

fct_cycle_count

Grain: one row per cycle-count line

Transaction-grain cycle-count fact for inventory record accuracy.

ColumnTypeKeys
cycle_count_keybigintPK
date_keybigint
product_keybigint
location_keybigint
lot_keybigint
adjustment_reason_keybigint
count_idvarchar
system_quantityinteger
counted_quantityinteger
variance_quantityinteger
abs_variance_quantityinteger
variance_valuedecimal
count_accuracy_pctdecimal
is_matchboolean
is_recount_requiredboolean

Dimension tables (6)

dim_date

Grain: one row per calendar day

ColumnTypeKeys
date_keybigintPK
full_datedateBK
day_of_weeksmallint
month_numbersmallint
quartersmallint
yearsmallint
fiscal_periodvarchar
is_business_dayboolean
is_period_endboolean

dim_product

Grain: one row per product per SCD2 version

SCD type 2

ColumnTypeKeys
product_keybigintPK
product_idvarcharBK
skuvarchar
product_namevarchar
product_categoryvarchar
product_subcategoryvarchar
brandvarchar
abc_classvarchar
is_perishableboolean
shelf_life_daysinteger
standard_costdecimal
reorder_pointinteger
safety_stockinteger
is_activeboolean

dim_location

Grain: one row per stocking location

ColumnTypeKeys
location_keybigintPK
location_idvarcharBK
location_namevarchar
location_typevarchar
warehouse_codevarchar
zonevarchar
cityvarchar
statevarchar
countryvarchar
regionvarchar

dim_supplier

Grain: one row per supplier

ColumnTypeKeys
supplier_keybigintPK
supplier_idvarcharBK
supplier_namevarchar
supplier_tiervarchar
countryvarchar
lead_time_daysinteger
min_order_quantityinteger
is_approvedboolean

dim_lot

Grain: one row per inventory lot / batch

ColumnTypeKeys
lot_keybigintPK
lot_idvarcharBK
lot_numbervarchar
manufacture_datedate
expiry_datedate
country_of_originvarchar
quality_statusvarchar

dim_owner

Grain: one row per inventory owner / business unit

ColumnTypeKeys
owner_keybigintPK
owner_idvarcharBK
owner_namevarchar
ownership_typevarchar
business_unitvarchar
cost_centervarchar

Lookup tables (3)

dim_uom

Grain: one row per unit of measure

ColumnTypeKeys
uom_keybigintPK
uom_codevarcharBK
uom_namevarchar
uom_typevarchar
base_conversion_factordecimal

dim_movement_type

Grain: one row per movement type

ColumnTypeKeys
movement_type_keybigintPK
movement_codevarcharBK
movement_namevarchar
directionvarchar
affects_valuationboolean

dim_adjustment_reason

Grain: one row per adjustment reason

ColumnTypeKeys
adjustment_reason_keybigintPK
reason_codevarcharBK
reason_namevarchar
reason_groupvarchar

Relationships

Each relationship is a foreign key on the first table referencing the second.

  • fct_inventory_snapshot.date_key → dim_date (many-to-one)
  • fct_inventory_snapshot.product_key → dim_product (many-to-one)
  • fct_inventory_snapshot.location_key → dim_location (many-to-one)
  • fct_inventory_snapshot.lot_key → dim_lot (many-to-one)
  • fct_inventory_snapshot.uom_key → dim_uom (many-to-one)
  • fct_inventory_snapshot.owner_key → dim_owner (many-to-one)
  • fct_inventory_movement.date_key → dim_date (many-to-one)
  • fct_inventory_movement.product_key → dim_product (many-to-one)
  • fct_inventory_movement.location_key → dim_location (many-to-one)
  • fct_inventory_movement.supplier_key → dim_supplier (many-to-one)
  • fct_inventory_movement.lot_key → dim_lot (many-to-one)
  • fct_inventory_movement.uom_key → dim_uom (many-to-one)
  • fct_inventory_movement.movement_type_key → dim_movement_type (many-to-one)
  • fct_inventory_movement.adjustment_reason_key → dim_adjustment_reason (many-to-one)
  • fct_stockout.date_key → dim_date (many-to-one)
  • fct_stockout.product_key → dim_product (many-to-one)
  • fct_stockout.location_key → dim_location (many-to-one)
  • fct_cycle_count.date_key → dim_date (many-to-one)
  • fct_cycle_count.product_key → dim_product (many-to-one)
  • fct_cycle_count.location_key → dim_location (many-to-one)
  • fct_cycle_count.lot_key → dim_lot (many-to-one)
  • fct_cycle_count.adjustment_reason_key → dim_adjustment_reason (many-to-one)

Related templates

All templates →
Start for $1

From requirements to AI-ready context, in one platform.

Describe your business in a conversation, start from a template or connect your own database. Your first model is ready in minutes.

Get startedBook a demo

Plans from $1/month · cancel any time