• Stars
    star
    135
  • Rank 269,297 (Top 6 %)
  • Language
    Ruby
  • Created almost 14 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Spree integration for Shopify's active_shipping gem.

Active Shipping

Build Status

This is a Spree extension that wraps the popular active_shipping plugin.

Installation

  1. Add this extension to your Gemfile with this line:

Spree >= 3.1

gem 'spree_active_shipping', github: 'spree-contrib/spree_active_shipping'

Spree 3.0 and Spree 2.x

gem 'spree_active_shipping', github: 'spree-contrib/spree_active_shipping', branch: 'X-X-stable'

The branch option is important: it must match the version of Spree you're using. For example, use 3-0-stable if you're using Spree 3-0-stable or any 3.0.x version.

  1. Install the gem using Bundler:
bundle install
  1. Copy & run migrations
bundle exec rake railties:install:migrations
bundle exec rake db:migrate
  1. Restart your server

If your server was running, restart it so that it can find the assets properly.

Rate quotes from carriers

So far, this gem supports getting quotes from UPS, USPS, Canada Post, and FedEx. In general, you will need a developer account to get rates. Please contact the shipping vendor that you wish to use about generating a developer account.

Once you have an account, you can go to the active shipping settings admin configuration screen to set the right fields. You need to set all of the Origin Address fields and the fields for the carrier you wish to use. To set the settings through a config file, you can assign values to the settings like so:

Spree::ActiveShipping::Config[:ups_login]
Spree::ActiveShipping::Config[:ups_password]
Spree::ActiveShipping::Config[:ups_key]
Spree::ActiveShipping::Config[:usps_login]

NOTE: When setting up FedEx credentials, :fedex_login is the "Meter Number" that FedEx supplies you with.

It is important to note how this wrapper matches the calculators to the services available from the carrier API's, by default the base calculator matches the service name to the calculator class and returns the rate, this magic happens as follows:

  1. inside the calculator class
Spree::Calculator::Shipping::Fedex::GroundHomeDelivery::description #holds the service name
  1. inside the calculator base
  rates_result = retrieve_rates_from_cache(package, origin, destination) # <- holds the rates for given package in a parsed hash (see sample response below)
  rate = rates_result[self.class.description] # <- matches with the description as the key

this means that the calculator Fedex::GroundHomeDelivery will hit FedEx Servers and try to get the rates for the given package, since FedEx returns rates for package and returns all of its available services for the given shipment we need to identify which service we are targeting ( see caching results below ) the calculator will only pick the rates from a service that matches the "FedEx Ground Home Delivery" string, you can see how it works below:

a sample rate response already parsed looks like this:

{
         "FedEx First Overnight" => 5886,
      "FedEx Priority Overnight" => 2924,
      "FedEx Standard Overnight" => 2529,
                "FedEx 2 Day Am" => 1987,
                   "FedEx 2 Day" => 1774,
    "FedEx Ground Home Delivery" => 925
}

the rate hash that is parsed by the calculator has service descriptions as keys, this makes it easier to get the rates you need.

  1. getting the rates (all the above together)
  calculator = Spree::Calculator::Shipping::Fedex::GroundHomeDelivery.new
  calculator.description # "FedEx Ground Home Delivery"
  rate = calculator.compute(<Package>)
  rate # $9.25

you can see the rates are given in cents from FedEx (in the rate hash example above), spree_active_shipping converts them dividing them by 100 before sending them to you

Note: if you want to integrate to a new carrier service that is not listed below please take care when trying to match the service name key to theirs, there are times when they create dynamic naming conventions, please take as an example USPS, you can see the implementation of USPS has the compute_packages method overridden to match against a service_code key that had to be added to calculator services ( Issue #103 )

Global Handling Fee

Spree::ActiveShipping::Config[:handling_fee]

This property allows you to set a global handling fee that will be added to all calculated shipping rates. Specify the number of cents, not dollars. You can either set it manually or through the admin interface.

Weights

Global weight default

This property allows you to set a default weight that will be substituted for products lacking defined weights. You can either set it manually or through the admin interface.

Spree::ActiveShipping::Config[:default_weight]

Weight units

Weights are expected globally inside spree_active_shipping to be entered in a unit that can be divided to oz and a global variable was added to help with unit conversion

Spree::ActiveShipping::Config[:unit_multiplier]

It is important to note that by default this variable is set to have a value of 16 expecting weights to be entered in lbs

Example of converting from metric system to oz

Say you have your weights in kg you would have to set the multiplier to 35.274

Spree::ActiveShipping::Config[:unit_multiplier] = 35.274

Cache

When Spree tries to get rates for a given shipment it calls Spree::Stock::Estimator, this class is in charge of getting the rates back from any calculator active for a shipment, the way the estimator determines the shipping methods that will apply to the shipment varies from within spree versions but the general idea is this:

NOTE: Shipping methods are tied to calculators

  private
  def shipping_methods(package)
    shipping_methods = package.shipping_methods
    shipping_methods.delete_if { |ship_method| !ship_method.calculator.available?(package) }
    shipping_methods.delete_if { |ship_method| !ship_method.include?(order.ship_address) }
    shipping_methods.delete_if { |ship_method| !(ship_method.calculator.preferences[:currency].nil? || ship_method.calculator.preferences[:currency] == currency) }
    shipping_methods
  end

The money line for spree_active_shipping is when it calls the calculator's available? method, this method is actually calling the carrier services, and it checks for rates or errors in the form of Spree::ShippingError, if the rates are there for the specified shipment, the calculator will store the parsed rates with a specific key for each package inside the cache, consider the following example to see why this works and why this is necessary:

  • User orders N amount of products
  • All of the products from this order are stored in Stock Location 1
  • Once the order creates shipments you will end up with 1 shipment
  • Calculators are active for the following services: FedEx Ground Home Delivery, FedEx 2 Day, FedEx International Priority
  • Order calls the estimator for rates:
  • Estimator will try to get the active shipping methods for this package, it will call available? on all of the active calculators to determine if they are all available for this shipment
  • once it calls it for the first calculator (FedEx Ground Home Delivery) it will get the following rates back from FedEx
{
         "FedEx First Overnight" => 5886,
      "FedEx Priority Overnight" => 2924,
      "FedEx Standard Overnight" => 2529,
                "FedEx 2 Day Am" => 1987,
                   "FedEx 2 Day" => 1774,
    "FedEx Ground Home Delivery" => 925
}
  • when it tries to get rates for the 2nd calculator (FedEx 2 Day) it will check the cache first and will find that for this package and stock location it already has rates stored in the cache and it won't call FedEx again, using this same rates
  • when it hits the last calculator (FedEx International Priority) it will find that the cache doesn't have any rates for the given key, and the method available? called from the Estimator will return false thus removing the calculator's shipping method from the list of available calculators and won't return any rates back for it
  • Consequently since this 3rd calculator (FedEx International Priority) is an international calculator it would have been removed as well by the line that checks if any shipping method is allowed in already defined Zones.

Testing

Be sure to bundle your dependencies and then create a dummy test app for the specs to run against.

$ bundle
$ bundle exec rake test_app
$ bundle exec rspec spec

Further Reading

Andrea Singh has also written an excellent blog post covering the use of this extension in detail. It is rather old and somewhat outdated.

More Repositories

1

spree_i18n

I18n translation files for Spree Commerce.
Ruby
346
star
2

spree_social

Building block for spree social networking features (provides authentication and account linkage)
Ruby
213
star
3

spree_related_products

Related products extension for Spree Commerce.
Ruby
149
star
4

spree_multi_vendor

Spree marketplace extension. Create your own marketplace on top of Spree Commerce
Ruby
130
star
5

spree_reviews

Straightforward review/rating functionality.
Ruby
125
star
6

spree_digital

A Spree extension to enable downloadable products
Ruby
116
star
7

better_spree_paypal_express

A better Spree PayPal Express Extension.
Ruby
109
star
8

spree_wishlist

Wishlist extension for Spree Commerce.
Ruby
106
star
9

spree_drop_ship

Spree Drop Shipping Extension
Ruby
102
star
10

spree_address_book

Adds address book for users to Spree
Ruby
94
star
11

spree_print_invoice

Create a PDF invoice for Spree orders.
Ruby
90
star
12

spree_fancy

SpreeFancy is a responsive theme for Spree Commerce.
CSS
86
star
13

spree_marketplace

Turn Spree into a marketplace by extending spree drop ship.
Ruby
77
star
14

spree_store_credits

This Spree extension allows admins to issue arbitrary amounts of store credit to users.
Ruby
70
star
15

spree_blue_theme

Original Spree Blue theme (0.60.x)
Ruby
65
star
16

spree_shared

Multi-tenancy for Spree using Apartment (per tenant databases).
Ruby
61
star
17

spree_rdr_theme

WIP - everything might change.
Ruby
52
star
18

spree_email_to_friend

Email a friend functionality for Spree Commerce.
Ruby
49
star
19

spree_sitemap

Sitemap Generator for Spree Commerce.
Ruby
47
star
20

spree_affiliate

Affiliate support for Spree Commerce.
Ruby
46
star
21

spree_braintree_vzero

Official Braintree + PayPal integration gem for Spree Commerce
Ruby
45
star
22

spree_multi_currency

Provides UI to allow configuring multiple currencies in Spree.
Ruby
41
star
23

spree_contact_us

Adds Contact Us form to your Spree Commerce store
Ruby
40
star
24

spree_product_zoom

Lightbox zoom functionality to show original product image
Ruby
32
star
25

spree_social_products

Add social sharing buttons for your Spree products
Ruby
28
star
26

spree_mail_settings

Mail setting functionality extracted from Spree.
Ruby
28
star
27

spree_slider

Ruby
26
star
28

spree_api_examples

Ruby
26
star
29

spree_globalize

Adds support for model translations (multi-language stores) using Globalize gem
Ruby
24
star
30

spree_simple_dash

Alternative dashboard overview for Spree
Ruby
23
star
31

spree_price_books

Price book functionality for running sales, role based, country based pricing etc...
Ruby
21
star
32

spree_analytics_trackers

Integrate your Spree application with Google Analytics and Segment.com
Ruby
19
star
33

spree_product_groups

Extension to Spree featuring Product Groups that were originally part of core prior to 1.1 release.
Ruby
19
star
34

spree_skrill

Add support for Skrill / MoneyBookers Quick checkout as a payment method.
Ruby
18
star
35

spree_analytics

Ruby
18
star
36

spree_store_credit_payment_method

Adds store credit functionality as a payment method.
Ruby
17
star
37

spree_tax_cloud

US sales tax extension for Spree using the Tax Cloud service.
Ruby
15
star
38

spree_page_cache

Minor tweaks to make Spree pages suitable for page caching
Ruby
15
star
39

spree_blue_sass_theme

spree_blue_theme using sass
Ruby
14
star
40

spree-adyen

Adyen payment gateway integration for Spree.
Ruby
12
star
41

spree_mailchimp_ecommerce

Connect your Spree application to Mailchimp eCommerce API for full email automation
Ruby
12
star
42

spree_shopify_importer

Migrate your Shopify store to Spree
Ruby
9
star
43

spree_handling_fees

Adds Handling Fee functionality to Spree.
Ruby
9
star
44

spree_clean

Admin UI to allow the removal of sample / test data.
Ruby
9
star
45

spree_vouchers

A WIP for Gift Vouchers
Ruby
7
star
46

spree_avatax_official

The new officially certified Spree Avatax (Avalara) extension
Ruby
7
star
47

spree_favorites

Add Spree::Favorite model to track favorite products or anything else you would like.
Ruby
7
star
48

spree_claim_order

Claim guest orders associated with an email address
Ruby
5
star
49

rfcs

A Request for Comments on Spree.
5
star
50

spree_videos

Spree extension to allow linking of youtube reference IDs to products
Ruby
5
star
51

spree_jirafe

Front-end integration for Jirafe.
Ruby
5
star
52

spree_usa_epay

Ruby
4
star
53

spree_multicode_promotions

Ruby
2
star
54

spree_jmeter

Contains https://github.com/flood-io/ruby-jmeter scripts for benchmarking & load testing Spree.
Ruby
1
star
55

spree_automation_interfaces

Ruby
1
star
56

spree_legacy_return_authorizations

Spree 2.3.x Legacy Returns
Ruby
1
star