More at Features | Support | Blog | Demo | Community | Download


This guide covers the use of calculators in Spree. After reading it, you should be familiar with:

1 Introduction

Calculators are the mechanism by which Spree handles any type of custom calculation. Some typical uses of a calculator would be to determine shipping and tax charges. They can also be used to provide custom coupon and discount logic.

2 Interface

All calculators need to implement the following method

def compute(something=nil) ... end

The calculator is passed an optional “target” on which to base their calculation. This method is expected to return a single numeric value when the calculation is complete. A value of nil should be returned in the event that a charge is not applicable.

3 Configuration

Since calculators are an instances of ActiveRecord::Base they can be configured with preferences. Each instance of ShippingMethod is now stored in the database along with the configured values for its preferences. This allows the same calculator (ex. Calculator::FlatRate) to be used with multiple ShippingMethods, and yet each can be configured with different values (ex. different amounts per calculator.)

Calculators are configured using Spreeā€™s flexible preference system. Default values for the preferences are configured through the class definition. For example, the flat rate calculator class definition specifies an amount with a default value of 0.

class Calculator::FlatRate < Calculator preference :amount, :decimal, :default => 0 ... end

Spree now contains a standard mechanism by which calculator preferences can be edited. The screenshot below shows how the amounts for the flat rate calculator are editable directly in the admin interface.

Changing Shipping Config

4 Registering a Custom Calculator

Calculators are stored in a special calculator directory located within app/models. There are several calculators included that meet many of the standard store owner needs. Developers are encouraged to write their own extensions to supply additional functionality or to consider using a third party extension written by members of the Spree community.

Calculators need to be “registered” with Spree in order to be made available in the admin interface for various configuration options. The recommended approach for doing this is via an extension. Custom calculators will typically be written as extensions so you need to add some registration logic to the extension containing the calculator. This will allow the calculator to do a one time registration during the standard extension activation process.

The CalculatorExtenion that is included in the Spree core is a good example of how you can achieve this in your own custom extensions.

def activate [ Calculator::FlatPercent, Calculator::FlatRate, Calculator::FlexiRate, Calculator::PerItem, Calculator::SalesTax, Calculator::Vat, ].each(&:register) end

This calls the register method on the calculators that we intend to register. Spree provides a mechanism for extension authors to specify the operations for which the calculator is intended. For example, a flat rate calculator might be useful for all operations but another calculator may be appropriate only for coupons and not shipping or taxes.

Models that are declared with has_calculator maintains their own set of registered calculators. Currently this includes Coupons, ShippingMethods, ShippingRates and TaxRates. The following example shows how to configure a calculator to make it available for use with Coupons.

def self.register super Coupon.register_calculator(self) end

Spree automatically configures your calculators for you when using the basic install and/or third party extensions. This discussion is intended to help developers and others interested in understanding the desgin behind calculators.

Once your calculators have been registered correctly by your extensions, then they will become available as options in the appropriate admin screens.

Choosing a calculator