allBlogsList

Sitecore Experience Commerce - Filtering Shipping Methods per Country

How to Filter Shipping Methods Based on Selected Country

If you're building a Multi-Country Sitecore Commerce Solution, you will need the ability to filter Fulfillment Methods based on the selected Shipping Address / Country. I am sure there are many ways to implement this feature with Sitecore Commerce. In this blog, I will be sharing a simple solution I implemented recently for one of my clients.

To be able to filter the shipping methods per country, here are the steps you needed to follow:

  1. Extend 'Fulfillment Method' Template with a 'Countries' Multilist Field.
  2. Extend FulfillmentMethod Commerce Entity with a Countries Filter Component.
  3. Replace FilterCartFulfillmentMethodsBlock and FilterCartLineFulfillmentMethodsBlock with a custom implementation to filter methods based on Shipping Country.
  4. Assign appropriate countries to each Fulfillment Method.
  5. Sync Commerce Control Panel using Postman.

Let's now go through each of these steps in more detail:

1- Extend 'Fulfillment Method' Template with a 'Countries' Multilist Field.

Update this template: /sitecore/templates/CommerceConnect/Sitecore Commerce/Commerce Control Panel/Shared Settings/Fulfillment/Fulfillment Method by adding a Countries Multilist Field with Source  /sitecore/Commerce/Commerce Control Panel/Shared Settings/Countries-Regions  as displayed below:

FulfillmentMethodTemplate

2-Extend FulfillmentMethod Commerce Entity with a Countries Filter Component.

 2-A) Create CountriesFilterComponent:

public class CountriesFilterComponent : Component
{
   public List CountryCodes { get; set; } = new List();
} 

 2-B) Override/Replace TranslateItemsToFulfillmentMethodsBlock:

Replace TranslateItemsToFulfillmentMethodsBlock with a custom block, in which you will add the following logic:

if (itemModel.ContainsKey("Countries") && !string.IsNullOrEmpty(itemModel["Countries"] as string))
{
    var countries = itemModel["Countries"].ToString().Split('|');
    var countryCodeList = new List();

    foreach (var countryId in countries)
     {
        var countryItem = await this.Commander.Pipeline().Run(new ItemModelArgument(countryId), context);
        if (countryItem.ContainsKey("Country Code") && !string.IsNullOrWhiteSpace(countryItem["Country Code"] as string))
        {
            countryCodeList.Add(countryItem["Country Code"].ToString().TrimEnd());
        }
     }

     if (countryCodeList.Any())
     {
        var countriesFilterComponent = fulfillmentMethod.GetComponent();
        countriesFilterComponent.CountryCodes = countryCodeList;
     }
} 

3-Replace FilterCartFulfillmentMethodsBlock and FilterCartLineFulfillmentMethodsBlock with a custom implementation to filter methods based on Shipping Country

Replace the blocks mentioned above with Custom ones, and use the following method to filter the IGetFulfillmentMethodsPipeline call result:

public IEnumerable FilterFulfillmentPerCountry(Party party, IEnumerable fulfillmentMethods)
{
   return fulfillmentMethods.Where(f => !f.HasComponent() ||
                                        !f.GetComponent().CountryCodes.Any() ||
                                        f.GetComponent().CountryCodes.Contains(party.CountryCode));
} 

4-Assign appropriate countries to each Fulfillment Method.

 Using Sitecore Content Editor Update Fulfillment methods to assign Specific Countries where applies:

FulfillmentMethodCountries

5-Sync Commerce Control Panel using Postman.

For these changes to apply, you need to sync the Commerce Control Panel using Postman. 

Here's how: https://doc.sitecore.com/developers/90/sitecore-experience-commerce/en/synchronize-content-items.html

And we're all set.

Your Shipping/Fulfillment methods can now be filtered per country.

This solution was implemented and tested on Sitecore Experience Commerce 9.0.2.