Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for stock items and stock movements #2539

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions guides/inventory/stock-items.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Stock items

On-hand inventory is tracked using the `Spree::StockItem` model. A stock item
tracks stock at a single `Spree::StockLocation`.

If you only track stock at one stock location, then every `Spree::Variant` in
your store has one corresponding `Spree::StockItem` object. If you track stock
at two stock locations, then every `Spree::Variant` in your store has *two*
corresponding `Spree::StockItem`s: one for each `Spree::StockLocation`.

The `Spree::StockItem`'s `count_on_hand` value that represents the number of
items you have in stock.

`Spree::StockItem` objects have the following attributes:

- `stock_location_id`: The ID for the `Spree::StockLocation` where the stock
item is located.
- `variant_id`: The ID for the `Spree::Variant` that this stock item represents.
- `count_on_hand`: The number of units currently in inventory. See [Count on
hand](#count-on-hand) for more information.
- `backorderable`: Sets whether the stock item should be
[backorderable](#backorderable-stock-items).
- `deleted_at`: A timestamp that logs when this stock item was deleted from
inventory. Otherwise, the value is `nil`.

## Count on hand

When administrators create a new product using the `solidus_backend`, they can
set an initial inventory "Count On Hand" value for the new product.

The `count_on_hand` value changes whenever a [stock movement][stock-movements]
occurs. For example, if one unit of a product is sold the `count_on_hand` would
decrease by one.

### Changing the count on hand value

While a `Spree::StockMovement` object logs the increase or decrease of the
`count_on_hand` value, administrators can also edit the count on hand from the
`solidus_backend`.

Whenever an administrator updates the count on hand, they are discarding the old
value completely. So, if a stock item's `count_on_hand` is `5`, when the
administrator changes the value to `20`, they are creating a
`Spree::StockMovement` with a value of `15`.

See the [Stock movements][stock-movements] article for more information.

[stock-movements]: stock-movements.md

## Backorderable stock items

If a `Spree::StockItem` is `backorderable`, then customers can continue to order
it after the product is sold out. When a sold out product continues to sell, the
`count_on_hand` becomes a negative integer.

For example, if a customer orders five backorderable items and its
`count_on_hand` becomes `-5`, the customer can still check out successfully.
[Inventory units][inventory-units] with the `state` value of `backordered` are
created for the five items.

The `Spree::Shipment`(s) associated with the backordered items cannot be shipped
until the stock has been replenished. Once the item is in stock again, each
backordered inventory unit's `state` value is changed from `backordered` to
`on_hand` and the shipment becomes shippable.

[inventory-units]: inventory-units.md
58 changes: 58 additions & 0 deletions guides/inventory/stock-movements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Stock movements

A `Spree::StockMovement` object is created every time that a stock item moves in
or out of a stock location. This objects documents how many items were added or
removed.

The `Spree::StockMovement` model has the following attributes:

- `stock_item_id`: The ID of the `Spree::StockItem` the movement is related to.
- `quantity`: The amount of stock items added or removed from the
`Spree::StockItem`'s `count_on_hand` value.
- `originator_type` and `originator_id`: The model and ID of an object that
initiated the creation of the current stock movement. For example, an
originator could be an administrator (a `Spree::User`) adding new stock or a
`Spree::Shipment` being created after an order is placed.

<!-- TODO:
There is an additional attribute: `action`. It seems to always be `nil`.
Looking at some legacy code, it used to equal either `sold` or `received`,
describing what kind of movement was taking place. Now, `action` does nothing
out of the box, but it could be repurposed by a store's shipping/fulfillment
departments.
-->

## Usage example

A typical example of a stock movement would be when a customer buys an item from
your store:

1. A stock item has a `count_on_hand` value of `20`.
2. A customer buys one unit of its associated variant.
3. A new `Spree::StockMovement` object is created.
- It has a `quantity` of `-1`.
- It has a `originator_type` of `Spree::Shipment` because a new shipment
triggered the movement.
4. The stock item's `count_on_hand` value is updated to `19`.

## Administrating inventory

Administrators can generate stock movements by changing the "Count On Hand"
value for a stock item in the `solidus_backend` (on the **Stock** page).
However, they cannot create a stock movement directly.

Because of this, Solidus has no concept of *adding to* existing inventory. For
example:

- A stock item has a `count_on_hand` value of `7`.
- A store administrator receives 25 new items to add to inventory.
- They log into the backend and change the count on hand from `7` to `33`.
- This creates a new `Spree::StockMovement` with a quantity of `25`. (`7 + 25 =
33`.)

If an administrator does not account for the units already in stock, they may
enter the wrong value into the "Count On Hand" field for an item.

For example, if the administrator changes the value from `7` to `25`, then the
stock movement only documents that `18` units were added to inventory. (`7 + 18
= 25`.)