Blog posts tagged with 'GettingStarted'

RSS
Expressions can use Extension Methods- Tuesday, January 7, 2014

When writing expressions, it is typically necessary to access the objects within the "context" of the calculation (for both Shipping Rates and Payment Methods).  The context includes the Customer and the Shopping Cart (Items) among other objects.  For example, if you need to know how many items are in the cart, the expression might look like:  Items.Count().   Items is a collection, and "Count()" is a a built in method (Linq) that counts the number of items in a collection.  NopCommerce objects have properties - e.g. a (shopping cart) Item has a Product property and a Quantity property.  So, Items.Count() is not really an accurate count of the # of products in the cart.  To do that, you need to sum the Quantity: Items.Sum(Quantity).   Without going into details about writing Linq expressions, suffice it to say that to use them in SD & PD it's necessary to access properties of nopCommerce objects, and we sometimes need helper methods that are more specific to nopCommerce objects (see this blog about Shopping Cart Object and Query Operators , but note it's based on the older nopCommerce versions that had product variants).  So, here's a list of helper methods (and also includes String helper methods). To use them, follow the nopCommerce object with a "." followed by the method name - e.g. Customer.IsInRole("Member").  In the future, I'll come back and fill in the Description column with more info/examples.


Class / Extension

Return

Description

String

 

 

SubstringAfter(value [,includeDelimiter = false])

String

 

SubstringBefore(value [,includeDelimiter = false])

String

 

SubstringBetween(value [,includeDelimiter = false])

String

 

SubstringRemove(value
    [,stringComparison = StringComparison.InvariantCulture])

String

 

SubstringRemoveIgnoreCase(value)

String

 

ToTitleCase()

String

 

ToOnlyAlphaAndDigits()

String

 

Split(string [,separator])

String

 

IsNumeric()

Boolean

 

IsInteger()

Boolean

 

SelectSingleNode(xpath)

XmlNode

 

Customer

 

 

IsInRole(roleSystemName)

(or  IsInCustomerRole(roleSystemName)  )

Boolean

E.g. Customer.IsInRole("Free Shipping") 

Be sure to assign the Role's "System name" field.

If you need to do a wildcard match, use e.g.  Customer.CustomerRoles.Any(SystemName.Contains("Discount"))

(UPDATE: The  CustomerRoles collection  no longer works as of SD for 4.30 -

GetAttribute(attributeName)

String

 

GetAttributeValues(attributeName [valueSeparator])

String

attribute value, or if list/checkboxes, then separated list of selected values for attribute (nopC 3.30+)

HasAttributeValue(attributeName)

HasAttributeValue(attributeName, valueName)

HasAttributeValue(attributeName, valueId)

Boolean

True if has attribute [and value]

HasDiscountCouponCode("couponcode")

Boolean

True if customer used coupon code. (Case is ignored,)

AppliedDiscountCouponCodes()

string[]

You can use .Contains(), .Any(), etc. to test the array

Example: Customer.AppliedDiscountCouponCodes().Any()

GetOrders()

Orders collection

 

GetRewardPointsBalancePoints()

Integer

 

GetRewardPointsBalanceAmount()

Decimal

 

Product

 

 

HasCategory(categoryName)

Boolean

 Example: Product.HasCategory("Free Shipping")

HasCategory(categoryId)

Boolean

 Example: Product.HasCategory(5)

HasCategoryMatch(categoryNameRegex)

Boolean

 Example: Product.HasCategoryMatch("Brushes") 

   (has a category that has the word "Brushes" in its name)

HasParentCategory(categoryName)

Boolean

 

HasParentCategory(categoryId)

Boolean

 

HasParentCategoryMatch(categoryNameRegex)

Boolean

 

HasManufacturer(manufacturerName)

Boolean

 

HasManufacturer(manufacturerId)

Boolean

 

ShoppingCartItem

 

 

GetWeight()

Decimal

Shopping Cart Item Weight (Includes attribute weight if any.) (The weight is for single item; multiply by Quantity if required)

GetAttributeValues(attributeName [, valueSeparator = ", "])

String

returns string of separated values for given attributeName

HasAttributeValue(attributeName [, valueName])

Boolean

if no valueName param passed, then any for given attributeName

HasAttributeValue(valueId)

Boolean

 

GetVendor()

Vendor

 

GetVendorAddresses()

Address collection

 

GetShippingOriginAddress()

Address

If the product has a warehouse assigned, then this returns that warehouse's address, otherwise it returns the shipping origin address in Shipping Settings.

example: surcharge if any cart items are being shipped from Zip Code 12345

 Decimal  Surcharge    Items.Any(GetShippingOriginAddress().ZipPostalCode = "12345") ? 2 : 0

GetWarehouse()

Warehouse

 

GetSubTotalWithDiscounts()

Decimal

 

GetSubTotalWithoutDiscounts()

Decimal

 

HasSku(sku)

Boolean

 Will also test against product attribute combinations SKU

Address

 

 

ToSenderString([defaultIfNone])

String

*

GetState()

StateProvince

In Shipping Director you can just use State to get the two character state abbreviation.
In Payment Director you can use ShippingAddress.GetState().Abbreviation

GetCountry()

Country

In Shipping Director you can just use Country to get the two character country code.
In Payment Director you can use ShippingAddress.GetCountry().TwoLetterIsoCode

ZipPostalCode

string

In Shipping Director you can just use Zip to get the postal zip code.
In Payment Director you can use ShippingAddress.ZipPostalCode

GetAttributeValues()

string

Since attributes can be defined as checkboxes that can multi-select
this function can return a comma separated value
If your field is a Text Box expecting a numeric value, you can parse it
Example: Decimal.Parse(ShippingAddress.GetAttributeValues("MinShippingAmount"))

Warehouse

 

 

ToSenderString([defaultIfNone])

String

**

GetAddress()

String

Check that a product has a warehouse before using this.  It's safer to use an Item's GetShippingOrigiAddress() (see above)

(Root)

 

 

GetLocaleStringResourceByName(resourceName)

String

 

*SenderStringFormat - Address

{Company}:Address={Address1};City={City};StateProvince={StateProvince};ZipCode={ZipPostalCode};Country={Country.TwoLetterIsoCode};

*SenderStringFormat - Warehouse

{Warehouse.Name}:Address={Address1};City={City};StateProvince={StateProvince};ZipCode={ZipPostalCode};Country={Country.TwoLetterIsoCode};

Tags :  VariablesGettingStarted
Comments (0)
Flat Rate Shipping with Multiple Options- Sunday, October 7, 2012

Here a basic example of how to set up various shipping rate options.  When you have certain conditions that depend on Country where you only want to offer a single option, then use OptionExit so that no other options are evaluated.  When you want to offer multiple options, then use Option - each condition expression is evaluated, and if true, then the option is presented to the customer.  A typical example would be when you want to offer Ground, Next day, etc.

Example requirements:

  • International $100
  • Canada $55
  • Hawaii & Alaska $55
  • Free ground shipping orders over $100, except HI and AK.
  • Ground $15 for all orders under $100
  • Next Day Air $95
  • 2 Day Air $85
  • 3 Day Air $75

Order

Type

Name

Expression

Rate Expression

100

String

Country

ShippingAddress.Country.TwoLetterIsoCode

 

110

String

State

ShippingAddress.StateProvince.Abbreviation

 

200

OptionExit

International

!("US,CA".Contains([Country]))

100

210

OptionExit

Canada

[Country] = "CA"

55

220

OptionExit

Hawaii & Alaska

"AK,HI".Contains([State])

55

300

Option

Free Ground Shipping

[$SubTotalWithDiscounts] > 100

0

310

Option

Ground

[$SubTotalWithDiscounts] <= 100

15

320

Option

Next Day Air

true

95

330

Option

2 Day Air

true

85

340

Option

3 Day Air

true

75

 

Also, check out the first part of this blog   I.e. you need to use ErrorExit to check for country/state as the initial record, because if in Estimate Shipping the customer does not choose a Country or State it will cause an error in the above references.

You can leave out the zip code check based on above conditions:

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


Tags :  FlatRateGettingStarted
Comments (2)
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)
The Shipping Director is an "evaluation engine"- Wednesday, December 7, 2011

The Shipping Director is an "evaluation engine".  Each row is evaluated based on "Order".  (Some old school VB developers may notice the numbering scheme in the example screen below. :)  The "Type" of each row is either a variable (String, Boolean, etc.), an Error, or a shipping Option.  For Variables, the "Expression" field should evaluate to the type of the declaration.  For Error and Option, the "Expression" field is a 'condition' that should evaluate to a boolean - if true, the additional expressions are evaluated (rate, surcharge, etc.), and if false, the next row is examined.  You can specify whether the rows continue to evaluate, or "Exit" when matched - ErrorExit, OptionExit.  Additionally, there is (not shown below) a global setting: "Evaluate All" vs. "EvaluateFirstMatchOnly", whereby a plain Exit or Option will exit if EvaluateFirstMatchOnly is set.


Below are some sample expressions in context of the Configure screen.   (Note that NameExpression and DescriptionExpression must evaluate to strings - if you just have text, be sure to enclose it in double quotes.)


Sample Expressions

Tags :  GettingStarted
Comments (2)
The Shopping Cart Object and Query Operators- Saturday, December 3, 2011

(Update: 12/20/2021 - This is a very old blog.  Some of the properties have changed.  Contact us at support@noptools.com for up-to-date information.)

The previous blog discussed expressions, and that the underlying attributes of the Shopping Cart can be referenced.  Below is a partial shopping cart hierarchy.  You use a dot (".") between attributes in the hierachy to reference children.  Some attributes are collections (lists), that can contain 0 or more other objects.  All expressions must yield a scalar value, so collections must have some Query Operator applied like All() [a boolean], or Sum() [a decimal].

Some query operators, like All(), will return a boolean.  For example, Any() will return true if any items in the collection meet the criteria.  For example - The customer has the Administrator role:

Customer.CustomerRoles.Any(Name = "Administrators")

Some query operators, like Where(), will return a subset which is still a collection, so a First() operator must then be applied and then probably followed with an attribute name.  This Where().First() is a common scenario.  For example,  check if customer has the role with Any() above, and then check if that  role is Active:

and Customer.CustomerRoles.Where(Name = "Administrators").First().Active  

 Customer                Customer
     Id                      1
     Username                user@optonline.net
     Email                   user@optonline.net
     AdminComment            NULL
     LanguageId              NULL
     CurrencyId              NULL
     TaxDisplayTypeId        0
     IsTaxExempt             False
     VatNumber               NULL
     VatNumberStatusId       0
     CheckoutAttributes      
     DiscountCouponCode      
     GiftCardCouponCodes     
     UseRewardPointsDuringCheckout    False
     TimeZoneId              NULL
     AffiliateId             NULL
     Active                  True
     IsSystemAccount         False
     SystemName              NULL
     CreatedOnUtc            9/3/2011 2:08:02 AM
     Affiliate               NULL
     Language                NULL
     Currency                NULL
     CustomerRoles           Collection[CustomerRole]
         Id                      1
         Name                    Administrators
         FreeShipping            False
         TaxExempt               False
         Active                  True
         IsSystemRole            True
         SystemName              Administrators

     CustomerAttributes      Collection[CustomerAttribute]
         Key                     FirstName
         Value                   John


         Key                     LastName
         Value                   Smith


         Key                     LastVisitedPage
         Value                   http://localhost:7872/


         Key                     LastShippingOption
         Value                   


         Key                     LastContinueShoppingPage
         Value                   http://localhost:7872/m/261/test           


         Key                     Gender
         Value                   


         Key                     DateOfBirth
         Value                   


         Key                     Company
         Value                           


 Items                   List[ShoppingCartItem]
         Id                      16
         ProductVariantId        59
         CustomerEnteredPrice    0.0000
         Quantity                1
         CreatedOnUtc            10/5/2011 3:12:37 AM
         UpdatedOnUtc            10/15/2011 1:52:19 AM
         ProductVariant          
             Id                      59
             ProductId               58
             Name                    Box Cutter
             Sku                     123456789
             Description             NULL
             AdminComment            NULL
             ManufacturerPartNumber    099999
             IsGiftCard              False
             GiftCardTypeId          0
             ...
             IsDownload              False
             ...
             IsFreeShipping          False
             AdditionalShippingCharge    0.0000
             IsTaxExempt             False
             TaxCategoryId           0
             ...
             CallForPrice            False
             Price                   52.9100
             ...
             Weight                  1.0000
             Length                  0.0000
             Width                   0.0000
             Height                  0.0000
             ...
             Product                 System.Data.Entity.DynamicProxies.Product
                 Id                      58
                 Name                    Box Cutter
                 ShortDescription        NULL
                 ...
                 ProductCategories       Collection[ProductCategory]
                     Id                      14
                     ProductId               58
                     CategoryId              72
                     IsFeaturedProduct       False
                     DisplayOrder            1
                     Category                Category
                         Id                      72
                         Name                    Box Cutter Knife, Blades
                         Description             NULL
                         ...


                 ProductManufacturers    Collection[ProductManufacturer]
                     Id                      14
                     ProductId               58
                     ManufacturerId          5
                     IsFeaturedProduct       False
                     DisplayOrder            1
                     Manufacturer            Manufacturer
                         Id                      5
                         Name                    ABC Industries
                         Description             NULL
                         ...



 ShippingAddress         Address
     FirstName               NULL
     LastName                NULL
     Email                   NULL
     Company                 NULL
     CountryId               1
     StateProvinceId         40
     City                    NULL
     Address1                NULL
     Address2                NULL
     ZipPostalCode           10021
     PhoneNumber             NULL
     FaxNumber               NULL
     CreatedOnUtc            1/1/0001 12:00:00 AM
     Country                 Country
        Country : 1
     StateProvince           StateProvince
        StateProvince : 40
     Id                      0

 CountryFrom             NULL
 StateProvinceFrom       NULL
 ZipPostalCodeFrom       



                                                              
Tags :  GettingStarted
Comments (3)
Shipping Director - Sample Expressions- Saturday, December 3, 2011

Expressions are created by referencing variables that you define, or the underlying attributes of the Shopping Cart.  Expressions are built using variables and properties of the shipping request (e.g. Customer, Items collection, etc.).   Simple expressions just use typical operators like "+", "-", "and", "or", etc.  Queries use a variant of Linq syntax (no lambda symbol "=>" required).  Queries are applied to collections to "extract" the items in the collection that meet the query criteria.

When variable names are used in expressions, they must be enclosed in square brackets - e.g. [ZipCode3].  Variables can be boolean, string, decimal, integer, etc.  Query expressions and Attributes are referenced without enclosing brackets.  Most attributes are "objects" that themselves contain other attributes.  Some attributes are collections (lists), that can contain 0 or more other objects.  Developers having a familiarity with the nopCommerce shopping cart object and linq syntax certainly have an advantage when creating expressions, but the syntax is not that hard to grasp given some examples, and future blogs will discuss the cart,, and provide more examples.  Here are some examples that may commonly be used:

Only 2 free items allowed

Items.Where(ProductVariant.Price = 0).Sum(Quantity) > 2

Has Role with Free Shipping

Customer.CustomerRoles.Any(Name = "FreeShipping")  (* see below update)

Affiliated to XYZ

Customer.AffiliateId = 1

Placed 2 or more orders in past 30 days

Customer.Orders.Where((DateTime.Now - CreatedOnUtc).TotalDays <= 30).Count() >= 2

IsOverweight2

[$TotalWeight] > 150

ZipCode3
ZoneRate

ShippingAddress.ZipPostalCode.Substring(0,3)
EXECUTE ShippingZone_LookupRate @p1, @p2; [ZipCode3], [$TotalWeight]

(Update: 12/12/2012 - see this for more about Variable and Expression Data Types )

(Update: 12/20/2021 - Customer.CustomerRoles won't work in 4.x and above.   Use Customer.GetCustomerRoles() to get the full collection, or to check a specific role, use helper property  Customer.IsInRole("role system name") )

Comments (3)