Blog

RSS
Shipping Director - Variable and Expression Data Types- Monday, September 3, 2012

Be sure your expression is of the correct type whether assigned to a variable, or used in one of the Expression fields of a record.  Here are the types for the various Expression Fields:

Record/ExpressionName

Data Type

Description

Option and OptionExit

 

 

Expression

Boolean

When evaluates to true, the Option is presented to customer

Rate Expression

Decimal

The calculated Rate + Surcharge appears to customer as the rate

Surcharge Expression

Decimal

 

Name Expression

String

If present, will override the record Name displayed to customer

Description Expression

String

If present, the description appears under the Name/Rate line

 

Error and ErrorExit

 

 

Expression

Boolean

When evaluates to true, the Error message is presented to customer

Description Expression

String

Required.  The description appears under the Name/Rate line

 

Packing

 

See the Packing blogs

Expression

Boolean

When evaluates to true, the packing is performed

Packing Method

literal

E.g. Packing.FirstFitSingleBox  .

Requires Own Package Expression

Boolean

Evaluated for each item

Sender Expression

Boolean

Evaluated for each item

Exclude Item Expression

Boolean

Evaluated for each item

 

Reference

 

See the Reference Type blog

Expression

literal

A reference is a type of variable that is really just a shortcut.

 

 

Notes

 

Booleans

You can use literals 'true' and 'false'.   (lowercase, no quotes)

Strings

Be sure to put literals in double quotes.
To put a double quote in your literal, use two double quotes.
If using String.Format(), beware of localization.

Decimals, Doubles, Singles

Literals must include a decimal point "." regardless of localization
If using e.g. Decimal.Parse(), beware of localization.

DateTimes

Construct literals using DateTime() - e.g. DateTime(2010,8,9).  If using DateTime.Parse(dateString), beware of localization parsing.

Rate and Surcharge Expression

Numeric only.  Do not include any leading currency symbol.

Comments (0)
Shipping Director - Built-in Variables- Monday, September 3, 2012

Here's a list of all built-in variables.  Note that they all start with a "$".  As with user defined variables, the must be enclosed in brackets when used - e.g. [$TotalWeight].

     

Shopping Cart Properties - Set by system at start of rate calculation
$TotalWeight Decimal   uses ShippingService.GetShoppingCartTotalWeight()

$SubTotalWithoutDiscounts Decimal    (uses orderTotalCalcService.GetShoppingCartSubTotal() )

$SubTotalWithDiscounts Decimal

$SubTotalWithoutDiscountsInclTax Decimal

$SubTotalWithDiscountsInclTax Decimal

$ProductTotalWithoutDiscounts Decimal    (uses PriceCalculationService.GetSubTotal() )
$ProductTotalWithDiscounts Decimal

$IsFreeShipping Decimal   uses OrderTotalCalcService.IsFreeShipping()

Shipping Director Record - Set by system for each row (used in debugging and error messages)
$Id Integer   SD record's Id field
$Order Integer   SD record's Order Field
$Name String   SD records's Name field
$Expression String   Set before each expression evaluated (Expression, RateExpression, SurchargeExpression, etc.)

Option Processing - Set by system when the record type is Option, OptionExit, OptionReplace (OptionReplace available only in SD ver 1.05 and above)
$Name String 
$Description String
$Rate Decimal (e.g. surcharge expression can use $Rate)
The Option record's Expressions can reference $Name & $Description & $Rate variables.  Thus, you can adjust the data returned by external shipping rate methods.  (Reminder – an external shipping rate method is called in the Option’s Rate Expression – e.g. Shipping.Fedex).
External shipping rate methods can return multiple options/rates.  If the $Name of an external shipping rate option is set to "", then that option is removed.
Example: To show an option name of just "Ground" and "Priority" rather than "FedEx Ground" and "FedEx Priority", use [
$Name].Replace("FedEx ", "") in the NameExpression to remove the word "FedEx " from the option name.

 

Shipping Option Request properties (These are passed to other shipping rate calculation methods to override the other methods' configuration page.  Not supported by all shipping rate methods.)
$ZipPostalCodeFrom String
$StateProvinceFrom String
$CountryFromTwoLetterIsoCode String

Set by system after other shipping rate calculation method is called
$ShippingOptionsCount Integer

SD sets this after using an external shipping plugin (or SQL) with the total # of shipping rate options it returned.  It's not typically used, but if you are doing something where you think no options will match, then you should check it and say something like "call for rate".


Packaging
$Sender string ""   Set by system when a package is rated manually (not external shipper rate).  Can then be used in Option's Rate, Surchage, Name, Description expressions
$PackageCount Integer 0   Set by system after packaging.  Although defaults to 0, if no Packaging is done, the system actually creates 1 package with all shopping cart items just before rate calculation.

Packaging using PackingFirstFitSingleBox
$PackageBoxWeight Decimal
$PackageBoxMaxWeight Decimal
$PackageBoxHeight Decimal
$PackageBoxLength Decimal
$PackageBoxWidth Decimal
$PackageItemAddWeight Decimal
$PackageItemAddDimension Decimal
$PackageShrinkPercent Integer 0 - Used by PackingFirstFitSingleBox - If $PackageShrinkPercent > 0, and the volume actually packed is less than this % of the given box volume, then this will shrink the final box to its actual packed content volume, rather than the given box volume.  ("
less than this %" => The idea is if the box is "almost full", then use the box dimensions)

Packaging's SenderExpression can evaluate to a string that can contain Ship From Location information.  The string is of the form:
"State=...; ZipCode=...; Country=...;"
This allows different Ship From address for each Sender (see Shipping Option Request properties above):


$PackageBox variable (shorthand for setting many package attributes in one line)
 e.g. $PackageBox   "MaxWeight:40,Height:15,Width:15,Length:15"
 Here's how each shorthand attribute corresponds to the built in variable:
    MaxWeight    => $PackageBoxMaxWeight
    Height       => $PackageBoxHeight
    Width        => $PackageBoxWidth
    Length       => $PackageBoxLength
    Weight       => $PackageBoxWeight
    AddWeight    => $PackageItemAddWeight
    AddDimension => $PackageItemAddDimension
    ShrinkPercent=> $PackageShrinkPercent


Rate Request Type - When Packaging, can be set by user to indicate the way that rate requests are made to other rate calculation methods when Packaging
$ShippingRateRequest String
    "OneRequestForAllPackages"
    "OneRequestPerPackage"
    "OneRequestPerSender"

E.g. "OneRequestPerPackage" => Get FedEx rates separately for each package

if $ShippingRateRequest is not set by user, then the system will default depending on if the Packing SenderExpression used:
    if no SenderExpression then "OneRequestForAllPackages" else  "OneRequestPerSender"


Debugging

$Debug boolean false   When true, detailed messages are written to the system log.

(Note:   Because log messages are not HTML formatted, they can be hard to read in the browser.  So, when viewing a System Log record, click View to see the log detail page.  Then, right click the page and "View Source".  Scroll down (a bit more than half way) until you see the plain text messages.)



Flow Control  (SD ver 1.05 and up)
$Goto Integer 0 Set to a Order/Line number. Can be conditional and dynamic. Set to 0 to skip.  E.g. Use ternary if/then/else operator $Goto condition ? 100 : 0 ==> "If condition then Goto 100 (else goto next line)"

Special Functions
Special functions must be assigned to a String variable and must be the first word in the variable’s Expression field.  The expression cannot be complex: E.g. it can be like GetLocaleString("...") or GetLocaleString([someotherstringvar]), but cannot include any operators.


GetLocaleString(<string>)   get a language specific message.
GetSetting(<string>)        get a setting

Tags :  VariablesGettingStarted
Comments (1)
Restricted Products Can’t Ship to Outside of Certain Countries.- Tuesday, August 7, 2012

In this scenario, our requirement is to prevent shipping certain products to countries outside of the European Union (EU 27).  Similar to the last blog, you should set up an unpublished category for the restricted products.  Then, in SD, we check if both the shipping address is outside the permitted countries and the cart contains restricted products.  If this condition occurs, the ErrorExit line will cause the message "Sorry, we can't ship restricted products outside the EU" to appear to the customer, and prevent them from checking out. (The double quotes are required because Description Expression is an expression) 

Order

Type

Name

Expression

Description Expression

30

String

EU_27

"AT,BE,BG,CY,CZ,DK,EE,FI,FR,DE,GR,HU,IE,IT,LV,LT,

LU,MT,NL,PL,PT,RO,SK,SI,ES,SE,GB,"

 

40

Boolean

IsRestrictedCountry

![EU_27].Contains(ShippingAddress.Country.TwoLetterIsoCode)

 

50

ErrorExit

 Restricted Products

[IsRestrictedCountry] and Items.Any(Product.HasCategory("Restricted Shipping"))

"Sorry, we can't ship restricted products outside the EU"

60

Option

 

 

 

  Order Line 60 would be whatever Option(s) you would want to offer.

(The above blog was updated 9/8/2013.  Older versions of Shipping Director did not have HasCategory() function, and used a more complex expression to get the Category:

Order

Type

Name

Expression

Description Expression

10

Reference

categories

 ProductVariant.Product.ProductCategories

 

20

Reference

categoriesAny_Restricted

 [@categories].Any(Category.Name = "Restricted Shipping")

 

30

String

EU_27

"AT,BE,BG,CY,CZ,DK,EE,FI,FR,DE,GR,HU,IE,IT,LV,LT,

LU,MT,NL,PL,PT,RO,SK,SI,ES,SE,GB,"

 

40

Boolean

IsRestrictedCountry

![EU_27].Contains(ShippingAddress.Country.TwoLetterIsoCode)

 

50

ErrorExit

 Restricted Products

 [IsRestrictedCountry] and Items.Any([@categoriesAny_Restricted])

"Sorry, we can't ship restricted products outside the EU"

60

Option

 

 

 


Tags :  Restricted
Comments (1)
Next Day Shipping Rate depends on if any or all items are eligible for it.- Thursday, August 2, 2012

In this scenario, our requirement is to offer Standard Shipping and Next Day Shipping methods with fixed amount for each: £3 for Standard and £10 for Next Day).  However, only certain products can be sent on Next Day delivery.  We need the checkout process to exclude Next Day if not applicable.   Additionally, if the cart has a mix of products, some that allow Next Day and some that don't, we want to charge BOTH the Standard and Next Day delivery charge combined on the order (£3 + £10 = £13).

So, we always want to offer Standard shipping at £3, and then additionally offer Next Day if the cart has any Next Day eligible products – but if the cart has a mix, then since we need to ship out two deliveries, we want to charge for both.  Here are the possible cases:

No Next Day eligible products:

Standard              £3

All Next Day eligible products:

Standard              £3

Next Day             £10

Some Next Day eligible products, and some not:

Standard              £3

Next Day             £13

And here’s one way to do it in Shipping Director:

Create a (non-published) Category called “Can Ship Next Day”, and put all eligible products in that category.   (Remember, products can be in more than one category).  Then, just configure Shipping Director! 

Order

Type

Name

Expression

Rate Expression

10

Reference

canShipNextDay

Product.HasCategory("Can Ship Next Day")

 

30

Option

Standard

true

3

40

OptionExit

Next Day

Items.All([@canShipNextDay])

10

50

OptionExit

Next Day

Items.Any([@canShipNextDay])

13

 

(The above blog was updated 9/8/2013.  Older versions of Shipping Director did not have HasCategory() function, and used a more complex expression to get the Category: 

Order

Type

Name

Expression

Rate Expression

10

Reference

categories

ProductVariant.Product.ProductCategories

 

20

Reference

categoriesAny_CanShipNextDay

[@categories].Any(Category.Name = "Can Ship Next Day")

 

30

Option

Standard

true

3

40

OptionExit

Next Day

Items.All([@categoriesAny_CanShipNextDay])

10

50

OptionExit

Next Day

Items.Any([@categoriesAny_CanShipNextDay])

13



Tags :  VariableRate
Comments (0)
Exclude Ground Shipping Based on State- Wednesday, June 13, 2012

First, I recommend checking if a Country/State/Zip has been provided, because the “Estimate Shipping” will work even if they are not selected, and depending on rate calculation method (shipping plugin), you could get funny results, or an error. (Only US and Canada have states.)   For this, we use the ErrorExit record Type.  This will Exit if the Expression (condition) evaluates to true, and the customer will see the message calculated in the Description Expression.  Note, that this is a String Expression, so be sure to include quotes for a literal value.

Order

10

Type

ErrorExit

Name

Missing Country State Zip

Expression

ShippingAddress.Country = null or ShippingAddress.ZipPostalCode = null or ("US,CA".Contains(ShippingAddress.Country.TwoLetterIsoCode) and ShippingAddress.StateProvince = null)

Description Expression

"Please Enter Country, State, and Postal Code"

Then, let’s say we want to prevent shipping if the State is Alaska or Hawaii.  We would use the ErrorExit type here too:

Order

20

Type

ErrorExit

Name

No Shipping to Alaska and Hawaii

Expression

"AK,HI".Contains(ShippingAddress.StateProvince.Abbreviation)

Description Expression

"Sorry, we can’t ship to Alaska or Hawaii"

The condition Expression could have also been written as

Expression

ShippingAddress.StateProvince.Abbreviation = "HI" or ShippingAddress.StateProvince.Abbreviation = "AK"

But when using an “or”, be sure to use parenthesis if you have a more complex expression that includes “and”s too.

Alternately, you may just want to exclude just Ground shipping to Alaska and Hawaii.  For example, you want to use the Shipping.ByWeight rate calculation method, but don’t want to offer Ground to Alaska or Hawaii.  Then the above would instead be entered with an Option type:

Order

20

Type

Option

Name

Ship By Weight but no Ground for AK and HI

Expression

true

Rate Expression

Shipping.ByWeight

Name Expression

"AK,HI".Contains(ShippingAddress.StateProvince.Abbreviation) and [$Name].Contains("Ground") ? "" : [$Name]

For the Option type, the Expression field is a condition.  If it evaluates to true, then the option record is processed, otherwise it's skipped.  The Rate Expression can either be a decimal expression calculating the actual rate you want to charge, or the name of a shipping plugin.  The Name Expression calculates the shipping option Name shown to the customer.  However, if the Name Expression evaluates to blank (""), then Shipping Director will exclude the Option.  The [$Name] is a built-in variable that contains the Name of the shipping option as returned by the other rate caclulation plugin.  So, here we are saying "if the state is Alaska or Hawaii, then exlude the named option, else show the named option".  The If-Then-Else is achieved using the " ? : " ternary operator -  condition ? if-true : if-false.

Tags :  ExcludeOptionErrorExit
Comments (6)
Per Item Shipping Rates- Tuesday, June 12, 2012

Here's a simple but useful shipping scenario:

First Item shipping would be £3.50
Each additional Item adds £1.00

So, for example, 3 items would be £3.50 + £1 + £1 = £5.50

This is easily handled by Shipping Director with a single Option type record:

Type:

Option

Name:

Shipping Rate

Expression:

true

Rate Expression:

3.50 + ((Items.Sum(Quantity)-1) * 1.00)

You can even decide to charge different rates for different countries or postal codes.  For example, shipping to the Highlands and the islands should be

First Item shipping would be £5.50
Each additional Item adds £1.50

For that, we would just add an OptionExit type record ordered before the previous one.  

Type:

OptionExit

Name:

Shipping Rate

Expression:

",AB,BT,DD,HS,IM,IV,KA,PA,PH,TR,ZE,".Contains( Zip.Substring(0,2) )

Rate Expression:

5.50 + ((Items.Sum(Quantity)-1) * 1.50)

OptionExit will exit with the calculated rate when the "Expression" condition is true.  Whereas "Option" with true expression will return the caclulated rate, and continue looking for more Options.

(Note, the above postal codes are just examples.  Determining all the actual codes for the Highlands & islands is more complex)

And finally, a little about the "Name:" field.  This is the option's name displayed to the customer.  In the examples above both Option records used the same Name "Shipping Rate".  But, the Highlands Option could have used "Shipping to Highlands and Islands".   Or, you can also include a "Name Expression".  If none is present, then the "Name" is displayed to the customer.  The Name Expression allows you to caclulate the option's name displayed to the customer.  For examples, see the other blogs like this one where the weight is included in the option name, and see this blog about using localized resources

UPDATE:

The postal code expression above was updated;  in older versions the "Zip" part was written as

  ShippingAddress.ZipPostalCode.Substring(0,2)

Additionally, in any version, you should probably have a prior rule to check that a Zip/Postal code was entered, otherwise an error will result - e.g.

ErrorExit   String.IsNullOrWhitespace(Zip)         "Please enter a zip/postal code"

Tags :  RatePerItem
Comments (2)
Exclude Shipping Options from Carrier Plugins- Monday, May 21, 2012

(Updated 11/29/2013 for Shipping Director versions for nopCommerce 3.x) 

For external shipping rate methods (carrier plugins like FedEx, USPS, etc.), which can return many options, it may be desirable to conditionally eliminate some options.

In this example, we only offer USPS Media Mail if all items in the cart are books:

Order

Type

Name

Expression

Rate Expression

Name Expression

10

Boolean

CategoriesAllBooks

Items.All(Product.HasCategory("Books"))

 

 

100

Option

USPS

true

Shipping.USPS

[$Name].Contains("Media Mail") and ![CategoriesAllBooks] ? "" : [$Name]

Of course you're not limited to checking Categories.  For example, you could also eliminate an option based on there being any item in the cart with the Product Name Length greater than X.  E.g.

Items.Any(ProductVariant.Product.Name.Length > 12)

_________________________________________________________________________________________________  

Here's the old version for nopC 2.x having Product Variants, and prior to SD having HasCategory() function:

Order

Type

Name

Expression

Rate Expression

Name Expression

10

Reference

categories

ProductVariant.Product.ProductCategories

 

 

20

Boolean

categoriesAllBooks

Items.All([@categories].Any(Category.Name = "Books"))

 

 

100

Option

USPS

true

Shipping.USPS

[$Name].Contains("Media Mail") and ![categoriesAllBooks] ? "" : [$Name]


Tags :  ExcludeOption
Comments (9)
Shipping Rates with a Minimum Charge- Sunday, May 20, 2012

As previously mentioned, I'll be posting some more simple shipping examples...

The first shipping computation example we'll configure is:

Charge a fixed rate of 6% of the shopping cart sub total; however there should be a minimum of $10.

Here are some Shopping Cart Properties that are pre-defined variables in Shipping Director:

$TotalWeightDecimaluses ShippingService.GetShoppingCartTotalWeight()
$SubTotalWithoutDiscountsDecimaluses PriceCalculationService.GetSubTotal()
$SubTotalWithDiscountsDecimaluses PriceCalculationService.GetSubTotal()
$IsFreeShippingDecimaluses OrderTotalCalcService.IsFreeShipping()

(All pre-defined variables start with "$".  Also, when referenced, don't forget to enclose variable names in square brackets [ ] .)

So, 6% of  our "shopping cart sub total" would look like   [$SubTotalWithoutDiscounts] * 0.06

We want to calculate:  If 6% of subtotal is greater than $10, then use it, else use $10.  The If-Then-Else is achieved using the "? : " ternary operator -  condition ? if-true : if-false.

Here's the final record entry:

Above you can see how easy it is to have fixed rates with a minimum charge.   You can have a minimum shipping fee even when using actual rates from an external shipping method (like UPS, Fedex, USPS);  it's easily achieved using the Surcharge Expression - if the Rate returned by the shipper is more than $10, then no surcharge ($0), else the surcharge is the difference between $10 and the Rate returned.


Of course, you'd probably want to change the Name to something like "Shipping Rate".  Or, leave the name for your benefit, and use the Name Expression to override it when displayed to customer.  The Name Expression expects a string expression, so be sure to enclose any text in double quotes.

Tags :  MinimumCharge
Comments (0)
Only Allow Shipping to a Certain Country- Wednesday, May 16, 2012

Only allow shipping if the destination country is Mexico:

Create this record with a low "Order" (e.g. 10) , so that it gets evaluated before any shipping Options.

Tags :  Country
Comments (0)
Fixed Rate when less than X kg, otherwise per kg rate- Wednesday, May 16, 2012

The last few posts have been fairly complex scenarios.  I'll be posting some more simple shipping examples...

The shipping computation we'll configure is:

If the total weight is less than 5 kg, then the shipping will be a flat rate of $20.00, 

and if the total weight is 5 kg or more, then there will be a shipping rate of $4.00 per kilo.



Note the Name Expression on the above option.  This is optional.  In this case, it allows you to show the actual weight in the Shipping Rate Name shown to the customer.  E.g.

    Shipping for 9.1 kg ($36.40)

You can also choose to use a Ceiling math function in the Rate Expression so that fractions of weight roll up to the next whole integer:

   Math.Ceiling([$TotalWeight]) * 4.00

Shipping for 9.1 kg ($40.00)

Comments (0)
 First ... Previous 4 5 6 7 8 Next ... Last