Skip to content

Stock History

First-Pass Node Dossier

This page is an example of the node-level documentation format generated from the domain hierarchy and questionnaire work.

What It Is

StockHistory is a supporting audit record, not a primary business object. It stores quantity changes over time using:

  • stock_before
  • stock_after
  • stock_difference
  • timestamps
  • a polymorphic causer

In the inspected codebase, the practical source of StockHistory rows is ProductInventoryItem changes.

Parent hierarchy:

  • Inventory & Vendor Supply
  • Inventory State
  • Stock History

Primary implementation paths:

  • packages/framework/src/Models/StockHistory.php
  • packages/framework/src/Models/Traits/StockHistoriesTrait.php
  • packages/framework/src/Actions/StockHistory/LogStockHistory.php
  • packages/framework/src/Observers/ProductInventoryItemObserver.php

What Users Can Do With It

Direct capabilities

Users can directly:

  • list stock-history rows through the admin API
  • filter by id, causer_type, and causer_id
  • sort by created_at, stock_after, and stock_difference

Things users cannot do directly

In the inspected packaged UI and API, users cannot directly:

  • create a stock-history row
  • edit a stock-history row
  • delete a stock-history row
  • open a dedicated stock-history detail screen

Source:

  • packages/framework/src/Http/Controllers/Api/Admin/StockHistoriesController.php

Where It Is Managed

ChannelRoleNotes
Admin APIDirect read-onlystock_histories route only exposes index
Admin UIIndirectInventory screens show current stock state, not stock-history rows
StorefrontIndirectUses current inventory state only
ERP / feeds / fulfillmentIndirect upstream inputsThese flows mutate inventory items, which may create stock-history rows
Excel import/exportIndirect upstream inputsNo inspected sheet directly imports or exports StockHistory

Creation Model

StockHistory is system-generated.

The effective write path is:

  1. a ProductInventoryItem changes
  2. ProductInventoryItemObserver sees available as dirty
  3. the observer calls logStockHistory()
  4. LogStockHistory compares the new value to the latest prior history row
  5. a new row is created only if the quantity actually changed

Sources:

  • packages/framework/src/Observers/ProductInventoryItemObserver.php
  • packages/framework/src/Models/Traits/StockHistoriesTrait.php
  • packages/framework/src/Actions/StockHistory/LogStockHistory.php

Configuration And Data Model

Key model characteristics:

  • plain Eloquent model
  • polymorphic causer
  • integer casts for stock values
  • no soft deletes
  • no explicit status/state machine

Important caveat:

  • if there is no prior stock-history row, LogStockHistory starts from stock_before = 0
  • initial inventory-item creation does not seed a first history row

That means the first logged change after creation may not reflect the true original quantity.

Sources:

  • packages/framework/src/Models/StockHistory.php
  • packages/framework/database/migrations/2022_11_26_132348_create_stock_histories_table.php
  • packages/framework/src/Actions/StockHistory/LogStockHistory.php
  • packages/framework/src/Observers/ProductInventoryItemObserver.php

Relationships

Direct relationship:

  • causer()

Practical owner in the inspected framework:

  • ProductInventoryItem

Trait-based accessors added to the owning model:

  • stockHistories()
  • latestStockHistory()
  • oldestStockHistory()

Sources:

  • packages/framework/src/Models/StockHistory.php
  • packages/framework/src/Models/Traits/StockHistoriesTrait.php
  • packages/framework/src/Models/ProductInventoryItem.php

Rules And Downstream Effects

Logging rules

A history row is created only when:

  • ProductInventoryItem.available changes

It is not created when only:

  • backorder_allowed changes
  • discontinued changes

Additional side effects on the same inventory update

When inventory-item state changes, the observer also queues product stock recalculation. That recalculation can update:

  • product stock_level
  • product stock_status
  • product stock_purchasable
  • product discontinuation-driven stock behavior

Sources:

  • packages/framework/src/Observers/ProductInventoryItemObserver.php
  • packages/framework/src/Actions/Product/CalculateStock.php

Where It Appears In The Product

StockHistory is mostly invisible to end users.

What appears in packaged UIs instead:

  • current availability badges
  • current inventory tables
  • current stock status on storefront product views

The inspected admin and storefront resources do not nest stock_histories inside their inventory-item payloads.

Sources:

  • packages/admin/resources/views/components/product-inventory-item/availability-field.blade.php
  • packages/admin/resources/views/components/product-inventory-item/availability-dialog.blade.php
  • packages/admin/resources/views/components/inventory/data-table.blade.php
  • packages/framework/src/Http/Resources/Admin/ProductInventoryItemResource.php
  • packages/framework/src/Http/Resources/Storefront/ProductInventoryItemResource.php
  • packages/storefront/resources/views/components/product/stock-status.blade.php

Integrations And Automation

StockHistory itself is not the sync object for ERP, feeds, or Excel.

Instead, those upstream systems modify ProductInventoryItem, and that can indirectly create stock-history rows.

Examples of upstream inputs:

  • ERP inventory sync
  • vendor feed inventory sync
  • fulfillment debit from inventory

Sources:

  • packages/framework/src/Actions/ErpBridge/ProductInventoryItem/UpdateOrCreateModelFromDTO.php
  • packages/framework/src/Actions/ProductInventoryItem/SyncInventoryItem.php
  • packages/framework/src/Actions/Fulfillment/DebitFulfilledItemsFromInventory.php
  • packages/erp-bridge/src/Requests/ProductInventoryItems/GetProductInventoryItemsRequest.php

Current Documentation Takeaways

The three most important operator-level facts are:

  1. StockHistory is an audit artifact, not something operators manage directly.
  2. The real place to understand or influence it is ProductInventoryItem.
  3. Quantity changes can create both a history row and a queued product stock recalculation, but only some field changes generate history.

Open Questions

  • The concrete generated bindings config that wires the observer is not committed in this repo snapshot, so observer registration is inferred from framework boot logic and the observer class itself.
  • The stock_histories API route exists, but no packaged admin Livewire screen currently appears to consume it directly.