Excluding Shipping Options for Products
In a recent webinar that I delivered, I was asked how to make a shipping option only available to a particular product / set of products. I thought that was a great question and one that many developers may have. A particular carrier may not allow transporting of a particular type of product so in this blog I will show you how to filter out options based on the product(s) selected.
Overview
In this blog I will be covering how to customize the available shipping options based on configurable criteria. This blog follows the same pattern as the Custom shipping option selection example in the Kentico documentation here. I have modified the criteria to base the filtering on specific products rather than the user’s country.
1. Setting up our shipping option
The first step is to add a field to the shipping option to hold the set of product IDs on which we want to filter our shipping options. This list will allow us to filter out a shipping option from the selection if the user has one of the “excluded” products in their cart. Store administrators will set these products when they define their shipping option in the Store Configuration UI.
The new field will be added to the ShippingOption class in the E-commerce module.
New Field Details
Field name: ShippingOptionExcludedProducts
Field caption: Excluded products
Form control: uni selector
Object type: ecommerce.sku
Return column name: SKUID
Selection mode: Multiple
2. Configuring the excluded products
The next step in the process is to set some products on which to apply the filter. In my example I am going to exclude FedEx if the user is purchasing the AeroPress brewer or filter.
(The idea here is that a specific product in your store is not shippable by a particular carrier.)
3. Adding the logic
The next step is to add the logic to filter our options based on the selection. This is accomplished by creating a CustomShippingOptionInfoProvider class and adding it to our project (App_Code / Old_App_Code folder).
using System.Linq;
using CMS;
using CMS.Ecommerce;
using CMS.Globalization;
using CMS.Helpers;
using System;
using CMS.EventLog;
[assembly: RegisterCustomProvider(typeof(CustomShippingOptionInfoProvider))]
/// <summary>
/// Sample shipping option info provider.
/// </summary>
public class CustomShippingOptionInfoProvider : ShippingOptionInfoProvider
{
/// <summary>
/// Ensures that the shipping option is applicable only if user is not purchasing one fo the excluded products
/// </summary>
/// <param name="cart">Shopping cart data.</param>
/// <param name="shippingOption">Shipping option which is being checked for applicability.</param>
/// <returns>True if the shipping option is allowed to be applied for the current cart items, otherwise returns false.</returns>
protected override bool IsShippingOptionApplicableInternal(ShoppingCartInfo cart, ShippingOptionInfo shippingOption)
{
bool blnOptionAllowed = true;
try
{
// Does not check availability if shopping cart or shipping option object is not available
if ((cart == null) || (shippingOption == null))
{
return true;
}
// Gets data for the ShippingOptionExcludedProducts field
var shippingOptionExcludedProducts = shippingOption.GetValue("ShippingOptionExcludedProducts");
// Does not check availability if no products were permitted
if (shippingOptionExcludedProducts == null)
{
return true;
}
// Parses retrieved data
var excludedProducts = shippingOptionExcludedProducts.ToString().Split(';');
// Loop through the cart to see if it contains any of the selected products.
// If so, do not allow the shipping option
foreach (ShoppingCartItemInfo sci in cart.CartItems)
{
if (excludedProducts.Contains(ValidationHelper.GetString(sci.SKUID, "")))
{
//Set the flag to false so the option is not allowed
blnOptionAllowed = false;
break;
}
}
}
catch(Exception ex)
{
EventLogProvider.LogException("CustomShippingOptionInfoProvider - IsShippingOptionApplicableInternal", "EXCEPTION", ex);
}
return blnOptionAllowed;
}
}
This code is nearly identical to the example except for the last piece. This section of code looks at the user’s cart and determines if it contains any of the excluded products.
// Loop through the cart to see if it contains any of the selected products.
// If so, do not allow the shipping option
foreach (ShoppingCartItemInfo sci in cart.CartItems)
{
if (excludedProducts.Contains(ValidationHelper.GetString(sci.SKUID, "")))
{
//Set the flag to false so the option is not allowed
blnOptionAllowed = false;
break;
}
}
4. Testing the site
Now that all of the pieces are in place, the last step is to test the site. Here I have a general item in my cart.
You can see the FedEx options are available.
Next I will add the AeroPress brewer to the cart.
After adding, we should see the FedEx options filtered out because it will get handled by the custom shipping option info provider.
Wrapping Up
This is a pretty simple modification to a site that you can build on for your projects. Every site has different requirements for when to (and not to) allow certain functionality. Hopefully this blog helps you get your specific requirements handled and your sites working great. Enjoy!
This blog is intended to demonstrate one of many ways to accomplish this task. Always consult the Kentico Documentation for best practices and additional examples.