Articles

VM2 Shipping by Rules Plugin - Shipping costs calculated from general rules

Introduction

This is a Virtuemart 2 plugin that allows the shop owner to determine shipping costs according to arbitrary sets of general rules. Very complex shipping cost structures (depending on the amount, weight, number of products and/or articles and postal code of the order) can be easily implemented as one shipping method by describing each by a simple rule with conditions.

There are two flavors of the plugin: The free "Shipping by Rules" plugin and the paid "Advanced Shipping by Rules" plugin. The main difference is that in the advanced plugin, all terms can be given as mathematical expressions, while in the basic version, only comparisons of the order properties with fixed values are possible.

Shipping costs can depend on:

  • Total amount of the order (before or after tax, before or after discounts)
  • Total weight of the order
  • Number of articles or different products in the order
  • Volume or minimal and maximal extensions of the products
  • Postal code of the delivery address
  • Coupon code (advanced version)
  • SKUs of the products in the cart (advanced version)
  • Categories of the products in the cart (advanced version)

The name of the rule can also contain variables, which are replaced from the cart values. So e.g. you can have a shipping name "Domestic (Weight 3.25kg)".

The rules are described as a simple line of text with an easy structure (semicolons separate the parts of the rule). For example:

Name=Free Shipping; 100<=Amount; 0
Name=Domestic Small; Articles<5; Amount<100; Shipping=1.50 Name=Domestic Standard; Amount<100; Shipping=3.50

This set of rules describes three shipping costs: Orders of 100€ and more are free, otherwise orders with less than five articles have shipping costs of 1.5€, all others 3.50€.


As another example, consider the following shipping costs of a webshop:

  <50€ <100€ above 100€
Domestic 2,50€ for up to 3 articles
2,50€ for weight less than 1kg
5€ otherwise
6,50€ FREE
International 8,50€ 8,50€ FREE

The standard shipping plugin of Virtuemart requires you to create at least four different shipping methods (domestic <50€, domestic otherwise, international <50€, international otherwise), while the dependence on the article count cannot be implemented at all. Another drawback of using different shipping methods to model this shipping cost structure is that if the customer selects a shipping method and then modifies the quantities in the cart, the new order amount might fall into the new category, and the selected shipping method will be deselected, forcing the user to select a shipping method again.

In contrast, this plugin allows this cost structure to be described by the following rules:

For the domestic country/countries:

Name=Domestic small; Articles<=3 OR Weight<=1; Amount<50; Shipping=2.50
Name=Domestic medium; Amount<50; Shipping=5
Name=Domestic Standard; 50<=Amount<100; Shipping=6.5
Name=Free Shipping above 100€; 100<=Amount; 0

For all other countries (international):

Name=International Shipping; Amount<100; Shipping=8.50
Name=International Free Shipping; Amount>=100; 0

Differences between the standard and the advanced version

  "Shipping by Rules" "Advanced Shipping by Rules"
Arbitrary number of rules yes yes
Arbitrary number of conditions yes yes
Number of different country zones 8* 8*
Comparisons as conditions yes yes
Shipping costs given before or after taxes yes yes
Shipping costs as fixed amount yes yes
NoShipping identifier to prevent shipping for certain conditions;
Print warning message for the user if desired
yes yes
Variable substitutions in the rule name strings yes yes
Allow comments in the rules (to document a rule with no effect to the user) yes yes
Shipping costs described by mathematical
formulas, involving all cart properties
no yes
Mathematical expressions as conditions no yes
OR operator and "in" operator (for lists) in conditions no yes
~ operator to compare beginning of variables no yes
Functions like not, round, floor, ceil, max, min, day, weekday, etc. no yes
Available Variables:
Amount, prices before/after tax/discounts yes yes
Weight yes yes
Postal code (ZIP)
First characters of ZIP: ZIP1, ZIP2, ZIP3, ZIP4, ZIP5, ZIP6
Country and State name variables
yes yes
Support for alphanumeric postal codes (UK, Canada, Netherlands) no yes
max/min/total volume/height/length/width/volume
of the products
yes yes
Coupon code no yes
Custom variable definitions for arbitrary expressions no yes
* Eight country zones are configurable per shipping method. If you need more country zones, simply create a second shipping method, which provides you with eight more country zones.

 

Installation and Configuration

After installation (like any Joomla plugin, using Joomla's extension manager), you need to create a shipping method of the type "Shipping by Rules" in VirtueMart:

  • Go to "Shop" -> "Shipment Methods" and click on "New"
  • Choose a name and select the "(Advanced) Shipping by Rules" plugin in the "Shipment Method"
  • Click "Save" to populate the "Configuration" tab
  • Go to the "Configuration" tab:
  • There are eight sections for different country zones that can have different rules.
  • Select the countries fo the first zone (if no countries are selected, the rules apply to all countries!)
  • Enter your rules, one per line, in the "Rules"input field (see below for the exact format). Each rule consists of conditions, a shipping cost specification and optionally a name. These parts can be given in any order, separated by semicolons.
  • When calculating the shipping costs, the plugin looks at each country zone, checks whether the country matches and then checks each of the rules until a rule matches. If no rules matches, the next country zone it investigated.
  • The first matching rule will be returned as the shipping cost.

How the shipping cost is determined

When determining a possible shipping rate for a shipping method derived from this plugin, it will walk through all rules in the order they are given and check their conditions. The first rule that matches the country selection as well as all given conditions (with the current cart properties) will be returned and offered to the user by VirtueMart. If the shipping cost of the first matching rule is set to the identifier NoShipping, then no further rules are investigated the method will not offer any shipping.
If the cart properties change (e.g. a new product is added, the quantities are updated or the shipping address is changed), this is repeated.

Knowing this procedure can help you save a lot of time an effort, since once you have checked a condition in the first rule, for all further rules you can safely assume that the conditions of the first rule are not fulfilled.

VirtueMart allows only one shipping cost to be returned per shipping method. If you want to offer e.g. a standard and an express rate, you need to set up two shipping methods with this plugin.

Format of the rules

Each line of the rules field specifies one rule and consists of several rule parts, separated by a semicolon. E.g.:

Name=Domestic Small; Articles<5; 10<=Amount<100; Shipping=3.50
Name=Free shipping with Coupon; Coupon=="FREE_SHIPPING"; Shipping=0
Name=Free Shipping; 100<=Amount; 0

All rule parts with comparison operators (supported operators are: <, <=, =<, ==, !=, <>, >=, =>, >) are understood as conditions, where multiple comparisons can be chained to one longer condition.

Let us now look at the first rule of the example above. It consists of four parts, separated by semicolons:

  1. Name=Domestic Small
    Name of the rule (will be displayed in the cart and the invoice)
  2. Articles<5
    Condition: number of articles needs to be less than five
  3. 10<=Amount<100
    Condition: the total prices of the order needs to be at least 10 and smaller than 100 currency units; This is equivalent to two separate conditions: 10<=Amount; Amount<100
  4. Shipping=3.50
    Specifies the shipping cost without taxes (in the default currency units). The Shipping= can be left out. This means that any part of the rule that does not contain a comparison operator or an = is understood as the shipping costs without taxes

The second rule shows how to use a string, which is indicated by simply wrapping it with quotes. The name of the rule is an exception and will always be understood as a string, without the need to be wrapped in quotes (although it can be). All identifiers that contain letters and are not wrapped in quotes, are understood as variables, all identifiers containing only of digits (and optionally a decimal point) are understood as numbers. ATTENTION: only a point is understood as a decimal point, not a comma like many European countries use.

The general format of a rule is:

Name=Name of the rule (displayed); [Comment=Comment that won't be shown]; [Condition=]Articles<5; ...; [Shipping=]3.50
None of the parts are required.

The "Condition=" can be left out if the condition contains any comparison operators(like <, >=, ==, etc.). If the condition consists only of a variable or of a function call (advanced version only), the "Condition=" is required to mark this part as a condition and not as shipping costs.

The "Shipping=" can always be left out. Rule parts without any assignment are always interpreted as shipping costs unless the part contains a comparison operator (like <, >=, ==, etc.)

Available Variables

In the conditions, the following properties of the order (case-insensitive) can be used:

Amount, AmountWithTax, salesPrice
Invoice amount, including taxes
amountWithoutTax
priceWithoutTax
basePrice
basePriceWithTax
discountedPriceWithoutTax
taxAmount
salesPriceWithDiscount
discountAmount
Various Cart prices before and after taxes and discounts

Weight
MinWeight, MaxWeight

Total weight of the order
Minimal / maximal weights of the all articles in the order
ZIP
ZIP1, ZIP2, ZIP3, ZIP4, ZIP5, ZIP6
Postal code of the order
First 1, 2, 3, 4, 5 and 6 characters of the postal code

CountryID, Country, Country2, Country3
StateID, State, State2, State3
City

Country/State ID (numeric), name (string), and 2- and 3-letter country codes
City name (as a string); CAUTION: Your customer might use different spellings!
Products Number of different products in the order
Articles Total number of articles (each prduct counted with the according quantity) in the order
Volume
MinVolume, MaxVolume
total/minimal/maximal volume of the products in the order. The volume of each product is calculated as length*width*height in the given length unit

MinLength, MaxLength
MinWidth, MaxWidth
MinHeight, MaxHeight
MinPackaging, MaxPackaging

minimal/maximal extensions of the products in the order
TotalLength, TotalWidth, TotalHeight, TotalPackaging
The length/width/height/packaging of all articles summed up (ATTENTION: The parcell will NOT have extensions TotalLength x TotalWidth x TotalHeight! It will rather be considerably smaller!). The TotalPackaging does not use any conversions, so it makes only sense when all products have the same units.
Coupon Coupon code entered by the user (Advanced version only!)
UK_Outward
UK_Area
UK_District
UK_Subdistrict
UK_Inward
UK postal code support (see below) (ADVANCED version only)
Canada_FSA
Canada_Area
Canada_Urban
Canada_Subarea
Canada_LDU
Canadian postal code support (see below) (ADVANCED version only)
SKUs List of all SKUs of the products in the cart. (ADVANCED version only). This can be used to check whether a particular product is in the cart (condition: "your-sku" in SKUs).

Categories
Vendors
Manufacturers

List of the category IDs, vendor IDs and manufacturer IDs of all products in the cart. In the advanced version, which can be used to check if e.g. only products from one particular vendor are purchased.

Values_Debug

DEBUGGING ONLY: A string representation of all available variables. Use e.g. as Name="All values: <pre>{Values_Debug}</pre>" to print all available (built-in) variables

All rule parts of the form [VARIABLE]=VALUE are assignments, with [VARIABLE] being one of

Name (optional) Name of the shipping cost rule (will be displayed in the cart and in the invoice). This can also be a translatable identifier, which will be translated if a translation is available.
Shipping Shipping cost (before taxes) if the rule matches, the tax gross shipping cost will be calculated from the selected tax rule; If set to NoShipping, the shipping method will not offer any shipping.
ShippingWithTax Shipping cost including taxes if the rule matches, the tax and the net shipping cost will be calculated from the selected tax rule
Comment A comment that will be completely ignored (i.e. you can use such fields to add comments in the backend that won't be shown to the customers)
Variable or
Definition
For variable definitions: The name of the variable to be defined
Value For variable definitions: The value of the variable to be defined (name of the variable given in Variable=.. or Definition=...)

For the shipping cost, Shipping= can be left out. I.e. if a rule part consists entirely of a numerical value, with no assignment or comparison operator, it is understood as shipping cost before taxes.

Shipping rule name

The (visible) name of the shipping rule is a free form string (no quotes needed, but possible) that further describes the shipping costs. The displayed shipping name will be "Shipping method name (rule name)". The string given as a rule name is translatable through the normal Joomla translation system.

To insert cart values like the total weight into the rule name, you can simply use {variablename} for any of the available variables above. E.g.

Name=Small package: {articles} articles, weight {weight} kg; Articles<3; Weight<5; Shipping=3

will display a name like "Shipping method (Small package: 2 articles, weight 3.2 kg)".

Excluding certain conditions from shipping

Setting the shipping costs to the special identifier NoShipping can be used to disallow shipping when certain conditions are met. For example, you might want to exclude some postal codes from shipping at all (e.g. some islands). An example is:

Name=No shipping of heavy packages to a certain area; Weight>100; 8000<=ZIP<9000; NoShipping
Name=No shipping of more than 100 articles; Articles>100; Shipping=NoShipping
Name=Flat rate otherwise; Shipping=15
Starting with version 4.0 of the plugin, the name of the NoShipping rule will be displayed to the user as a warning message! If the rule does not have any name set, no warning will be printed. You can use Comment=... in the rule to add a description for yourself, which will NOT be displayed to the user:
Comment="No Warning displayed, but disallow shipping to a certain ZIP range"; ZIP>9000; NoShipping

Available Operators (in their order of precendence)

OperatorDescriptionIn basic plugin
in Check whether a certain value is contained in a list  
 ^ Power  
 *, /, % Multiplication, Division, Modulo  
+, - Addition, Subtraction  
<, <=, =< less then / less or equal X
>, >=, => larger / larger or equal X
== equal X
!=, <> NOT equal X
~ starts with (the longer term of the left or right side starts with the term on the other side)  
AND, &, && logical AND operator to join two comparisons to one condition  
OR logical OR operator to join two comparisions to one condition  
= Assignment (possible LHS variables are Shippping, ShippingWithTax and Name) X

The operator names are case-insensitive.

Like with normal mathematical expressions, parentheses (...) can be used to achieve a different grouping of the terms than the normal precedence rules would imply.

Debugging problems in the Plugin

To debug problems with the plugin, it is often useful to find out the value of a certain variable, or even the full list of all available variables. I recommend to create a new shipping method called "Debugging" without any restrictions that contains just one NoShipping rule:

Name=Here you create some debug output that will be displayed to the user while debugging; NoShipping

 

The advantage of this approach is that this method will never offer a shipping rate (and does not influence your existing shipping methods),  but it will always be considered and(starting with version 4.0 of the plugin) print out its name as a warning.

  1. If you only want to know the value of one variable, simply include that one variable in the name as {Variablename}.
  2. If you want to check which variables are available and see the values of all variables, use the varible "Values_Debug", which is a string representation of all pre-defined variables. You can use a rule like the following (note, though, that this does NOT work with user-defined variables, which are available only inside the shipping method they are defined).

 

Name=All variables: <pre>{Values_Debug}</pre>; NoShipping
This rather long list will show you all variables and their values. Finding the problem is then usually just a matter of thinking your rules through with the displayed values.

 

Mathematical expression in the "Advanced Shipping by Rules" Plugin

The normal "Shipping by Rules" plugin suffices for most webshops, as it allows arbitrary many shipping cost rules with fixed shipping cost for each rule and supports numeric postal codes.

However, in some cases the shipping costs need to be even more flexible and can not be expressed by fixed shipping amount, but only by arithmetic mathematical expressions. Simple cases are shipping costs of 5% of the order amount, or 10€ per kg, or 2€ shipping per additional article. More advanced rules are employed by cargo companies, where the shipping per kg gets cheaper the more you ship.

For this reason, an advanced version of the plugin is available for sale, which adds support for alphanumeric postal codes and also incorporates arbitrary basic arithmetic expressions (allowed operators are +, -, *, /, %, ^, OR, AND and parentheses) of the above variables in all terms (conditions and shipping costs). An example is the following rule, which applies to all orders of at least 2 articles below 100€ and specifies shipping costs as 5€ fixed plus 3% of the order amount plus 1€ per kg plus 0.5€ per additional article:

Name=Complex shipping function; articles>=2; amount<100; shipping=5+amount*0.03+1*weight+0.5*(articles-2)

For more examples of such advanced shipping cost calculations, see the examples below.

NOTE: When using the OR or AND operator, it is strongly recommended to use a space before and after the operator to prevent parsing errors in certain cirumstances. E.g. "1<3OR3<5" would NOT be parsed correctly, because "3OR3" is understood as one expression!

The operator precedence (which operators are evaluated first, e.g. in 1+3*4, the multiplication has a higher precedence and is first evaluated to get the correct result of 1+12=13) is:

  1. Function calls
  2. Power ^
  3. Multiplication *, Division /, Modulo %
  4. Addition +, Subtraction -
  5. Comparisons: <, <=, >, >=, =>, =<, ==, !=, <>
  6. String startsWith: ~
  7. AND, &, &&
  8. OR
  9. Assignment =

To achieve a different order of evaluation, one can always add parentheses, e.g. (1+3)*4 to evaluate the addition first.

Available functions

Since version 3.0, the mathematical expressions of the advanced version can also contain function calls. The following functions are available (case-insensitive as of version 4.0):

FunctionDescriptionNr of arguments
not(val)
Logical NOT of the argument (e.g. not("testsku" in SKUs) to check whether a particular product is not in the cart). 1 (logical value)
round(val)
floor(val)
ceil(val)
Round the argument (less than .5 rounded down, .5 or more rounded up)
Round down (decimal part cut off)
Round up (always round up to next integer)
 exactly 1
round(val, unitval)
floor(val, unitval)
ceil(val, unitval)
Round the argument to multiples of unitval
Round down to multiples of unitval
Round up to multiples of unitval
exactly 2
max(val1, val2, val3, ...)
min(val1, val2, val3, ...)
Maximum/minimum of the arguments (any number of arguments possible) 1 or more
year(), month(),
yearday(), day(), weekday(),
hour(), minute(), second()
Current date components as integer NONE
list(val1, val2, val3, ....) Create a list from the given arguments. The result can be used with the "in" operator, e.g. to differentiate shipping costs for different states (condition state2 in list("TX", "WS", "MS") ) 1 or more
length(list) Number of elements in the list 1 (list)
union(list1, list2, ...), join(list1, list2, ...) Join two lists to one (union and join behave identical) 2 or more
complement(list1, list2, ...) Return list of all elements of list1 that are NOT in any of the other lists 2 or more
intersection(list1, list2, ...) Return list of all elements that are in all lists 2 or more

issubset(childlist, parentlist)
contains(parentlist, childlist)

Returns whether childlist is a subset of parentlist (notice the different order of arguments for issubset and contains) exactly 2 LISTS
contains_any(list, elem1, elem2, ...)
contains_all(list, elem1, elem2, ...)
Returns whether the list contains any/all of the other arguments given. First argument needs to be a list. 2 or more
digit(value, n) Returns the n-th digit (or character) of value exactly 2
substring(string, begin, len) Returns the substring of string of length len that starts at position begin exactly 3
print_r(value) DEBUGGING function: returns the value (e.g. a list or a numeric value) as a string exactly 1

Custom Variable Definitions

Since version 4.0, one can also define your own custom variables to hold e.g. complex conditions that are used in multiple rules. The format is similar to rules (i.e. one line per variable definition):
Definition=VariableName; [Value=]ValueOfTheVariable
Instead of "Definition=" one can also use "Variable=", and the "Value=" can be left out (as long as the value does not contain any comparison operators). The VariableName needs to be one string without spaces or any special characters, the value can be any expression or condition that can be used in a rule. 
Variable definitions and shipping rules can be given in any order, but they are evaluated sequentially. In particular, a variable definition will only be available in all rules that are given after the definition.
If you want to store conditions in a variable and then use that variable in a rule, you need to mark it as a condition with "Condition=YOURVARIABLE". Otherwise, the plugin would interpret a single variable as the shipping rate.
Here is an example of a variable definition:
Name="Here VAR is not available yet: {VAR}"; Weight>100; 10
Definition=VAR; Value=1000<=ZIP<2000
Name="Here VAR is available: {VAR}"; Condition=VAR; Shipping=50
Variable definitions can overwrite/modify a previous variable definition, and they can also contain conditions:
Definition=myship; Value=0
Definition=myship; 1 in Categories; Value=myship+4
Definition=myship; 2 in Categories; Value=myship+12345
Name="Shipping costs summed up"; Shipping=myship

Supporting alphanumeric postal codes

Most countries employ numeric postal codes, which allow direct comparisons using the ZIP variable, e.g.

Name=Free shipping to Vienna (Austria); 1000<=ZIP<2000; Shipping=0
However, some countries, most notably the UK, Canada and the Netherlands use alphanumeric postal codes, which also contain letters. Their postal codes all have a certain structure, which allows the postal code to be split up into smaller parts that describe the area further. The advanced version (starting with version 2.4) of the plugin also supports those alphanumeric postal codes by providing several variables that contain the different parts of the postal codes and can be used in the conditions.

UK postal codes

UK PostalCode PartsThe UK postal codes have the form "A[A]0[0][A] 0AA", where parts in square brackets are options. The first part before the space is called "Outward" part of the postal code and is used to distribute letters to a post office for final distribution. The part after the space is called the "Inward" part and is used by the post office to sort the mail for final delivery. The "Outward" part begins with one or two letters, indicating the postcode area, followed by one or two digits, identifying the district within the area. Some districts in Central London have been further subdivided by an additional letter after the digit.

If the plugin detects that the postal code of the delivery address (or the invoice address if no shipping address is given) matches the form of UK postal codes, it will provide the following variables for use in the conditions:

UK_Outward The Outward part of the postal code (the two to five characters before the space)
UK_Area The postal area (one or two letter)
UK_District The postal district within the postal area (one or two digits)
UK_Subdistrict The subdivision of some central London districts (a letter, or empty)
UK_Inward The Inward part of the postal code (the three characters after the space)

Here are a few examples of rules for UK postal codes:

Name="Free shipping to Birmingham"; UK_Area=="B"; Shipping=0 
Name="Free shipping to parts of Walsall"; UK_Area=="WS" AND 15<=UK_District; Shipping=0
Name=No Shipping to PO boxes in North London; UK_Outward=="N1P"; NoShipping
The British overseas territories also use postal codes the follow the the structure of UK postal codes, except that the outward part consists of four letters and the inward part is always "1ZZ", e.g. "ASCN 1ZZ" for Ascension or "PCRN 1ZZ" for the pitcairn Islands. The only exception is Gibraltar whith a postal code of "GX11 1AA". For those postal codes, only the outward and the inward parts are assigned, while the area, district and subdistrict variables are empty.
Name="Free shipping to Gibraltar"; UK_Outward=="GX11" AND UK_Inward=="1AA"; Shipping=0 
Name="No shipping to Falklands"; UK_Outward=="FIQQ"; NoShipping

Canadian postal codes

Canadian PostalCode PartsThe Canadian postal codes have the form "A0A 0A0", where the first part is called the "Forward Sortation Area" (or FSA) and the final three characters are the "Local Delivery Unit" (LDU). The initial letter indicates the postal district (province/region), the number at the second position indicates either a particular urban area (if >0) or a rural area (if 0), and the letter at the third position subdivides the urban or rual area further into districts or smaller cities. The LDU then usually simply gives the delivery post office with no particular geographic rules or order.

If the plugin detects that the postal code of the delivery address (or the invoice address if no shipping address is given) matches the form of Canadian postal codes, it will provide the following variables for use in the conditions:

Canada_FSA The Forward Sortation Area (the three characters before the space)
Canada_Area The first letter (indication the Postal District, i.e. typically the province or region)
Canada_Urban The digit at the second position (indicating either a rural area if 0, or a particular urban area if larger than 0)
Canada_Subarea The letter at the third position (subdividing the urban or rural area even further)
Canada_LDU The Local Delivery Unit (the three characters after the space)

Here are a few examples of rules for Canadian postal codes:

Name=Free Shipping to British Columbia; Canada_Area=="V"; Shipping=0
Name=Chicoutimi (Quebec); Canada_Area=="G" AND Canada_Urban==7 AND "G"<=Canada_Subarea<="K"; Shipping=5
Name=Saint-Joseph-de-Coleraine; Canada_FSA=="G0N" AND Canada_LDU=="1B0"; Shipping=7
Please notice that in the third rule, the separate checks for FSA and LDU are better than a check for ZIP=="G0N 1B0", since it will also work if the user enters multiple spaces between the FSA and the LSU.
In the second rule the area and urban check could also be combined into a check whether the FSA starts with "G7": Canada_FSA~"G7"

Dutch postal codes

The postal code in the Netherlands has the structure "0000 AA" (i.e. four digits and then two letters), where the final two letters only divide the area described by the digits into even smaller parts (at the street/house level). For the calculation of shipping costs, the two final letters are practically never relevant, so by using the variable ZIP4 (the first four characters of the postal code), the Dutch postal codes can be used just like any numeric postal code:

Name=No shipping to Amsterdam; 1011<=ZIP4<=1109; NoShipping

Coupons for Lower Shipping Costs

The advanced version also provides the coupon code as a variable, which allows to make shipping depend on the coupon code given.

To make use of this feature, you need to enable VirtueMart's coupon system (AwoCoupon will not work) and create a coupon, e.g. with code "COUPON_CODE". You can then check for the coupon code in the shipping rule and make the shipping costs depend on the existence of this coupon code:

Name=Free shipping with coupon; Coupon=="COUPON_CODE"; Shipping=0
This allows standard VirtueMart coupons to influence the price as well as the shipping cost. Of course, you can use other conditions to make the coupon only apply if e.g. the order amount reaches a certain threshold, or to set a lower rater per kg, etc.

Demo Server

Examples

Frequently Asked Questions (FAQ)

License

This plugin is licenced unter the GNU GPLv3. The "Shipping by Rules Plugin" can be downloaded free of charge, while the "Advanced Shipping by Rules Plugin" (providing additional arithmetic expressions as described above) can only be downloaded after payment. In both cases, you will get all the rights (and duties) that the GPL gives you. You are allowed to use the plugin on as many webshops as you like. We try to give support as our time allows, but we cannot guarantee a certain response time. A payment for the Advanced version gives you access to all future versions of the plugin with no time restriction.

Version History

2014-10-23: Version 4.3: Add support for Joomla 3 and VirtueMart 3 (at least version 2.9.9f required); Drop support for Joomla 1.5
2014-09-11: Version 4.2: Fix a small, but tricky issue that caused lots of server log warnings about non-object
2014-01-15: Version 4.1: Don't print out a warning if a NoShipping rule has no name
2014-01-14: Version 4.0.1: (Basic plugin only) fix comparisons with strings; allow html and = in rule names
2014-01-11: Version 4.0:

  • Add custom variable definitions
  • The name of a rule with NoShipping is printed out as a warning
  • Add many list handling functions, digit and substring functions
  • Function names and operators are now case-insensitive
  • Add comments
  • Make rule names translatable
  • Support carts with multiple different tax rates
  • Add print_r function, values_debug variable

2013-09-21: Version 3.3 (Add not operator; add categories, vendors and manufacturers variables; Fix country checks)
2013-08-26: Version 3.2 (Fix some translations due to changed VM internals; Fixed country zone check)
2013-08-17: Version 3.1 (Implement lists and the in operator; add SKUs variable; add country/state name variables)
2013-07-06: Version 3.0.2 (Fix broken UK post code handling)
2013-06-23: Version 3.0.1 (Fix for PHP 5.3)
2013-06-19: Version 3.0.0 (Functions in the rules; packaging variables; Variable substitutions in the name)
2013-06-15: Version 2.4.7 (Allow UK post codes to be entered in lower-case)
2013-05-31: Version 2.4.6 (Fix shippingWithTax)
2013-05-30: Version 2.4.5 (Fix various cart price variables)
2013-05-07: Version 2.4.3 (Allow UK and Canadian postal codes to be entered without the space; ADVANCED version only)
2013-05-03: Version 2.4.2 (Added MinWeight and MaxWeight variables)
2013-03-31: Version 2.4 (Added support for UK and Canadian alphanumeric postal codes - ADVANCED version ONLY)
2013-03-30: Version 2.3 (Added NoShipping identifier to exclude shipping; Fixed shipping cost when Shipping= was left out)
2013-03-21: Version 2.2 (Fixed chained conditions; added length unit setting and conversion; added ZIP1, ZIP2, ... variables; added ~ operator to compare beginning of variables; fixed totalLength/Width/Height calculation; )
2013-03-18: Version 2.1.1 (Fixed shipping cost display in shipping selection page)
2013-03-18: Version 2.1 (Fixed bug that parameters were not saved sometimes; totalLength, totalWidth and totalHeight variables; support for Joomla! 1.5)
2013-02-14: Version 2.0 (OR operator, Coupon variable, fixed ZIP when no address given, all Price variables of the cart)
2013-01-22: Version 1.1 (implement Volume and minimal/maximal volume and product extensions )
2013-01-15: Version 1.0 (initial public release)