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

New Field
 

Store Configuration UI

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.

Filtered Products 1

Filtered Products 2

(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;
 
[assemblyRegisterCustomProvider(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.

Standard Cart

You can see the FedEx options are available.

FedEx Included

Next I will add the AeroPress brewer to the cart.

Updated Cart

After adding, we should see the FedEx options filtered out because it will get handled by the custom shipping option info provider.

FedEx Excluded

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!

CustomShippingInfoProvder.zip

 

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.

 

Share this article on   LinkedIn

Bryan Soltis

Hello. I am a Technical Evangelist here at Kentico and will be helping the technical community by providing guidance and best practices for all areas of the product. I might also do some karaoke. We'll see how the night goes...

Comments