Blog

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 fille 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

 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"))

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]

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

 

GetSku()

Boolean

 Will also test against product attribute combinations SKU

Address

 

 

ToSenderString([defaultIfNone])

String

*

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)
More per-store information- Thursday, December 19, 2013
Shipping Director and Payment Director have built-in variables that you can use to configure your scenario on a per store basis:
  • $CurrentStoreId
  • $CurrentStoreName

(UPDATE:  You no longer need to use [$CurrentStoreId] or [$CurrentStoreName].  You can just use 

  • CurrentStoreId
  • CurrentStoreName

 e.g.  CurrentStoreId = 1

)

The 2nd half of this example describes that:


When using Shipping Director, it must be the only Active shipping method.  You can still use/call other carriers (e.g. USPS, FedEx, etc.) from Shipping Director, and you can configure them in their configuration page, but they must not be Active.  Thus, if you use Shipping Director in a multi-store environment, then you must have a License for each URL.

Similarly for Payment Director; if you want conditional payment methods for one store, and allow all the payment methods for another store, you still need to purchase multiple licenses.

When you purchase each license, you will enter a specific url, and then download the License.txt file.  Each file will be called "License.txt", and you must rename them uniquely but starting with the text "License", and having ".txt" extension (e.g. License_store1.txt, License_store2.txt, etc.).  Put them all in the plugin folder.

Tags :  Multi-Store
Comments (0)
Exclude Letter and Postcards from USPS First Class- Friday, November 29, 2013

In a prior post, I presented an example where it was desired to Exclude Shipping Options from Carrier Plugins

Here’s a similar recent scenario I helped a client configure.  The client uses USPS and wanted to offer First Class Parcel, but not First Class Letter or First Class Postcards.   Out of the box, the USPS shipping plugin only has a checkbox for “First Class”.  USPS will return all applicable first class methods/rates that match the input dimensions (weight, height, etc.).  If you’re not using dimensions, or you have really small/light items (like physical gift cards), you could see the Letter & Postcards methods.  For example, if in the USPS plugin configuration page you check off First Class, Priority Mail Express, and Priority Mail, then you could get back all these options (if your cart is “light”):

USPS Priority Mail Express 1-Day™ ($25.25) 
USPS Priority Mail 2-Day™ ($6.00) 
USPS First-Class Mail® Parcel ($2.07) 
USPS First-Class Mail® Letter ($0.66) 
USPS First-Class Mail® Postcards ($0.33)

So, if you’re not using dimensions, or you have really small/light items and you don’t want to offer Letter & Postcards methods, then they can be excluded by Shipping Director using the [$Name] variable in the Option record’s Name Expression.

The client also wanted to exclude First Class Parcel if the cart contained certain items.   As per previous blogs, the recommendation is to create an unpublished Category for those products.  (Products can be in more than one category.)

And, to make this more interesting, let’s say that there are two stores.  The first store offers in-store pick up and the methods as described above.  The second store will only offer the “Priority Mail” methods.

First, on lines 10 & 20, it has the requisite checks for Address (because Estimate Shipping does not), and also includes on line 30 a check to reject PO Boxes.  On line 100 is the check if there are any items in the cart that should cause the Parcel method to be suppressed.  Line 110 is the in-store option, but the Expression is set to only allow it for store 1 ([$CurrentStoreId]=1).  Line 130 is the USPS option for store 1 (includes the Name filtering using the ternary if-then-else operator “ ? : “ ).  Finally, on line 150, is the USPS option for store 2 also using “ ? : “.  When an external shipping plugin (e.g. “Shipping.USPS”) is in the Rate Expression field, the Name Expression checks each method from the carrier, and if the expression evaluates to blank (“”) the method is suppressed.

Order

Type

Name

Expression

Rate Expression

Name Expression

Description Expression

10

ErrorExit

No State Entered

ShippingAddress.StateProvince = null

 

 

"Please enter Country, State, and Zip"

20

ErrorExit

No Zip Entered

ShippingAddress.ZipPostalCode = null

 

 

"Please enter Country, State, and Zip"

30

ErrorExit

No PO Boxes

ShippingAddress.Address1 != null and Regex.IsMatch(ShippingAddress.Address1, "(?i)\b(?:Post\ (?:Office\ )?|P[.\ ]?O\.?\ )?Box\b")

 

 

"Sorry, we can't ship to PO Boxes."

100

Boolean

SuppressParcel

Items.Any(Product.HasCategory("Suppress Parcel"))

 

 

 

110

Option

In-Store Pickup

[$CurrentStoreId]=1

0

 

"Customer will pick-up at our store in YourTown, NY"

130

Option

US Mail Store 1

[$CurrentStoreId]=1

Shipping.USPS

[$Name].Contains("Letter") or [$Name].Contains("Postcards") or ([$Name].Contains("Parcel") and [SuppressParcel]) ? "" : [$Name]

 

150

Option

US Mail Store 2

[$CurrentStoreId]=2

Shipping.USPS

 [$Name].Contains("Priority Mail") ? [$Name] : ""

 

You can download the configuration import file by clicking on this link ShippingDirector (Exclude Letter and Postcards from USPS First Class).txt


Tags :  ExcludeOptionMulti-Store
Comments (0)
Html in Shipping Method error messages- Sunday, November 17, 2013

Shipping Director provides ability for the calculation of an Error Description using the Error (or ErrorExit) record type.  But, out of the box, nopC will not show the HTML correctly.  One needs to just modify the view file - e.g.

\Views\ShoppingCart\EstimateShipping.cshtml
change from 
    @foreach (var error in Model.Warnings)
    {
        <li>@error</li>
    }

to
    @foreach (var error in Model.Warnings)
    {
        <li>@Html.Raw(error)</li>
    }


similarly in

\Views\Checkout\ShippingMethod.cshtml
\Views\Checkout\ShippingMethod.Mobile.cshtml
\Views\Checkout\OpcShippingMethods.cshtml

Tags :  HTML
Comments (0)
Shipping Director Video- Monday, October 7, 2013
Tags :  Video
Comments (0)
Add a handling charge for a manufacturer- Monday, July 8, 2013

If one of your suppliers (manufacturers) charges a handling fee for orders, you can pass that fee on to your customers.

Order

Type

Name

Expression

Rate Expression

Surcharge Expression

10

Reference

HasManufacturer

Product.ProductManufacturers.Any

 

 

20

Reference

hasManufacturerX

[@HasManufacturer](Manufacturer.Name = "X")

 

 

50

Decimal

SurchargeForX

Items.Any([@hasManufacturerX]) ? 10 : 0

 

 

100

Option

Shipping

true

Shipping.Fedex

[SurchargeForX]

Additionally, you can show the customer a description explaining that a fee has been added (it appears to customer under the shipping option name).  Just include a Description Expression on the Option line:

[SurchargeForX] = 0 ? "" : "A $" + [Surcharge].ToString() + " has been added because your cart contains a product from manufacturer X"

If you only want to charge the fee if the total amount of merchandise from that particular manufacturer is under $250, then we need to calculate the total $ amount of the items for that manufacturer, and then the expression for SurchargeForX would need to check if that total less than $250:

Modify the above - add line 30 for the total $ calculation and change line 50 to use the total:

Order

Type

Name

Expression

Rate Expression

Surcharge Expression

 

 

 

 

 

30

Decimal

TotalForX

Items.Where([@hasManufacturerX]) .Sum(Product.Price  * Quantity)

 

 

50

Decimal

SurchargeForX

[TotalForX] < 250 ? 10 : 0

 

 

Note, that the “the total amount of merchandise from that particular manufacturer” is the full price amount – i.e. does not include any discounts.

(Updated Aug. 2014.  If using nopCommerce versions prior to 3.00, then use ProductVariant.Product in plasce of just Product, and ProductVariant.Price in place of Product.Price)

Tags :  Manufacturer Fee
Comments (0)
Payment Director - If certain product is in cart, then only allow COD payment method- Monday, June 10, 2013

In this Payment Director example, we only want to allow COD if the cart contains an IPod.

Set up a variable to calculate the condition, and then suppress all options except COD if the condition is not met.  For example, let’s say that you generally offer two payment methods – COD, and Credit Card (e.g. Authorize.net).  However, if the cart contains an IPod, then you only want to offer COD:

Order

Type

Name

Expression

Fee Expression

Friendly Name Expression

10

Boolean

Only_COD_Allowed

Items.Any( Product.HasCategory("IPods") )

 

20

Option

Payments.CashOnDelivery

Show

 

30

Option

Payments.AuthorizeNet

![Only_COD_Allowed]

 

(The “!” is the NOT operator)

Above we use a Category to distinguish IPod products.  But, you can do it any number of ways…

Product SKU(s)

                Items.Any( Product.Sku  = "12345" or Product.Sku  = "56789"  )

                Items.Any( "12345, 56789, 55555".Contains(Product.Sku) )

Product Name

                Items.Any( Product.Name.StartsWith("iPod nano") )



----------------------------------------------------------------------------------------------------------------------------------------------------------------

Here's the same for older versions of nopCommerce having Product Variants:

Order

Type

Name

Expression

Fee Expression

Friendly Name Expression

10

Boolean

Only_COD_Allowed

Items.Any( ProductVariant.Product.HasCategory("IPods") )

 

20

Option

Payments.CashOnDelivery

Show

 

30

Option

Payments.AuthorizeNet

![Only_COD_Allowed]

 

(The “!” is the NOT operator)

Above we use a Category to distinguish IPod products.  But, you can do it any number of ways…

Product SKU(s)

                Items.Any( ProductVariant.Sku  = "12345" or ProductVariant.Sku  = "56789"  )

                Items.Any( "12345, 56789, 55555".Contains(ProductVariant.Sku) )

Product Name

                Items.Any( ProductVariant.Product.Name.StartsWith("iPod nano") )

Tags :  PD-Restrict
Comments (1)
The "Test" button- Saturday, March 30, 2013

In evaluation mode, the Director plugins will allow 5 rate calculations from the front end store.   However, you can use the "Test" button in the Director configuration page as many times as you want; it's much easier to test from this page.  I suggest you "Test" as much as possible in the configuration page, and then do a final check when ready in the front end store. 

When you click on the Test button, you are presented with a dialog.  The default "0" means the currently logged in Customer (You, the admin :) .  You can enter a different Customer using Id, Username, or Email:


First, though, you must add items to cart for that user and go thru the checkout process to the point of selecting your shipping address*.  Then return to Director configuration page to test.  You can do this for the currently logged in user (you as admin), or as admin you can also "Impersonate" users and do same.  This allows you to set up many different test cases.

* Required for Shipping Director, for Payment Director, it depends on if you reference the shipping address, or cart items, or order totals in any Expressions.

The results of the test will appear in the upper left portion of the configuration page.   Green check marks are valid Options that the customer would see (rate amounts are not formatted for currency).  Red X's would be Errors (the messages that the customer would see, not the Fatal Errors that get logged in the System > Log).

Test Button Results

Note!  Test calculation results will not take into account any nopCommerce core shipping "adjustments" - such as "Free shipping over X", "Free shipping if all items in cart are marked as Free Shipping", shipping discounts, etc.

Tags :  Testing
Comments (0)
Checkout Attributes in Expressions- Friday, March 29, 2013

In certain scenarios, you may want to look at Checkout Attributes to do some conditional processing.  For example, your shipping carrier might charge extra to ship to a residential address.  You could just add a Price adjustment to the Attribute Value, however there are some drawbacks to that:

1) The Price Adjustment shows up in the sub total area as an itemized item.  You may want it to just be included right in the shipping rate, and/or you may not want your customer to know what the surcharge is.

2) You can't apply it conditionally - e.g. don't want to include it for customers with certain roles.

3) You can't calculate the surcharge value (the price adjustment is fixed)

Older versions of Shipping Director required that you use  XML parsing via SelectSingleNode().  As of version 1.07 Shipping Director has the following built in variables (and Payment Director too):

$CheckoutAttributeValues

$CheckoutAttributeLocalizedValues

These are variables that contain the checkout attributes returned as a String of concatenated name:value pairs (colon separator).  Each pair is terminated with "|".

For our residential address example, we would set up a checkout attribute named "Shipping Address Type" using control type "radio button list", and we would add two Attribute Values: Residential Address and Commercial Address

Then, this could be used in the Option's Surcharge Expression:

   ([$CheckoutAttributeValues].Contains("Shipping Address Type:Residential Address") ? [Fedex Residential Surcharge] : 0)

(The decimal variable [Fedex Residential Surcharge] would be declared beforehand)

Tags :  Attributes
Comments (0)
A Tip for using ErrorExit- Monday, March 11, 2013

You use ErrorExit rather than OptionExit when you want to show an error message to the customer, and not allow them to continue the checkout process.   In nopCommerce 2.50, they introduced a hidden setting:  shippingsettings.returnvalidoptionsifthereareany; the default is 'true' which is to show successful options if any.   The setting was added so that when using multiple external shipping plugins\carriers, and one of the carriers returns with successful shipping methods, that it would still present them to the customer, rather than showing the failed carrier's error message.

If you check all your error conditions up front, then the default setting is OK.  If however, you check for errors in the middle of Option records, then you may want to change the setting to 'false' if using ErrorExit.

If you've set up your records as multiple OptionExit records expecting that the first matching one will be the only shipping method offerred to the customer, you might follow it with a final ErrorExit in case none of the conditions match:

OptionExit  <some condition> ...

OptionExit  <some condition> ...

ErrorExit     true ... "Error Message"

In this case either setting is OK.


Tags :  ErrorExit
Comments (0)
Previous 1 2 3 4 5 Next ... Last