Adding conditions to product purchases
30th of April, 2017 0 comments

Adding conditions to product purchases

In a world of digital products, a possible requirement can be to have an "eligibility" criteria for purchasing certain products. A typical scenario could be to limit the availability of a membership product to users who have a particular "flag" on their account, are in a specific role, etc.

Let's look at a way of accomplishing this, with a solution that has a degree of flexibility and reusability.

The approach

The issues we need to tackle are:

  1. Determining if a user is eligible to purchase a product. We will make this easy to apply on any product, having it open for extension to cover any complex scenarios in the future
  2. Limiting the user's actions, to prevent them from purchasing the product if conditions have not been met
  3. Informing the user of the limitation

To keep things simple, we will look at implementing this on a simple "shop" type of website, where users select a product from a list. They will be eligible to purchase a particular product if they are in a specific role named "Special user".

Some elements that will assist us in getting this done are:

  • Additional fields on the SKU class. This will allow us to define the eligibility conditions
  • The "Condition builder" form control. A powerful macro editor, which we can plug in to our previously created field
  • Customised ShoppingCartInfoProvider class. By overriding the right methods, we can check the eligibility criteria of products

SKU setup

Before we start adding new fields, let's configure the "Condition builder" form control to be usable on system fields. Open the "Form controls" application, edit the "Condition builder" form control, and tick "Show control in: System tables". Click the "Save" button to save the changes.

Condition builder form control settings

Let's open the SKU class (Modules > E-commerce > Classes > SKU > Fields), and add new fields.

We will create an "Eligibility" field category, and add the following fields:

Name Data type Form control
EligibilityCondition Long text Condition builder
EligibilityValidationMessage Text (200) Text box

Customising the shopping cart validation method

Following the instructions on customizing info providers , let's add a CustomShoppingCartInfoProvider class in the App_Code folder (or Old_App_Code, for web application projects).

By overriding the CheckShoppingCartInternal method, we can validate our products by checking the result of the macro method from the EligibilityCondition field.

As there are built-in validation methods that we want to keep, we add our validation results to the ShoppingCartCheckResult object returned from the base method.

[assembly: RegisterCustomProvider(typeof(CustomShoppingCartInfoProvider))]
public class CustomShoppingCartInfoProvider : ShoppingCartInfoProvider
    protected override ShoppingCartCheckResult CheckShoppingCartInternal(ShoppingCartInfo cart)
        // The original result of the validation
        var checkResult = base.CheckShoppingCartInternal(cart);
        var resolver = MacroResolver.GetInstance();
        foreach (var item in cart.CartItems)
            var eligibilityCondition = item.SKU.GetStringValue("EligibilityCondition", string.Empty);
            if (string.IsNullOrWhiteSpace(eligibilityCondition))
                // If the 'EligibilityCondition' field is blank,
                // we skip the validation process
            var result = resolver.ResolveMacros(eligibilityCondition);
            if (!string.Equals(result, "true", StringComparison.OrdinalIgnoreCase))
                // By resolving the macro expression from the 'EligibilityCondition' field,
                // we expect a "true" value if validation passes. Otherwise, the validation
                // failed, and we need to prevent the user from proceeding with checkout
                // We retrieve the validation message, which will be shown
                // in the shopping cart
                var eligibilityValidationMessage = item.SKU.GetStringValue("EligibilityValidationMessage", string.Empty);
                checkResult.AddCartItemResult(new ShoppingCartItemCheckResult
                    CartItem = item,
                    OtherErrors = { eligibilityValidationMessage }
        // The method returns the object returned from the base method,
        // with the addition of any other failed validation errors
        return checkResult;

Setting up a product, and testing the validation

Looking at products in the "Products" application, the new condition fields are displayed under the "Eligibility" header.

Product eligibility fields

The macro condition control gives us an intuitive way of defining the criteria to purchase a product. If the criteria has not been met, the message from the "Validation message" is displayed.

Condition builder

Configured eligibility condition

Adding the product to the cart, and visiting the checkout page, we can see the validation in action:

Product validation message

Written by Kristian Bortnik