When configuring a product variant you can select "Free Shipping:". However, there are a few caveats you should know.
1) If ALL the items in the cart are marked Free Shipping, then the shipping charge will be $0 regardless of any shipping method or configuration (country/weight, etc). Even Shipping Director cannot override this, as it is calculated in the core system.
2) Free Shipping is currently not respected by online rate methods (FedEx, UPS, USPS, etc.). It is respected by the offline methods ByTotal, and ByWeight. And, it's also respected by Shipping Director's Packing.
By "respected", I mean that all the product items will be counted in the weight/dimensions. To get an accurate rate, you need to only get a rate based on the weight/dimensions of the non-free-shipping items.
So, a simple setup to use the product variant Free Shipping with an online method looks like this
Type | Name | Expression | Rate Expression |
Packing | Pack ignores items marked FreeShipping | true | Packing.FirstFitSingleBox |
OptionExit | FedEx only sees packed items | true | Shipping.Fedex |
However, the above will (for items that are not free shipping) calculate rates for ALL the shipping methods - Ground, Priority, Standard, etc.
If you want to only offer Free Ground Shipping then it is necessary to first get a rate quote for all items, and then get a rate quote for just the non-free-shipping items for just the Ground method. But, as pointed out above, if ALL items are marked Free Shipping in the product variant, then we always get a $0 rate. So, we can't use the Free Shipping checkbox on the variant. Instead, I recommend using a Category. Set up a "Free Ground Shipping" Category, and mark it as unpublished (i.e. uncheck "Published" check box). If the category is unpublished, you can still put products in the category, but it won't appear in the category navigation tree or elsewhere. (If you need free ground on only a specific variant of a product, then you'll have to use some other mechanism; we won't cover that here.)
To get Ground only rates, we need to exclude certain methods (e.g. Priority, Standard). For that we need to use the Option record type's ability to modify the shipping method Name returned by the offline shipping method; if the Name Expression evaluates to blank (""), then the entire method/rate is excluded. Also, we need to replace the the first Ground rate calculated on all the product items. For that, we use the new OptionReplace type. The "Option" type adds rates to existing same-Name methods, whereas "OptionReplace" will replace the rate.
So, assuming we are not using product variant Free Shipping and instead using Categories, it looks like this - Get rates for all methods, pack only the non-Free Shipping items (by excluding Free-Shipping items), get the rates again but only keep the Ground rate replacing the original Ground rate.
EvalType | Name | Expression | Rate Expression | Name Expression | Description Expression (Exclude) |
Reference | hasFreeGroundShipping | Product.HasCategory("Free Ground Shipping") | | | |
Option | FedEx All Items | true | Shipping.Fedex | | |
Packing | Pack exclude free-ground items | Items.Any([@hasFreeGroundShipping]) | Packing.FirstFitSingleBox | | [@hasFreeGroundShipping] |
OptionReplace | FedEx Ground Only | Items.Any([@hasFreeGroundShipping]) | Shipping.Fedex | [$Name].Contains("Ground") ? [$Name] : "" | |
Don't forget, you can use the $Debug variable as your first record, and this will provide detailed processing messages in the System Log (view source of page for readability).
EvalType | Name | Expression |
Boolean | $Debug | true |
(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 – it had two References rather than one:
EvalType | Name | Expression |
Reference | HasCategory | ProductVariant.Product.ProductCategories.Any |
Reference | hasFreeGroundShipping | [@HasCategory](Category.Name = "Free Ground Shipping") |