Question about 'Cart contains product from category' Campaign Condition

Good day,

Currently we have a free shipping campaign in a specific channel with a condition - Cart contains product from category. We have added a category and its subcategories. The campaign works fine, however, we would like the campaign to work only on the desired category and should not work if we add something outside of the category. I understand that the free shipping campaign is ruled out to work if the order contains any products from the said category (see screenshot).
image
This merely explains why if a product from the declared category is added in the order as well as other items, this will yield a freeshipping.
But is there a way that we can make a freeshipping campaign that only works for the product added in the order with the category in the condition then if another product was added outside of the condition, the campaign is removed after a call to CalculateOrderTotals?

Please advise.

Thanks in advance.

Litium version: 7.6.1

Not by using the default category condition.

You could implement your own doing something like below, where we check if the order rows contain any categories not included in our condition list. It’s a bit naïve, so if a product both is in a category that’s included and one that’s not you would not get the discount.

It re-uses the same panel for configuring the condition.

using Litium.Foundation.Modules.ECommerce;
using Litium.Foundation.Modules.ECommerce.Plugins.Campaigns;
using Litium.Foundation.Modules.ECommerce.Plugins.Campaigns.Conditions;
using Litium.Foundation.Modules.ECommerce.Plugins.Campaigns.ConditionTypes;
using Litium.Foundation.Modules.ExtensionMethods;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Litium.Accelerator.Campaigns
{
    public class ExclusiveCategoryCondition : ProductConditionType
    {
        private const string PATH = "~/Litium/ECommerce/WebUserControls/Conditions/ProductGroupConditionControl.ascx";

        ProductGroupCondition.Data m_data;

        /// <summary>
        ///     Gets the panel path.
        /// </summary>
        /// <value>The panel path.</value>
        public override string PanelPath
        {
            get { return PATH; }
        }

        /// <summary>
        ///     Initializes the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        protected override void Initialize(object data)
        {
            base.Initialize(data);
            m_data = (ProductGroupCondition.Data)data;
        }

        /// <summary>
        ///     Evaluates the specified condition.
        /// </summary>
        /// <param name="conditionArgs">The condition args.</param>
        /// <returns></returns>
        protected override IEnumerable<FilteredOrderRow> Evaluate(ConditionArgs conditionArgs)
        {
            if (m_data.FilterRows)
            {
                return conditionArgs.FilteredOrderRows.Any(product => product.CategorySystemIds.Except(m_data.ProductGroupIDs).Any())
                    ? Enumerable.Empty<FilteredOrderRow>()
                    : conditionArgs.FilteredOrderRows.Where(product => m_data.ProductGroupIDs.Intersect(product.CategorySystemIds).Any());
            }
            else
            {
                return conditionArgs.OrderRows.Any(product => product.CategorySystemIds.Except(m_data.ProductGroupIDs).Any())
                    ? Enumerable.Empty<FilteredOrderRow>()
                    : conditionArgs.OrderRows.Where(product => m_data.ProductGroupIDs.Intersect(product.CategorySystemIds).Any());
            }
        }

        /// <summary>
        ///     Gets the description.
        /// </summary>
        /// <param name="languageID">The language ID.</param>
        /// <returns></returns>
        public override string GetDescription(Guid languageID)
        {
            StringBuilder sb = new StringBuilder();
            if (m_data != null)
            {
                sb.Append(ModuleECommerce.Instance.Strings.GetValue("ProductGroupConditionDescription", languageID, true));
                foreach (Guid item in m_data.ProductGroupIDs)
                {
                    var category = item.GetCategory();
                    if (category != null)
                    {
                        sb.Append(Environment.NewLine);
                        sb.Append(category.GetDisplayName(languageID));
                    }
                }
            }
            else
            {
                sb.Append(base.GetDescription(languageID));
            }
            return sb.ToString();
        }
    }
}
1 Like

Thank you for the response.

I will try this out.

Hello again. Btw how do I get the ConditionArgs? Can I retrieve it via OrderCarrier or via Campaign object?

Thanks in advance!

NVM, I got it to work now. Thanks again :slight_smile:

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.