diff --git a/guides/data/nav_tree.yml b/guides/data/nav_tree.yml index 704278e58bb..0e0a1b4337a 100644 --- a/guides/data/nav_tree.yml +++ b/guides/data/nav_tree.yml @@ -150,6 +150,8 @@ main: href: "/developers/shipments/cartons.html" - title: "Custom shipping calculators" href: "/developers/shipments/custom-shipping-calculators.html" + - title: "Stock location sorters" + href: "/developers/shipments/stock-location-sorters.html" - title: "Shipment setup examples" href: "/developers/shipments/shipment-setup-examples.html" - title: "Shipping method filters" diff --git a/guides/source/developers/shipments/stock-location-sorters.html.md b/guides/source/developers/shipments/stock-location-sorters.html.md new file mode 100644 index 00000000000..637cf3804f0 --- /dev/null +++ b/guides/source/developers/shipments/stock-location-sorters.html.md @@ -0,0 +1,52 @@ +# Stock location sorters + +This article explains the purpose, interface and correct usage of custom stock location sorters. + +Your app's stock location sorter defines the order in which stock locations are used to allocate +inventory when creating packages for an order. The sorter is called by `Spree::Stock::SimpleCoordinator` +when allocating inventory for an order. + +## Pre-configured sorters + +Currently, we only have two sorters, which you should use unless you need custom logic: + +- [Unsorted](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/stock/sorter/unsorted.rb), + which allocates inventory from stock locations as they are returned from the DB. +- [Default first](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/stock/sorter/default_first.rb), + which allocates inventory from the default stock location first. + +## Custom sorter API + +A custom sorter should inherit from `Spree::Stock::LocationSorter::Base` and implement a `sort` method +which accepts a `Spree::StockLocation::ActiveRecord_Relation` and returns an enumerable of stock +locations. Note that the return value does not have to be an AR relation. + +Here's an example that sorts stock locations by a custom `priority` attribute: + +```ruby +class Spree::Stock::LocationSorter::Priority < Spree::Stock::LocationSorter::Base + def sort + stock_locations.order(priority: :asc) + end +end +``` + +### Switching the sorter + +Once you have created the logic for the new sorter, you need to register it so that it's used by +`Spree::Stock::SimpleCoordinator`. + +For example, you can register it in your `/config/application.rb` initializer: + +```ruby +# /config/application.rb +module MyStore + class Application < Rails::Application + # ... + + initializer 'spree.register.stock_location_sorter' do |app| + app.config.spree.stock.location_sorter_class = 'Spree::Stock::LocationSorter::Priority' + end + end +end +```