Attribute | Description | Example Value |
---|---|---|
number | The unique identifier for this shipment. It begins with the letter H and ends in an 11-digit number. This number is shown to the users, and can be used to find the order by calling Spree::Shipment.find_by(number: number) . | H12345678901 |
tracking | The identifier given for the shipping provider (i.e. FedEx, UPS, etc). | 1Z999AA10123456784 |
shipped_at | The time when the shipment was shipped. | 2021-07-21T14:36:00.000Z |
state | The current state of the shipment. | shipped |
stock_location_id | The ID of the Stock Location where the items for this shipment will be sourced from. | 3 |
pending
ready
shipped
canceled
Name | Zone | Calculator |
---|---|---|
USPS Ground | US | Flexi Rate(2) |
FedEx | EU_VAT | FlatRate-per-item($10) |
S. Category / S. Method | DHL | FedEx | USPS |
---|---|---|---|
Light | Per Item ($5) | Flat Rate ($10) | Per Item ($8) |
Regular | Per Item ($5) | Per Item ($2) | Per Item ($8) |
Heavy | Per Item ($50) | Flexi Rate(15) | Per Item ($20) |
Zone
. For example, you wouldn’t be able to get a package delivered internationally using a domestic-only shipping method. You can’t ship from Dallas, USA to Rio de Janeiro, Brazil using UPS Ground (a US-only carrier).
If you are using shipping categories, these can be used to qualify or disqualify a given shipping method.
Shipping methods can now have multiple shipping categories assigned to them. This allows the shipping methods available to an order to be determined by the shipping categories of the items in a shipment.
Configuration
-> Shipping Categories
) and then assigned to products (Products
-> Edit
).
During checkout, the shipping categories of the products in your order will determine which calculator will be used to price its shipping for each Shipping Method.
Shipment
objects are created during checkout for an order. Initially each records just the shipping method and the order it applies to. The administrator can update the record with the actual shipping cost and a tracking code, and may also (once only) confirm the dispatch. This confirmation causes a shipping date to be set as the time of confirmation.
LineItem
objects and return a cost. It can look at any reachable data, but typically uses the address, the order and the information from variants which are contained in the line_items.
ShippingCategory
, which adds product-specific information to the calculations beyond the standard information from the shipment. Standard information includes:
ShippingCategory
is basically a wrapper for a string. One use is to code up specific rates, eg. “Fixed 40”, from which a calculator could extract imposed prices (and not go through its other calculations).
available?
method returns true
by default. It is, therefore, the zone of the destination address that filters out the shipping methods in most cases. However, in some circumstances it may be necessary to filter out additional shipping methods.
Consider the case of the USPS First Class domestic shipping service, which is not offered if the weight of the package is greater than 13oz. Even though the USPS API does not return the option for First Class in this instance, First Class will appear as an option in the checkout view with an unfortunate value of 0, since it has been set as a Shipping Method.
To ensure that First Class shipping is not available for orders that weigh more than 13oz, the calculator’s available?
method must be overridden as follows:
create_proposed_shipments
on an Order
object while transitioning to the delivery
state during checkout. This process will first delete any existing shipments for an order and then determine the possible shipments available for that order.
create_proposed_shipments
will initially call Spree::Stock::Coordinator.new(@order).packages
. This will return an array of packages. In order to determine which items belong in which package when they are being built, Spree uses an object called a Splitter
, described in more detail below.
After obtaining the array of available packages, they are converted to shipments on the order object. Shipping rates are determined and inventory units are created during this process as well.
At this point, the checkout process can continue to the delivery step.
Spree::Stock::Coordinator
is the starting point for determining shipments when calling create_proposed_shipments
on an order. Its job is to go through each StockLocation
available and determine what can be shipped from that location.
The Spree::Stock::Coordinator
will ultimately return an array of packages which can then be easily converted into shipments for an order by calling to_shipment
on them.
Spree::Stock::Packer
object is an important part of the create_proposed_shipments
process. Its job is to determine possible packages for a given StockLocation and order. It uses rules defined in classes known as Splitters
to determine what packages can be shipped from a StockLocation
.
For example, we may have two splitters for a stock location. One splitter has a rule that any order weighing more than 50lbs should be shipped in a separate package from items weighing less. Our other splitter is a catch-all for any item weighing less than 50lbs. So, given one item in an order weighing 60lbs and two items weighing less, the Packer would use the rules defined in our splitters to come up with two separate packages: one containing the single 60lb item, the other containing our other two items.
Shipping Category Splitter
Weight Splitter
Spree::Stock::Splitter::Weight.threshold
(defaults to 150
) in an initializer.Spree::Stock::Splitter::Base
, you can create your own splitter.
For an example of a simple splitter, take a look at Spree’s weight based splitter. This splitter pulls items with a weight greater than 150 into their own shipment.
After creating your splitter, you need to add it to the array of splitters Spree uses. To do this, add the following to your application’s spree initializer spree.rb
file:
spree.rb
file:
StockLocation
, you need to decorate the Spree::Stock::Coordinator
class and override the splitters
method.
Spree::Stock::Prioritizer
object will decide which StockLocation
should ship which package from an order. The prioritizer will attempt to come up with the best shipping situation available to the user.
By default, the prioritizer will first select packages where the items are on hand. Then it will try to find packages where items are backordered. During this process, the Spree::Stock::Adjuster
is also used to ensure each package has the correct number of items.
The prioritizer is also a customization point. If you want to customize which packages should take priority for the order during this process, you can override the sort_packages
method in Spree::Stock::Prioritizer
.
Adjuster
visits each package in an order and ensures the correct number of items are in each package. To customize this functionality, you need to do two things:
adjust
method to get the desired functionality.Spree::Stock::Coordinator
and override the prioritize_packages
method, passing in your custom adjuster class to the Prioritizer
initializer. For example, if our adjuster was called Spree::Stock::CustomAdjuster
, we would do the following in app/my_store/spree/stock/coordinator_decorator.rb
:Spree::Stock::Estimator
loops through the packages created by the packer in order to calculate and attach shipping rates to them. This information is then returned to the user so they can select shipments for their order and complete the checkout process.