Hide menu Last updated: Oct 12 2015

This topic describes the multiple inventory locations concept in Episerver Commerce. You can define multiple inventory locations in the system. These are any place that has inventory that you want to track, whether that is a warehouse you are using for your shipping, individual stores, a factory, or whatever meets your needs. You could even include any trucks you have driving around delivering orders.

Currently only shipping from one central warehouse location is supported. If you have multiple shipping sources but you do not want to customize Commerce, then you can still track overall inventory in Commerce but you have to figure out your shipment fulfillment logistics from your individual shipment locations on your own outside of Commerce.

In-store pickup from any store location is provided, which can handle any number of locations that are defined as places for pickup (but not for fulfillment). In our definitions these are Fulfillment Centers from which you can ship, and Pickup Locations to which a customer can come to pick up an order. Without customizing Commerce you can have only one Fulfillment Center, but you can have as many Pickup Locations as you like.

These limitations exists because no one knows your business like you. Some business logic to support fulfillment from multiple locations is provided in the sample code. However each business has its own approach to its fulfillment practices and no logic supports more than a few situations at a time.

Fulfillment technical details

The changes to support multiple locations cross infrastructural code are hidden in the assemblies, new services, and logic that is visible in the workflows. The infrastructural changes will not matter to most customers, although they may affect some existing customized installations. You may implement your needs directly in the workflows or by replacing the services.


The core business logic for inventory and shipping is implemented in the Workflows. The key places to look for these are:

There is no implementation for multiple fulfillment centers out of the box. If you wish to have multiple fulfillment centers, you will need to:

  1. Disable the current lockout (required), and
  2. Implement custom warehouse selection logic (required), and possibly
  3. Implement custom inventory management logic (optional).

The modifications required for each of these are detailed below.

Disable the lockout

The first of these is simple. The default installation is designed to raise an exception for certain operations when there are multiple warehouses flagged as fulfillment centers. This exception is raised in the OrderGroupActivities\OrderGroupActivitiyBase workflow, in the CheckMultiWarehouse() method. The method is called from multiple locations (e.g. AdjustInventoryActivity.cs, AdjustInstoreInventoryActivity.cs at the time of this writing) so it is easier to clear the contents rather than removing all references. To allow multiple fulfillment warehouses you can replace the existing method with the following:

protected virtual void CheckMultiWarehouse(){}

...or add whatever consistency checks meet your needs.

Custom warehouse selection

The second part is the major piece of the implementation, and cannot be described in depth since the actual logic is going to be dependent entirely on the needs of a particular business. This guide will only cover the places in the system where an implementation may need to override the default logic.

The main piece of business logic you will need to replace is found in this workflow, in the GetFulfillmentWarehouseForLineItem() method. In the default implementation it does little more than find the default warehouse (see line 87). You will need to replace this with your custom logic.

As workflow inherits from OrderGroupActivity, you already have an OrderGroup and its data available for all calculations and logic. To determine your list of warehouses and information about their available inventory, access two new service interfaces that were added for release 7. These are the IWarehouseRepository and IWarehouseInventoryService. These can be instanced in code via the following:


See Warehouse/Inventory Services in this topic for further details. The current interfaces should be straightforward to use, although you may need to expand upon their functionality if you need additional information (e.g. geolocation) to determine your fulfillment warehouse selection.

ShipmentSplitActivity also has a reference to warehouses that may be of interest. Currently when a new split shipment is created, it is marked as sourcing from the same warehouse as its first line item. This works for a single fulfillment warehouse and in-store pickup, but may not function as desired for a more complicated multi-warehouse solution. Examine the SplitForm() method and determine whether this works for your custom solution and adjust it if not.

Custom inventory management (optional)

The existing Commerce workflows are able to manage the inventory in your individual warehouses out of the box, as long as your custom warehouse selection logic assigns the correct warehouse for each line item. However if you need to change the actual processing logic for inventory, such as changing how backorders and preorders are handled or to trigger external processes to balance inventories between warehouses as inventories get low, then you will need to change the logic in AdjustInventoryActivity to suit your needs. The main method in which to do so is AdjustStockItemQuantity().

The default implementation of the in-store pickup feature handles the store inventories out of the box, but you may also want to consider additional inventory handling here such as to resupply store inventory. The handling for in-store pickup inventories is found in AdjustInstoreInventoryActivity and CheckInstoreInventoryActivity. The former is probably the correct place to modify this for most implementations, but you can consider adjusting the latter instead.

Note: The HandoffActivityBase activity includes support for in-store pickup. It is not necessary to change this, but if you choose to disable all in-store pickup functionality then you should consider removing the code from this also. These include the PickupWarehouseInShipmentProperty dependency and PickupWarehouseInShipment property and these need simply be deleted.

Warehouse/inventory services

Many of the functions for accessing warehouse and inventory data were moved into services, which you can replace in your implementation. However, the default implementations work with the existing Episerver Commerce controls and database as-is. This could be useful if you want to encapsulate the current implementation to provide more methods (e.g. to support geolocation-based fulfillment logic) or if you wish to replace them entirely to manage your inventory with a new or external system.

If you do wish to implement custom inventory integration, there are 2 main services to consider:

You should review the interfaces for the required properties and methods which is documented in the method signatures and should be self-explanatory in terms of the expected input and output values. What you need to do depends on the scope of your changes and need to be considered on a case-by-case basis.

Note: The recommended model for managing inventory data across separate ERP and EPiServer Commerce systems is to update Commerce on a scheduled basis and allow Commerce to track inventory internally in the time between updates. Allowing Commerce to manage its own inventory provides the best performance in almost all situations. The main issue from a business standpoint is whether inventory is being sold (or otherwise removed) independently of Commerce, in which case you need to find some way to reconcile orders, by updating Commerce on-the-fly or by an appropriate backorder process.

You need to consider carefully the pros and cons of the various approaches (for instance development costs for integrations, and whether is worth incurring the higher latency costs of communicating with your ERP directly so that you have perfectly accurate numbers at all times). When you review these interfaces, some of the interfaces may be switched to use business objects instead of ID fields in the future.