Blog

RSS
Product Specific Fixed Rate for Quantity 1 plus Additional Shipping Charge for Quantity > 1- Wednesday, September 10, 2014
This example will allow you to maintain fixed rates at the product level using Admin Comment and also use the Product's Additional Shipping Charge.

Here's the magic formula :)

Items.Where(!String.IsNullOrWhiteSpace(Product.AdminComment)).Sum(Decimal.Parse(Product.AdminComment.SubstringBetween("Shipping:",";")) - Product.AdditionalShippingCharge)

It will parse out a Quantity 1 rate from Admin Comment, but be sure to use the format "Shipping" + ":" + rate + ";" :
      Shipping:nn.nn;
e.g.
       Shipping:12.99;
You can still use the rest of the Admin Comment as needed, either before, or after the Shipping:nn.nn;
You can change the format if you want - e.g.  livraison:nn.nn|   
But then be sure that you adjust the SubstringBetween expression.   (You can also use  Product.AdminComment.ToLower(), if you want to be safer :)

Caveat...

nopCommerce always adds the products' Additional Shipping Charges AFTER it gets the rate from a shipping plugin.  And, thus when you use the TEST button in Shipping Director, it will NOT show any additional charges.  If you use the Estimate Shipping in the public cart, then you will see the added charges.  Note the " - Product.AdditionalShippingCharge"  (minus) in the above expression.  That ensures that the Product.AdditionalShippingCharge does not apply to the first quantity of the product.  However, if you need also do some type of free shipping (e.g. free for domestic, and above per-item rates only for international), then you can't use the Product's Additional Shipping Charge, and must adjust the above scenario to also include the per-one rate as another element in the Admin Comment, and parse it out.

You can download the above configuration that you can then import into Shipping Director.
Tags :  RatePerItem
Comments (0)
Surcharge for Multiple Manufacturers- Sunday, August 31, 2014

A simple concept, with a tricky Count expression :)   We count distinct manufacturers for all the products in the cart.  The base shipping rate is 10.00 (includes up to one manufacturer), and then 3.00 extra surcharge for each manufacturer beyond the first.

Order

Type

Name

Expression

Rate Expression

Surcharge Expression

10

Integer

ManufacturerCount

Items.Select(Product.ProductManufacturers.Any() ? Product.ProductManufacturers.First().Manufacturer.Name : "").Distinct().Count() -1

 

 

20

Decimal

Surcharge

[ManufacturerCount] <= 1 ? 0 : [ManufacturerCount] * 3.00

 

 

100

Option

Shipping

true

10.00

[Surcharge]

Note, that in nopCommerce, Products can have more than one manufacturer, so we only get its first one.  The " -1 " compensates for those products that don't have any manufacturer.  (You can remove that if you want to also count for "the store").  If you want to surcharge even for the first manufacturer, then  change the Surcharge expression to just  [ManufacturerCount] * 3.00

You can download the above configuration that you can then import into Shipping Director.

Tags :  Manufacturer Fee
Comments (2)
Vendor can only ship to certain cities- Sunday, August 17, 2014

In this scenario, our requirement is to prevent shipping certain products to cities that a vendor does not ship to.  In SD, we check if both the shipping address city is not a permitted city and the cart contains an item for Vendor 1.  If this condition occurs, the ErrorExit line will cause the message like "Sorry, vendor1 does not deliver in your city" 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

10

String

Vendor1 Cities

"Boston, Seattle, Las Vegas"

 

20

Boolean

Not a Vendor1 City

![Vendor1 Cities].Contains(ShippingAddress.City)

 

50

ErrorExit

Vendor1 Restriction

Items.Any(Product.VendorId = 1) and [Not a Vendor1 City]

"Sorry, vendor " + Items.First(Product.VendorId = 1).GetVendor().Name + " does not deliver in your city"

60

Option

 

 

 

  Order Line 60 would be whatever Option(s) you would want to offer.  However, if there are multiple items in the cart, the customer may wonder which product is sold by Vendor1 -so, we can let them know with a message like:  "Sorry, HP Pavilion Artist Edition DV2890NR 14.1-inch Laptop is sold by vendor1, whom does not deliver in your city" .  Use this expression instead:

"Sorry, " + Items.First(Product.VendorId = 1).Product.Name + " is sold by " + Items.First(Product.VendorId = 1).GetVendor().Name + ", whom does not deliver in your city"

You can download the above configuration that you can then import into Shipping Director.

Tags :  VendorRestricted
Comments (1)
Payment Director - Pay In Store available only for In-Store Pickup- Wednesday, July 23, 2014

Prior to nopCommerce 3.40,  "In-Store Pickup" was Shipping Method and the customer had to select or enter a shipping address just to be able to get to the Shipping Methods page (or tab in One-Page Checkout).   "In-Store Pickup" has now moved to the Shipping Address page.  You can enable this by checking the '"Pick Up in Store" enabled:' option on the Configuration > Settings > Shipping Settings page.

If you have several payment options including "Pay In Store", you may want to only show "Pay In Store" if the customer selected "In Store Pickup".  Payment Director can handle this:

Order

Type

Name

Expression

Fee Expression

20

Option

Payments.PayInStore

ShippingOptionName = "In-Store Pickup"

 

Be sure to activate all the Payment Methods you want to offer, and then you only need to enter the one conditional Option above.   Any Options not indicated in the Payment Director configuration page will always show unconditionaly.

If you have multiple languages, you can access the Locale Resource String for the In-Store Pickup Shipping Method Name.  (This is also the shipping name you see on the Order).  Use Payment Director's GetLocaleString method:

Order

Type

Name

Expression

Fee Expression

10

String

In-Store Pickup

GetLocaleString("Checkout.PickUpInStore.MethodName")

 

20

Option

Payments.PayInStore

ShippingOptionName = [In-Store Pickup]

 

Additionally, if you want to show a payment method, but have it disabled so that the customer can't select it, Payment Director includes replacements for the Checkout Views that allow you to do that.  They also will let you show replacement text for the Friendly Name.  For example, if you want to still show the "Pay In Store" option, but don't want to the customer to be able to select it, and also for the description, show "(Pay In Store available only for In-Store Pickup)" rather than just "Pay In Store", you can set up a localized resource string for the text, and set up a Condition in the Friendly Name Expression:










  

Order

Type

Name

Expression

Friendly Name Expression

10

String

In-Store Pickup

GetLocaleString("Checkout.PickUpInStore.MethodName")

 

20

String

In-Store Pickup Hint

GetLocaleString("Checkout.InStorePickupHint")

 

30

Boolean

In-Store Pickup Selected

ShippingOptionName = [In-Store Pickup]

 

20

Option

Payments.PayInStore

[In-Store Pickup Selected] ? Show : Disabled

[In-Store Pickup Selected] ? "" : [In-Store Pickup Hint]

You can download the above configuration that you can then import into Payment Director.  You will find the replacement Views in the \Views subfolder in the download .zip file.  (Read the Readme.txt file in the .zip file.)

Tags :  PD-Restrict
Comments (0)
Shipping Director for nopCommerce 3.40 Released- Saturday, July 19, 2014

The SD version is 1.19

Release Notes

Updates for 3.40
Warnings about ShippingDirectorIsActive and OtherShippingRateMethodsAreActive
   Warning: Core 'Free shipping over X' is enabled
   Warning: Actual store shipping will be 0 because ...
       the cart has no items that require shipping
       all products are marked for 'Free shipping'
       the Customer role has free shipping"

Hide test button if SD is not active

Customer extension - HasAttribute  (This accesses the customer shopping attributes, not the customer custom attributes).  E.g.:
    Customer.HasAttribute("DiscountCouponCode","freeshipping")    //compare with InvariantCultureIgnoreCase

Tags :  ReleaseSD
Comments (0)
Payment Director - Various Expressions- Friday, July 18, 2014

Here's a bunch of expressions you can try.  Be sure that you activate any Payment Method that you want to use.  

  1. Boolean $Debug true  - this will log trace messages in the System > Log.  Be sure to remove it (or make inactive) in production.
  2. Check Or Money Order - shows custom localized text
  3. Cash On Delivery - only visible if postal code starts with 888
  4. Manual Credit Card - only visible when an admin is impersonating.  Note the " use POS " hint added to the freindly name
  5. Manual and Authorize.ney - calculate the fee based on selected card
  6. Purchase Order - only visible for specific role
  7. Pay In Store - visible always, but can only be selected if shipping method selected in In-Store Pickup
  8. PayPay - only visible for store # 1 when selected shipping is FedEx

In order to utilize the features to have disabled payment methods, and to change the name of payment methods that the customer sees, replace your checkout views (.cshtml files) with the ones provided in the \Views\Checkout sub folder from the evaluation zip file you downloaded.

Type

Name

Expression

FeeExpression

FriendlyNameExpression

Boolean

$Debug

true

 

 

String

CheckOrMoneyLocalized

GetLocaleString("your.custom.text")

 

 

Option

Payments.CheckMoneyOrder

true

 

[CheckOrMoneyLocalized] + " (test)"

Option

Payments.CashOnDelivery

Customer.ShippingAddress.ZipPostalCode.StartsWith("888")

 

 

Option

Payments.Manual

OriginalCustomerIfImpersonated != null

CreditCardType = null ? 0.00 : CreditCardType = "Visa" ? OrderTotalWithoutPaymentFee * 0.02 : 1.00

FriendlyName + " (use POS)"

Option

Payments.AuthorizeNet

OriginalCustomerIfImpersonated = null

CreditCardType = null ? 0.00 : CreditCardType = "Visa" ? OrderTotalWithoutPaymentFee * 0.02 : 1.00

FriendlyName + " (fee varies)"

Option

Payments.PurchaseOrder

Customer.IsInCustomerRole("Dealer Pricing")

 

 

Option

Payments.PayInStore

ShippingOptionName = "In-Store Pickup" ? Show : Disabled

 

ShippingOptionName = "In-Store Pickup" ? "" : FriendlyName + "(Available only for In-Store Pickup)"

Option

Payments.PayPalStandard

CurrentStoreId = 1 and ShippingOptionName.StartsWith("FedEx")

 

 

You can download the configuration import file by clicking on this link PaymentDirector (Various Expressions).txt

Also, if you're using the Test button in the PD configure page, if any expression uses OrderTotalWithoutPaymentFee, then be sure you've used the public store to put an item in the cart, and if using ShippingOptionName, go through the checkout process just past selecting a shipping method.  (PD will warn you otherwise)

Comments (0)
Evaluate customer's prior orders- Friday, June 20, 2014

The GetOrders() customer extension method has been around since Shipping Director 1.13 (for nopCommerce 3.10), but we've never blogged about it.  Here's a couple of possible scenarios  (you may need to put the expression in different configuration fields depending on your needs).

Example: Prior orders containing 2 or more products from a particular vendor:

  Customer.GetOrders().Count(OrderItems.Any(Product.VendorId = 1)) > 2

Example: 10% discount (by using Surcharge Expression) if any (paid) orders in the last 45 days

    Integer PaymentStatus_Paid 30
    Customer.GetOrders().Any(CreatedOnUtc > DateTime.UtcNow.AddDays(-45) and PaymentStatusId = [PaymentStatus_Paid]) ? -[$Rate]*0.10 : 0

Example: Free Shipping for Add On Order (i.e. there's a prior order that's not yet shipped)

    Integer ShippingStatus_NotYetShipped  20
    OptionExit   Free Shipping for Add On Order    Customer.GetOrders().Any(ShippingStatusId = [ShippingStatus_NotYetShipped])     0

Tags :  Expressions
Comments (0)
Example - Free ground shipping for Coupon Code, but want the customer to still have the option to pick the quicker options from Fedex at the regular price.- Monday, June 16, 2014

You can get the customer entered Coupon Code using:  Customer.GetAttribute("DiscountCouponCode").   In an Option record's surcharge expression, use the built-in [$Name] variable to get the carrier's shipping method name and the built in [$Rate] variable to get the method's rate.  In Surcharge Expression negate the rate if the shipping option name contains the word “Ground”.

Add new 'Shipping Director' record - a variable to get the customer entered coupon code.  Use ' + "." ' at the end because when the customer does not enter a code, then [DiscountCouponCode] will be null, so we need to check that before applying ToLower() below, or easier is just to append the ".". *

Type

String

Name

DiscountCouponCode

Expression

Customer.GetAttribute("DiscountCouponCode") + "."

Add new 'Shipping Director' record - a variable to calculate when free ground.  For example, if the Coupon Code is "freeground." (with "." at the end):

Type

Boolean

Name

FreeGround

Expression

[DiscountCouponCode].ToLower() = "freeground."



Add new 'Shipping Director' record - an Option record to get the rate.  Use a negative surcharge.

Type

Option

Name

FedEx Free ground shipping with Coupon

Expression

true

Rate Expression

Shipping.FedEx

Surcharge Expression

[FreeGround] and [$Name].Contains("Ground") ? -[$Rate] : 0

Name Expression

[FreeGround] and [$Name].Contains("Ground") ? "Free Ground Shipping" : [$Name]

Description Expression

 



If you have many different coupon codes, then give them something common so that you can easily detect them.   For example, if you have codes "ground1", "ground2", etc., then the variable's expression could be [DiscountCouponCode].ToLower().StartsWith("ground").  Or, you could use ... .Contains("ground").   

(*We could have used ' + "" ' (empty string) above rather than ".", but all strings contain and start with the empty string)

(update 7/26/2014:

For 2.65, replace    

   Customer.GetAttribute("DiscountCouponCode")

with just
      Customer.DiscountCouponCode 

Tags :  FreeShipping
Comments (5)
Add a handling charge for a Category- Wednesday, April 2, 2014

If you want to charge a fee when the cart contains any items from a given Category...

Order

Type

Name

Expression

Rate Expression

Surcharge Expression

100

Decimal

SurchargeForX

Items.Any(Product.HasCategory("CategoryX")) ? 20 : 0

 

 

110

Option

Shipping

true

Shipping.Fedex

[SurchargeForX]

The variable for surcharge is calculated using the ternary if-then-else operator “ ? : “.  The Option record’s rate expression can be a fixed amount, or can refer to any shipping rate calculation plugin.

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

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

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

Make these changes to the above:  add line 10 for the total $ calculation and change line 100 to use the total:

Order

Type

Name

Expression

Rate Expression

Surcharge Expression

10

Decimal

TotalForX

Items.Where(Product.HasCategory("CategoryX")) .Sum(GetSubTotalWithDiscounts())

 

 

100

Decimal

SurchargeForX

[TotalForX] < 250 ? 20 : 0

 

 

(There is also GetSubTotalWithoutDiscounts() if you do not want to include any discounts in the total calculation.

Tags :  Surcharge
Comments (0)
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

 

HasCategory(categoryId)

Boolean

 

HasCategoryMatch(categoryNameRegex)

Boolean

 

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

 

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)
Previous 1 2 3 4 5 Next ... Last