This project is not covered by Drupal’s security advisory policy.

Commerce Inventory is a Drupal 8 inventory/stock module for use with the Commerce suite of modules.

A note on other modules

Another stock module, Commerce Stock, is currently being ported for Drupal 8. For various reasons related to my own needs, I ultimately decided to write this module to handle stock instead of using it. With what I can tell from the thread, a few people have used Commerce Stock and it seemed to work for them for tracking stock on the backend. I encourage everyone to monitor its status and do your own research before deciding on a stock solution. A key difference between the two modules is that Commerce Inventory is built to allow multiple external stock providers to be enabled at one time, as well as allowing orders to be placed and stock be withheld without requiring a connection to the external service (which would be dependent on the selected provider using Commerce Stock).

Architecture

Commerce Inventory is built to be Commerce module agnostic; meaning that Order, Product, and Store aren’t required, but are available as additional installable modules included as part of Commerce Inventory. They give a good example of how easy it is to support other purchasable entity types and how to incorporate Commerce Inventory into Commerce core.

There are 3 entity types:

  • Inventory Locations: where inventory is held. Locations are not the same as Stores. Stores can be associated with Locations, which allows multiple stores to use inventory from the same locations, as well as one store to use inventory from multiple locations (this functionality is available in an included module).
  • Inventory Items: a purchasable entity at an Inventory Location. An example of a purchasable entity is a product variation (which can be enabled via an included module).
  • Inventory Adjustments: a quantity adjustment of a specific Inventory Item. Since this is an entity, this can be used in Views and saved with additional meta data and whatever else.

There are 2 plugin types that work with the entity types:

  • Inventory Providers: These are used as the bundles for Inventory Locations and Inventory Items. This is what allows multiple stock providers to be enabled at the same time, since all locations (and ultimately items) are then tied to a certain provider. This plugin has methods which are called at certain events which allows it to react to adjustments, creation, item validation, etc. Items and Locations have a remote ID setup by default, which the provider can declare that it uses. It also has a method to more-easily provide auto-complete for remote IDs.
  • Inventory Adjustment Type: These are used as bundles for Inventory Adjustments. They allow adjustments to be tracked by type (generic Decrease and Increase, Move To and Move From, Sale, Return, New). They have a method called adjustQuantity, which an adjustment quantity is passed before creation. This allows the type to clean the adjustment and make sure it matches what is supposed to happen (go negative, positive, etc). Providers can create new adjustments to more-easily track whenever they make adjustments (e.g.: “Square external Decrease” or “Lightspeed external Increase”) for adjustments made outside of Drupal.

The module handles inventory count in a few ways:

  • On Hand: The current “On Hand” count of an Inventory Item is automatically calculated from previous adjustments. It is fully handled by the module and isn’t modifiable. This is a cached value that is updated when adjustments are made.
  • Available: The current “Available” count of an Inventory item is the “On Hand” count, but modified via an event to relay what is currently available to be used. This allows modules like the included Commerce Inventory Order module to withhold Product on Orders that have been placed but not fulfilled (this functionality is configurable to meet different needs). This is a cached value that is updated when adjustments are made or when modules specify it should be invalidated.
  • Minimum: This is the minimum amount that the item can drop to before it’s labeled as “out of stock”. An example that is useful would be the ability to allow for back-orders to a certain point, even if the current Inventory Item “On Hand” quantity is 0. This is a cached value that is updated when adjustments are made or when modules specify it should be invalidated.

Finally, there is an Allotment Manager, which allows modules to modify how quantity is allotted to different Inventory Items based on certain criteria. An example would be when a Store uses multiple Inventory Locations, yet one of the Location’s Items doesn’t have enough stock to completely fulfill the request.

Order auto-adjustment/withholding

Settings for auto-withholding or auto-adjustments on Order events can be modified on an Order Item's configuration page.

Providers supported

These are the current inventory/stock providers supported to work with commerce_inventory and also good resources to see how easy it is to support external providers.

Created a Inventory provider? Submit an issue to add your module to the list.

Creator’s note

I created this in my free time for a project that I’ve been working on and haven’t had the ability for real-world testing as of yet. Although from preliminary tests, everything seems to be work correctly. I would encourage anyone interested to feel free to help in any way they can. Either by writing tests, or logging issues, or creating an external provider addition.

Project information

Releases