-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shipments documentation #2353
Merged
jhawthorn
merged 12 commits into
solidusio:master
from
benjaminwil:shipments_documentation
Jan 2, 2018
+887
−504
Merged
Shipments documentation #2353
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
aa8b2d8
Move shipping guide to subdirectory
benjaminwil 2a81ce0
Rename shipping overview article
benjaminwil 0400d2c
Add split shipments article
benjaminwil 700b609
Add solidus_active_shipping article
benjaminwil 4c29095
Add shipment setup examples article
benjaminwil e636928
Add custom shipping calculators article
benjaminwil bb4a805
Add shipping method filters article
benjaminwil 28cd90b
Add article about shipments UI
benjaminwil 5aed0a4
Revise overview of shipping attributes
benjaminwil 82edd76
Revise introduction to core shipping concepts
benjaminwil f73558b
Add introduction to additional shipping concepts
benjaminwil bf9f9bd
Implement feedback from shipments documentation PR
benjaminwil File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Cartons | ||
|
||
The `Spree::Carton` model represents how an order was shipped. For stores that | ||
use third-party logistics or complicated warehouse workflows, the shipment | ||
described when the order is confirmed may not be how the _actual_ shipment is | ||
packaged when it leaves its destination. | ||
|
||
## Example of usage | ||
|
||
**A customer orders two t-shirts.** | ||
|
||
Solidus creates one `Spree::Shipment` object, which is used to ship both | ||
t-shirts in the order as one package. | ||
|
||
**The customer is charged for a single shipment.** | ||
|
||
Your t-shirt warehouse receives the shipping instructions for the new order. | ||
However, they realize that one of the t-shirts is currently backordered. They | ||
cannot send both t-shirts in a single package. | ||
|
||
**The warehouse ship the first of two packages, which is the first of two | ||
t-shirts.** | ||
|
||
However, you do not want to charge the customer for a second shipment. Your | ||
inventory was not accurate, and your store is paying for the additional package. | ||
|
||
If you split the shipment into two `Spree::Shipment` objects, the customer would | ||
be charged shipping for both packages. | ||
|
||
To avoid an extra shipping charge, you can instead create additional | ||
`Spree::Carton` objects for every package sent out of the warehouse. This way, | ||
the shipment object stays unique and the order total does not change. | ||
|
||
**The warehouse ships the second of two packages.** | ||
|
||
This second package is associated with the order as another `Spree::Carton` | ||
object. Although it is shipped as a separate package, the customer is not | ||
charged for another shipment. | ||
|
||
<!-- TODO: | ||
This article is a stub. | ||
--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Custom shipping calculators | ||
|
||
This article provides context about creating custom shipping calculators in the | ||
case that the provided calculators do not meet your store's needs. | ||
|
||
## Pre-configured calculators | ||
|
||
Before developing a custom calculator, you should make sure that the calculator | ||
you need doesn't already exist in Solidus or one of its extensions. | ||
|
||
Solidus comes with a set of default calculators that account for typical | ||
shipping scenarios: | ||
|
||
- [Flat percent](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/flat_percent_item_total.rb) | ||
- [Flat rate (per order)](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/flat_rate.rb) | ||
- [Flat rate per package item](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/per_item.rb) | ||
- [Flexible rate per package item](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/flexi_rate.rb) | ||
- [Price sack](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/price_sack.rb) | ||
|
||
If the calculators that come with Solidus are not enough for your needs, you | ||
might want to use an extension like | ||
[`solidus_active_shipping`][solidus-active-shipping] that provides additional | ||
API-based rate calculation functionality for common carriers like UPS, USPS, and | ||
FedEx. Alternatively, you could develop your own custom calculator. | ||
|
||
[solidus-active-shipping]: solidus-active-shipping-extension.md | ||
|
||
## Custom calculator requirements | ||
|
||
A custom calculator should accept a `Spree::Stock::Package` (a `package`) and | ||
return a cost. | ||
|
||
Use the `package.order` method to access the current order's information, and | ||
the `package.contents` methods to access the current package's contents. As a | ||
developer, you should always deal with the `package.contents`. Otherwise, you | ||
may be quoting an entire order when you only want to quote one of many shipments | ||
on an order. | ||
|
||
<!-- TODO: | ||
So far, the shipments documentation doesn't go into packages in any details. | ||
These references by themselves are not enough. What is the purpose of a | ||
"package" that is distinctive from a "shipment". | ||
--> | ||
|
||
Typically, a calculator uses the following order information: | ||
|
||
- The `Spree::Address` used as the order's shipping address. | ||
- The `Spree::LineItem` objects associated with the order. | ||
- The `Spree::Variant` product information (such as the weight and dimensions) | ||
associated with each line item in the order. | ||
|
||
For an example of a typical calculator, we recommend reading the source code for | ||
Solidus's [stock flat rate calculator][flat-rate-source]. For a more complicated | ||
example of what is possible with custom calculators, see the | ||
[`solidus_active_shipping` base calculator][base-calculator-source]. This | ||
calculator collects enough information about an order to send to a carrier and | ||
get a rate quote back. | ||
|
||
[flat-rate-source]: https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/flat_rate.rb | ||
[base-calculator-source]: https://github.com/solidusio-contrib/solidus_active_shipping/blob/master/app/models/spree/calculator/shipping/active_shipping/base.rb | ||
|
||
## Use additional product information | ||
|
||
In addition to providing relevant information about shipping addresses and | ||
product variants, you can use information about the product itself to inform a | ||
calculator's results. A product's tax category or shipping category could be | ||
meaningful information for shipping calculations. By default, each package | ||
contains only items in the same shipping category. | ||
|
||
For example, you might want your calculator to handle your product with a | ||
shipping category of "Oversized" differently than it would a product with the | ||
"Default" shipping category. | ||
|
||
<!-- TODO: | ||
Add an example code block or a link to some Solidus code that shows a | ||
calculator taking advantage of shipping categories and/or tax categories to | ||
produce a specific result. | ||
--> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
# Overview of shipments | ||
|
||
Solidus uses a flexible system to calculate shipping. It accommodates the full | ||
range of shipment pricing: from simple [flat | ||
rate](https://en.wikipedia.org/wiki/Flat_rate) calculations to more | ||
complex calculations related to product weight or type, the customer's shipping | ||
address, what shipping method is being used, and so on. | ||
|
||
If your store has complex shipping needs, you may find one of Solidus's existing | ||
shipping extensions, like [`solidus_active_shipping`][solidus-active-shipping] | ||
or [`solidus_shipstation`][solidus-shipstation], useful. Check out [the list of | ||
supported Solidus Extensions](https://extensions.solidus.io). | ||
|
||
This article provides a summary of shipping concepts. If you are interested in | ||
reading about example Solidus shipment setups see | ||
[Shipment setup examples](shipment-setup-examples.md). | ||
|
||
<!-- TODO: | ||
Add section that summarizes what Spree::Objects are created related to | ||
shipments and explains what their function is in the larger checkout process. | ||
--> | ||
|
||
[solidus-active-shipping]: solidus-active-shipping-extension.md | ||
[solidus-shipstation]: https://github.com/boomerdigital/solidus_shipstation | ||
|
||
## Shipment attributes | ||
|
||
The `Spree::Shipment` model tracks how items should be delivered to the | ||
customer. Developers may be interested in the following attributes: | ||
|
||
- `number`: The unique identifier for this shipment. It begins with the letter | ||
`H` and ends in an 11-digit number. This number is visible to customers, and | ||
it can be used to find the order (by calling `Spree::Shipment.find_by(number: | ||
H12345678910)`). | ||
- `tracking`: The identifier given for the shipping provider (such as FedEx or | ||
UPS). | ||
- `shipped_at`: The time when the shipment is shipped. | ||
- `state`: The current state of the shipment. See [Shipping | ||
states](#shipping-states) for more information. | ||
- `stock_location_id`: The ID of the stock location where the items for this | ||
shipment are sourced from. | ||
- `adjustment_total`: The sum of the promotion and tax adjustments on the | ||
shipment. | ||
- `additional_tax_total`: The sum of U.S.-style sales taxes on the shipment. | ||
- `promo_total`: The sum of the promotions on the shipment. | ||
- `included_tax_total`: The sum of the VAT-style taxes on the shipment. | ||
- `cost`: The estimated shipping cost (for the selected shipping method). | ||
- `order_id`: The ID for the order that the shipment belongs to. | ||
|
||
<!-- TODO: | ||
Add a shipment process flow diagram. | ||
--> | ||
|
||
### Shipping states | ||
|
||
Each shipment is assigned a `state` attribute. Depending on its state, different | ||
actions can be performed on shipments. There are four possible states: | ||
|
||
- `pending`: The shipment has backordered inventory units and/or the order is | ||
not paid for. | ||
- `ready`: The shipment has no backordered inventory units and the order is paid | ||
for. | ||
- `shipped`: The shipment has left the stock location. | ||
- `canceled`: When an order is cancelled, all of its shipments will also be | ||
cancelled. When this happens, all items in the shipment will be restocked. If | ||
an order is "resumed", then the shipment will also be resumed. | ||
|
||
## Core concepts | ||
|
||
To leverage Solidus's shipping system, become familiar with its key concepts: | ||
|
||
- Stock locations | ||
- Shipping methods | ||
- Zones | ||
- Shipping categories | ||
- Shipping calculators | ||
- Shipping rates | ||
- Inventory units | ||
- Cartons | ||
|
||
### Stock locations | ||
|
||
Stock locations represent physical storage locations from which stock is | ||
shipped. | ||
|
||
### Shipping methods | ||
|
||
Shipping methods identify the actual delivery services used to ship the | ||
product. For example: | ||
|
||
- UPS Ground | ||
- UPS One Day | ||
- FedEx 2Day | ||
- FedEx Overnight | ||
- DHL International | ||
|
||
Each shipping method is only applicable to a specific geographic | ||
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, which is a United | ||
States-only carrier. | ||
|
||
### Shipping categories | ||
|
||
You can further restrict when shipping methods are available to customers by | ||
using shipping categories. If you assign two products to two different shipping | ||
categories, you could ensure that these items are always sent as separate | ||
shipments. | ||
|
||
For example, if your store can only ship oversized products via a specific | ||
carrier, called "USPS Oversized Parcels", then you could create a shipping | ||
category called "Oversized" for that shipping method, which can then be assigned | ||
to oversized products. | ||
|
||
Shipping categories are created in the admin interface (**Settings -> Shipping | ||
-> Shipping Categories**) and then assigned to products (**Products -> Edit**). | ||
|
||
### Zones | ||
|
||
Zones serve as a mechanism for grouping distinct geographic areas together. | ||
|
||
The shipping address entered during checkout defines the zone (or zones) for the | ||
order. The zone limits the available shipping methods for the order. It also | ||
defines regional taxation rules. | ||
|
||
<!-- TODO: | ||
For more information about zones, see [the Locations guide](../locations). | ||
--> | ||
|
||
### Shipping calculators | ||
|
||
A shipping calculator is the component responsible for calculating the shipping | ||
rate for each available shipping method. | ||
|
||
Solidus ships with five default shipping calculators: | ||
|
||
- [Flat percent](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/flat_percent_item_total.rb) | ||
- [Flat rate (per order)](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/flat_rate.rb) | ||
- [Flat rate per package item](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/per_item.rb) | ||
- [Flexible rate per package item](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/flexi_rate.rb) | ||
- [Price sack](https://github.com/solidusio/solidus/blob/master/core/app/models/spree/calculator/shipping/price_sack.rb) | ||
(which offers variable shipping cost that depends on order total) | ||
|
||
If you want to estimate shipping rates using carrier APIs, You can use an | ||
extension like [`solidus_active_shipping`][solidus-active-shipping]. Or, if you | ||
have other complex needs, you can create a [custom shipping | ||
calculators][custom-shipping-calculators] for more information. | ||
|
||
[custom-shipping-calculators]: custom-shipping-calculators.md | ||
|
||
### Shipping rates | ||
|
||
For each shipment, a `Spree::ShippingRate` object is created for each of your | ||
store's shipping methods. These objects represent the cost of the shipment as | ||
calculated by each shipping method's calculator. | ||
|
||
| `Spree::ShippingRate` | 1 | 2 | 3 | Description | | ||
|-----------------------|-------|-------|-------|-----------------------------------------------------| | ||
| `shipment_id` | 1 | 1 | 1 | All of these rates are for one shipment | | ||
| `shipping_method_id` | 1 | 2 | 3 | Each available shipping method | | ||
| `selected` | false | true | false | Set to `true` for the selected shipping method only | | ||
| `cost` | $0.50 | $1.75 | $1.25 | The shipment's shipping rate | | ||
|
||
Once the shipping method has been chosen, the matching `Spree::ShippingRate`'s | ||
`selected` key becomes `true`. Only one shipping rate can be `selected` for each | ||
shipment. | ||
|
||
### Inventory units | ||
|
||
A `Spree::InventoryUnit` is created for each item in a shipment. It tracks | ||
whether the item has shipped, what product variant the item is, and what order | ||
and shipment the item is associated with. | ||
|
||
<!-- TODO: | ||
This section is a stub. It may be worth revisiting inventory units in detail, | ||
or in its own article. | ||
--> | ||
|
||
### Cartons | ||
|
||
The `Spree::Carton` model represents how an order was shipped. For stores that | ||
use third-party logistics or complicated warehouse workflows, the shipment | ||
described when the order is confirmed may not be how the _actual_ shipment is | ||
packaged when it leaves its destination. | ||
|
||
For more information, see the [Cartons](cartons.md) article. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this link seems to be broken
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Thanks!