Skip to content

Commit

Permalink
Merge pull request solidusio#2539 from benjaminwil/stock_management_i…
Browse files Browse the repository at this point in the history
…nventory_documentation

Add documentation for stock items and stock movements
  • Loading branch information
jhawthorn authored Feb 15, 2018
2 parents 6978887 + 9bc3811 commit 5fedcf4
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
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`.)

0 comments on commit 5fedcf4

Please sign in to comment.