-
Notifications
You must be signed in to change notification settings - Fork 248
Source Selection Algorithms
Multiple Nodes Inventory (MNI) implies that the products will be stored in multiple locations. When Customer buys the product, it should be shipped from the particular location. A customer usually does not care what location product was shipped from, as soon as this is the cheapest option. For the Merchant, it is important to have minimal overhead for the inventory storage and shipping costs. An algorithm which assigns the particular inventory to the order item should take all these considerations into account and select the best possible options.
When multiple carriers and/or sources are used for delivery, there will be multiple possible shipping combinations that can fulfill the order. Merchants need to be able to present a consolidated shipping amount to the customer, but needs to be able to control which combination is selected. The merchant needs the ability to configure how the shipping amount is calculated in these scenarios, so they can choose the calculation algorithm that best matches their preferences.
- Warehouse, Source - synonyms which are used to identify single location of the inventory storage which has physical address. Merchant may have multiple of those when using multi-node inventory.
- Source selection algorithm - algorithm which decides which source of the inventory should be used to fulfill the order.
To visualize the process of the warehouse selection let's describe the following use-case. Customers create an Order to buy products A, B and C:
Product | Qty |
---|---|
A | 5 |
B | 2 |
C | 7 |
Merchant has following stock quantities in warehouses X, Y and Z
Product | Warehouse | Qty |
---|---|---|
A | X | 10 |
A | Y | 10 |
A | Z | 10 |
B | X | 1 |
B | Y | 1 |
B | Z | 1 |
C | X | 5 |
C | Y | 2 |
C | Z | 7 |
There are multiple possible options on how to fulfill the order:
- Ship 10xA from the Warehouse X, 1xB from the X and 1xB from Z, 5xC from the X and 2xC from Y
- Ship 5xA from X and 5xA from Y, 1xB from the X and 1xB from Z, 7xC from the Z
- etc
As you can see there are multiple possible strategies on how to optimize order fulfillment:
- try to ship as much as possible from one warehouse. This minimizes packaging costs and possibly shipping cost
- try to distribute the load between warehouses. This minimizes storage cost
- select warehouse based on the cost of shipment to the merchant address for the particular Carrier
- select warehouse based on the shipment time
The order fulfillment algorithm should pick the location of the product and use it to calculate the shipping cost.
Earlier implementations of MNI identified the problems with the advanced algorithms of the warehouse selection. For example, if the warehouse selected based on the delivery cost, for every possible combination of warehouses system should perform the API call to the carrier to retrieve the shipping cost.
It is impossible for the Magento platform to predict all the circumstances which affect inventory and shipping costs for the particular merchant. That's why instead of implementing all possible optimizations of the source selection algorithm, the framework will contain the interface which is used to resolve the Source for the order item. Different implementations of the algorithm will contain Implementations, provided by the 3-d party extensions will allow affecting the priorities of the warehouse selection depending on the particular case where Magento is used.
Magento framework will provide the default, rule-based algorithm which allows configuring the priority of warehouses depending on the source origin, shipping address and the selected carrier.
Following interface will be called by the Magento framework at the point of shipment calculation. Changing the implementation of the interface allows affecting the algorithm of the Warehouse resolution.
use Magento\Quote\Model\Quote\Address\RateRequest;
/**
* SourceShippingResolverInterface
*/
interface SourceResolverInterface
{
/**
* Resolve source shipping data
*
* @param RateRequest $request
* @param ShippingRateCalculator $shippingRateCalculator
* @return array
*/
public function resolve(RateRequest $request, ShippingRateCalculator $shippingRateCalculator);
}
Algorithm steps:
- Get list of sources sorted by priority (source attribute)
- Take all available products from 1st source by priority. If some of the products in the order couldn't be delivered from 1st source - get the rest of products from next by priority source. 2.1. Repeat Step 2. until all the products from the order would be ready to shipping.
Delivery to fulfill the order could be made from one or several (more than one) sources 1.1 Evaluate each source for one product delivery 1.2 Fulfill the order by minimal cost sources (result is sum of each value) 1.3 Recalculate shipping cost based on previous step result. Obtained value is displayed for customer.
Shopping Cart:
Product | Qty |
---|---|
A | 2 |
B | 2 |
Warehouses Inventory:
Product | Source | Qty |
---|---|---|
A | X (Flat Rate - 10$) | 100 |
A | Y (Flat Rate - 10$) | 100 |
B | X (Flat Rate - 15$) | 100 |
B | Y (Flat Rate - 15$) | 100 |
- Collect all common sources (with delivery cost) for all products in shopping cart
- 2xA from X, 2xB from X = 10$
- 2xA from Y, 2xB from Y = 15$
- We choose first combination with minimal cost
- 2xA from X, 2xB from X = 10$
Shopping Cart:
Product | Qty |
---|---|
A | 2 |
B | 2 |
Warehouses Inventory:
Product | Source | Qty |
---|---|---|
A | X (Flat Rate - 10$) | 100 |
A | Y (Flat Rate - 10$) | 1 |
B | X (Flat Rate - 15$) | 100 |
B | Y (Flat Rate - 15$) | 1 |
- Collect one product delivery cost for each source:
- (a) 1 Product A from Source X = 10$
- (b) 1 Product A from Source Y = 15$
- (c) 1 Product B from Source X = 10$
- (d) 1 Product B from Source Y = 15$
- Fulfill the order by minimal cost sources:
- (2 * a) + (1 * c) + (1 * d)
- Recalculation:
- We can see that we have two products going to be delivered from single stock, but we used Flat Rate cost twice. So we need to repeat calculation based on result from prev step: 25$ (this value is displayed for customer)
Shopping Cart:
Product | Qty |
---|---|
A | 2 |
B | 3 |
C | 4 |
Warehouses Inventory:
Product | Warehouse | Qty |
---|---|---|
A | X | 100 |
A | Y | 100 |
B | X | 2 |
B | Y | 2 |
C | X | 2 |
C | Y | 2 |
- Collect one product delivery cost for each source:
- (a) 1 Product A from Source 1 = 10$
- (b) 1 Product A from Source 2 = 15$
- (c) 1 Product B from Source 1 = 10$
- (d) 1 Product B from Source 2 = 15$
- (e) 1 Product C from Source 1 = 10$
- (f) 1 Product C from Source 2 = 15$
- Fulfill the order by minimal cost sources:
- (2 * a) // Product A is fulfill
- (2 * c) + (1 * d)
- (2 * c) + (1 * d) // Product B is fulfill
- (2 * e) + (2 * f) // Product C is fulfill
- Recalculation
- We can see that we have two products going to be delivered from single stock, but we used Flat Rate cost twice. So we need to repeat calculation based on result from prev step: 25$ (this value is display for customer)
Magento will allow creating rules of selecting the fulfillment warehouse based on following pieces of information:
- warehouses addresses
- customer shipping address
- carrier
The rules will be defined in the format: (Customer State, Carrier) -> Warehouse
The rules will be configured in the CSV file and imported to the Magento.
Following items need to be implemented in order to make Warehouse selection work in Magento:
- Create interface of the Warehouse resolution
- Inject interface to the Magento framework and use it during shipping rate calculation. Implement it for complex cases such as Bundle or Grouped products.
- Make information on selected warehouse reflected on the Order and be available during the fulfillment
- Implement default algorithm which works based on configured rules
- implement import of rules via CSV File
Multi-Source Inventory developed by Magento 2 Community
- Technical Vision. Catalog Inventory
- Installation Guide
- List of Inventory APIs and their legacy analogs
- MSI Roadmap
- Known Issues in Order Lifecycle
- MSI User Guide
- 2.3 LIVE User Guide
- MSI Release Notes and Installation
- Overview
- Get Started with MSI
- MSI features and processes
- Global and Product Settings
- Configure Source Selection Algorithm
- Create Sources
- Create Stock
- Assign Inventory and Product Notifications
- Configure MSI backorders
- MSI Import and Export Product Data
- Mass Action Tool
- Shipment and Order Management
- CLI reference
- Reports and MSI
- MSI FAQs
- DevDocs Documentation
- Manage Inventory Management Modules (install/upgrade info)
- Inventory Management
- Reservations
- Inventory CLI reference
- Inventory API reference
- Inventory In-Store Pickup API reference
- Order Processing with Inventory Management
- Managing sources
- Managing stocks
- Link and unlink stocks and sources
- Manage source items
- Perform bulk actions
- Manage Low-Quantity Notifications
- Check salable quantities
- Manage source selection algorithms
- User Stories
- Support of Store Pickup for MSI
- Product list assignment per Source
- Source assignment per Product
- Stocks to Sales Channel Mapping
- Adapt Product Import/Export to support multi Sourcing
- Introduce SourceCode attribute for Source and SourceItem entities
- Assign Source Selector for Processing of Returns Credit Memo
- User Scenarios:
- Technical Designs:
- Module Structure in MSI
- When should an interface go into the Model directory and when should it go in the Api directory?
- Source and Stock Item configuration Design and DB structure
- Stock and Source Configuration design
- Open Technical Questions
- Inconsistent saving of Stock Data
- Source API
- Source WebAPI
- Sources to Sales Channels mapping
- Service Contracts MSI
- Salable Quantity Calculation and Mechanism of Reservations
- StockItem indexation
- Web API and How To cover them with Functional Testing
- Source Selection Algorithms
- Validation of Domain Entities
- PHP 7 Syntax usage for Magento contribution
- The first step towards pre generated IDs. And how this will improve your Integration tests
- The Concept of Default Source and Domain Driven Design
- Extension Point of Product Import/Export
- Source Selection Algorithm
- SourceItem Entity Extension
- Design Document for changing SerializerInterface
- Stock Management for Order Cancelation
- Admin UI
- MFTF Extension Tests
- Weekly MSI Demos
- Tutorials