From bf9f9bd0c9ad3d448432618e9977c2b070f0a5f0 Mon Sep 17 00:00:00 2001 From: Benjamin Willems Date: Fri, 17 Nov 2017 15:48:42 -0800 Subject: [PATCH] Implement feedback from shipments documentation PR Thanks to @swcraig and @mamhoff for additional feedback on my shipments documentation PR. For the most part, these edits address the need to differentiate between "packages" and "shipments", especially when talking about Solidus's split shipment functionality. --- .../shipments/custom-shipping-calculators.md | 29 ++++++--- guides/shipments/overview-of-shipments.md | 7 ++- guides/shipments/shipping-method-filters.md | 2 +- .../solidus-active-shipping-extension.md | 63 +------------------ guides/shipments/split-shipments.md | 36 ++++++----- .../shipments/user-interface-for-shipments.md | 8 +-- 6 files changed, 52 insertions(+), 93 deletions(-) diff --git a/guides/shipments/custom-shipping-calculators.md b/guides/shipments/custom-shipping-calculators.md index 3cf02ec58a5..ca88290c466 100644 --- a/guides/shipments/custom-shipping-calculators.md +++ b/guides/shipments/custom-shipping-calculators.md @@ -1,4 +1,4 @@ -# Custom shipping calculators +# 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. @@ -19,19 +19,30 @@ shipping scenarios: 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 +[`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. +FedEx. Alternatively, you could develop your own custom calculator. [solidus-active-shipping]: solidus-active-shipping-extension.md ## Custom calculator requirements -Your calculator should accept an array of `LineItem` objects that are associated -with an order, and then return a cost. +A custom calculator should accept a `Spree::Stock::Package` (a `package`) and +return a cost. -The calculator can look at any reachable data related to the order, but -it typically requires the following information: +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. + + + +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. @@ -54,7 +65,7 @@ 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. +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 @@ -63,6 +74,6 @@ shipping category of "Oversized" differently than it would a product with the diff --git a/guides/shipments/overview-of-shipments.md b/guides/shipments/overview-of-shipments.md index 359af195c47..04d095f4fb7 100644 --- a/guides/shipments/overview-of-shipments.md +++ b/guides/shipments/overview-of-shipments.md @@ -13,14 +13,15 @@ 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.html.markdown). +[Shipment setup examples](shipment-setup-examples.md). -[solidus-active-shipping]: solidus-active-shipping-extension.html.markdown +[solidus-active-shipping]: solidus-active-shipping-extension.md +[solidus-shipstation]: https://github.com/boomerdigital/solidus_shipstation ## Shipment attributes @@ -145,7 +146,7 @@ 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.html.markdown +[custom-shipping-calculators]: custom-shipping-calculators.md ### Shipping rates diff --git a/guides/shipments/shipping-method-filters.md b/guides/shipments/shipping-method-filters.md index 48371a4d674..1cc753cf07a 100644 --- a/guides/shipments/shipping-method-filters.md +++ b/guides/shipments/shipping-method-filters.md @@ -60,7 +60,7 @@ class Calculator::Usps::FirstClassMailParcels < Calculator::Usps::Base "USPS Bogus First Class International" end - def available?(order) + def available?(package) multiplier = 1.3 weight = order.line_items.inject(0) do |weight, line_item| weight + (line_item.variant.weight ? (line_item.quantity * line_item.variant.weight * multiplier) : 0) diff --git a/guides/shipments/solidus-active-shipping-extension.md b/guides/shipments/solidus-active-shipping-extension.md index e059e602c83..b8e96f7cdca 100644 --- a/guides/shipments/solidus-active-shipping-extension.md +++ b/guides/shipments/solidus-active-shipping-extension.md @@ -142,67 +142,10 @@ The string returned by the `description` method must match the name of the USPS delivery service _exactly_. To determine the exact spelling, you should examine what the USPS API returns. -The following code block returns the description and the rate of USPS delivery -services: - -```ruby -class Calculator::ActiveShipping < Calculator - def compute(line_items) - #.... - rates = retrieve_rates(origin, destination, packages(order)) - # the key of this hash is the name you need to match - # raise rates.inspect - - return nil unless rates - rate = rates[self.description].to_f + -(Spree::ActiveShipping::Config[:handling_fee].to_f || 0.0) - return nil unless rate - # divide by 100 since active_shipping rates are expressed as cents - - return rate/100.0 - end - - def retrieve_rates(origin, destination, packages) - #.... - # carrier is an instance of ActiveMerchant::Shipping::USPS - response = carrier.find_rates(origin, destination, packages) - # turn this beastly array into a nice little hash - h = Hash[*response.rates.collect { |rate| [rate.service_name, rate.price] -}.flatten] - #.... - end -end -``` - - -This returns an array of services with their corresponding prices, which the -`retrieve_rates` method converts into a hash. Below is what would get returned -for an order with an international destination: - -```ruby -{ - "USPS Bogus First Class International"=>9999, - "USPS Priority Mail International Flat Rate Envelope"=>1345, - "USPS First-Class Mail International Large Envelope"=>376, - "USPS USPS GXG Envelopes"=>4295, - "USPS Express Mail International Flat Rate Envelope"=>2895, - "USPS First-Class Mail International Package"=>396, - "USPS Priority Mail International Medium Flat Rate Box"=>4345, - "USPS Priority Mail International"=>2800, - "USPS Priority Mail International Large Flat Rate Box"=>5595, - "USPS Global Express Guaranteed Non-Document Non-Rectangular"=>4295, - "USPS Global Express Guaranteed Non-Document Rectangular"=>4295, - "USPS Global Express Guaranteed (GXG)"=>4295, - "USPS Express Mail International"=>2895, - "USPS Priority Mail International Small Flat Rate Box"=>1345 -} -``` - -From all of the viable shipping services in this hash, the `compute` method -selects the one that matches the description of the calculator. + Expand this sub-article to make a practical example of a developer matching + the delivery service with its provided name. +--> ### Register the new calculator diff --git a/guides/shipments/split-shipments.md b/guides/shipments/split-shipments.md index ce435c732d1..91ecabd660a 100644 --- a/guides/shipments/split-shipments.md +++ b/guides/shipments/split-shipments.md @@ -10,6 +10,12 @@ business logic for how stock should be packaged. If your store requires a specialized flow for handling split shipments, the simple coordinator should provide a good starting point for customizations. + + ## Creating proposed shipments An order's shipments are determined by @@ -17,15 +23,15 @@ An order's shipments are determined by `Spree::Order`'s' state is set to `delivery`. This occurs before the customer has completed their order at checkout. -The simple coordinator deletes any existing shipments for an order and then -creates all of the shipments currently available for this order. +The `SimpleCoordinator` takes an order and builds as many shipments as are +necessary to fulfill it. [simple-coordinator]: https://github.com/solidusio/solidus/blob/master/core/app/models/spree/stock/simple_coordinator.rb The simple coordinator performs a number of tasks in order to create shipment proposals: -1. The coordinator calculates the availability of the ordered items. +1. The coordinator checks the availability of the ordered items. 2. Inventory is allocated from available stock to the current order. 3. It splits the order into logical packages based on stock locations and inventory at those locations. @@ -44,22 +50,23 @@ first splitter in the sequence takes the array of packages from the order, splits the order into packages according to its rules, then passes the packages on to the next splitter in the sequence. +For each generated shipment, a shipping method can be assigned. + ### Default splitters -Solidus comes with thre built-in splitters: +Solidus comes with three built-in splitters: - [Backordered splitter][backordered-splitter]: Splits an order based on the amount of inventory on hand at each stock location. - [Shipping category splitter][shipping-category-splitter]: Splits an order into - packages based on a product's shipping categories. This means that each + shipments based on a product's shipping categories. This means that each package only has items that belongs to the same shipping category. -- [Weight splitter][weight-splitter]: Splits an order into packages based on a - weight - threshold. This means that each package has a maximum weight: if a new item - is added to the order and it causes a package to go over the weight threshold, - a new package is created. All packages need to weigh less than the threshold. - You can set the weight threshold by changing - the `Spree::Stock::Splitter::Weight.threshold` value in an initializer. (It +- [Weight splitter][weight-splitter]: Splits an order into shipments based on a + weight threshold. This means that each shipment has a maximum weight: if a new + item is added to the order and it causes a package to go over the weight + threshold, a new shipment is created. Each shipment needs to weigh less than + the threshold. You can set the weight threshold by changing the + `Spree::Stock::Splitter::Weight.threshold` value in an initializer. (It defaults to `150`.) [backordered-splitter]: https://github.com/solidusio/solidus/blob/master/core/app/models/spree/stock/splitter/backordered.rb @@ -80,8 +87,7 @@ that Solidus uses. To do this, add the following to your `config/initializers/spree.rb` file: ```ruby -Rails.application.config.spree.stock_splitters << -Spree::Stock::Splitter::CustomSplitter +Rails.application.config.spree.stock_splitters << Spree::Stock::Splitter::CustomSplitter ``` You can also override the splitters used in Solidus, rearrange them, or @@ -95,7 +101,7 @@ Rails.application.config.spree.stock_splitters = [ ``` If you want to add different splitters for each of your `Spree::StockLocation`s, -you can decorate the `Spree::Stock::Coordinator` class and override the +you can decorate the `Spree::Stock::SimpleCoordinator` class and override the `splitters` method. #### Turn off split shipments diff --git a/guides/shipments/user-interface-for-shipments.md b/guides/shipments/user-interface-for-shipments.md index 46323815260..db68922d3f2 100644 --- a/guides/shipments/user-interface-for-shipments.md +++ b/guides/shipments/user-interface-for-shipments.md @@ -35,12 +35,10 @@ shipments can be associated with a single order. Shipments do not have their own dedicated part of the admin UI. Shipments are viewable and editable from within an order. -In the admin dashboard. the administrator can update each shipment's shipping +In the admin dashboard, the administrator can update each shipment's shipping cost and add tracking codes when editing an order. They can also perform other -tasks, such as splitting a single shipment into multiple shipments. - -In the Solidus demo store, edit any order (from the `/admin/orders` URL) and go -to the "Shipments" tab to see the default interface. +tasks, such as splitting a single shipment into multiple shipments. They can do +all of this from the "Shipments" tab of any order. ### Shipping instructions