Applying Multibuy discounts on product options

Yehuda Lando asked on September 29, 2014 20:16

Hi,

In my site we want to enable a customer to register and pay for an event. Each event has different tickets and prices, and also SKU numbers which are important for our CRM. So I used the "main" product as a container for the product options. The main product has a price of 0, and the product options have the full price.

I'm trying to apply buy x get y discount, but to limit them only to certain options. I copied the buy x get y interface elements from the e-commerce module to my own module, and changed the product selection controls to list product options. But after I apply the coupon, I don't get the discount.

Any idea which objects handle applying discounts? I'd like to override or extend them to apply the discount to and according to my product options.

Thanks

Recent Answers


Josef Dvorak answered on December 2, 2014 19:07

Hi Yehuda,

The Buy X Get Y discounts are capable of working with Product variants out of the box. Did you consider using this feature instead of the Product option approach?

The Buy X Get Y applicator is created from a dll class that is not modifiable. In theory you can replace the built-in MultiBuyDiscountsEvaluator class with your own, where you define that the discount should be applied to the specified Product option. It should then be picked up by the built in Applicator. However I have not tested this outside registering a simple evaluator class, so I cannot guarantee your scenario will be possible using this approach.

To do this, create a Custom info provider with an override of the method responsible for Evaluator initialization in MultiBuyDiscountInfoProvider. In this example I am using MultiBuyDiscountsEvaluator as base for the custom class, which may allow you to reuse some of the built-in functionality:

[assembly: RegisterCustomProvider(typeof(CustomMultiBuyDiscountInfoProvider))]

public class CustomMultiBuyDiscountInfoProvider : MultiBuyDiscountInfoProvider
{
    /// <summary>
    /// Returns an instance of MultiBuyDiscountsEvaluator to be used for given shopping cart.
    /// </summary>
    /// <param name="cart">Shopping cart info object to get applicator for.</param>
    protected override MultiBuyDiscountsEvaluator GetMultiBuyDiscountsEvaluatorInternal(ShoppingCartInfo cart)
    {
        return new CustomMultiBuyDiscountsEvaluator(cart.CartProducts);
    }

}

public class CustomMultiBuyDiscountsEvaluator : MultiBuyDiscountsEvaluator
{
    /// <summary>
    /// Creates a new instance of applicator for given cart items.
    /// </summary>
    /// <param name="cartItems">Cart items to be evaluated.</param>
    public CustomMultiBuyDiscountsEvaluator(IEnumerable<ShoppingCartItemInfo> cartItems) : base(cartItems)
    {
    }

}

This way you can try to implement your custom logic based on the API reference. However I would still recommend using the Product variants instead.

0 votesVote for this answer Mark as a Correct answer

Yehuda Lando answered on December 2, 2014 19:13

I found a way around this which solved almost all my problems. First of all, instead of a main product (ie the event), I used a product category.

I did try and want to use the Buy X Get Y discounts (which are great in principal), but there are cases where I want to apply a discount even if the customer bought only 1 product. And in that case the discount does not apply, even if I enter 1 or 0 as the min amount. Which is quite unfortunate. this discount type could fill almost all of my needs.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.