Try our conversational search powered by Generative AI!

Bug: Promotion evaluation of SpendAmountGetItemDiscount gives false positives


Discovered in Commerce v11.6.1

Steps to reproduce:

  1. Create a SpendAmountGetItemDiscount promotion
  2. Configure it to be active now and for all visitor groups without any coupon code
  3. Configure the condition so that the customer have to buy for atleast 200 in your currency
  4. Add a set off Variants X to the reward and give them a 25% discount
  5. Create a new variant Y or edit an existing one that is NOT included in set X
  6. Give the variant Y a price of 195 (Anything between 190 and 199.99 should reproduce this)
  7. Write a test that calls the IPromotionEngine's Evaluate method
  8. pass in a content reference to Y and the market and currency you have setup prices for and RequestFulfillmentStatus.PartiallyFulfilled
  9. The Evaluate method will say that your promotion is partially fulfilled for Y
  10. The wanted behaviour would be no promotion return as Y isn't part of the set X

Variants that costs over 200 will not be returned with RequestFulfillmentStatus.Fulfilled if they aren't part of X so i can't see how the partially fulfilled behaviour would be intentional.

We discovered this because the promotion had a banner image that was applied to all variants with a price >= 190 and <200 on the entire site, but only the variants in x actually got the discount when added to cart so it was very confusing for the customers that tried to get the discount on the other variants not included in x but had the banner since they matched the price range.>

Jan 03, 2018 15:08

We tracked the unwanted behaviour to GetItemDiscountProcessorBase.Evaluate so more promotion types might be affected and not just SpendAmountGetItemDiscount promotions.

Jan 03, 2018 15:16

I might be missing something here, but if I understand you correctly, then the behavior you mentioned is intentional, and actually correct. In this case Y is considered as the "conditions", and because the price is > 190 and < 200, which statisfies the condition for the promotion (total >= 200), the promotion is "almost fullfiled". 

The problem you see is how you treat the RewardDescription returned. It does not say " promotion is partially fulfilled for Y". It says "Y partifully fullfils the promotion". 

Jan 03, 2018 16:47

But by that logic Quan wouldn't any item Y with a price >= 200 be counted as fulfilled but it isn't fulfilled or even partially fulfilled?

How can a better match of the conditions result in a lesser fulfillment completion?

Edited, Jan 04, 2018 14:47

It fulfills/partly fulfills the condition(s), that does not mean it is getting the discount :) 

Edited, Jan 04, 2018 15:01

No it doesn't.

I know that it doesn't get the discount but if it costs more than 200 IPromotionEngine.Evaluate(...., RequestFulfillmentStatus.Fulfilled | RequestFulfillmentStatus.PartiallyFulfilled) will yield an empty result.

So if it costs >=190 and <200 we get FulfillmentStatus.PartiallyFulfilled but if it costs >=200 we get FulfillmentStatus.NotFulfilled. Do you understand my confusion?

Jan 04, 2018 15:05

OK that part I can understand. So if the item is <200 then the status is PartiallyFulfilled (correct), but if it is > 200, then the status is NotFulfilled (incorrect, which should have been Fulfilled), right?

Jan 04, 2018 15:11

I am looking at the code now and I think I understand the problem. The promotion engine uses PromotionApplicator to check if a a promotion can be applied, and if it is (Fulfilled), it tries to apply the promotion, which, in this case, fail, because the item(s) qualify for the condition(s) are not the item receiving the discount.

Interesting. We will look into this. Can you post your test code here so we can use it to verify once we fix the bug? 

Jan 04, 2018 15:17

That is correct according to your logic atleast then I can understand it, our customer wants it the other way around, but that is because they have seen the X set as part of the condition. I fully understand that you can't oblige them there as it wouldn't make for a solution that fits everyone, I will inquire the customer about why they do it like this and see what solution I can give them.

No test code to post im afraid, we have been setting up the scenario in admin mode and just run the evaluate method in the test to reproduce the issue.

We haven't written code for setting up the scenario. :P

Jan 04, 2018 15:35

FYI the customer will try and make their marketers use "Buy Products for Discount on All Selections" instead but they are sceptical as they had limited success with getting the marketing department to follow instructions before (one thing mentioned was difficulty getting them to prioritize entry level discounts higher than order level discounts). embarassed

If you do return Fulfilled even if Y isn't part of X you might want to pair it with NoMoneySaved so it could be filtered out by those who wants to ignore them. Also maybe pair PartiallyFulfilled with NoMoneySaved for clarity.

Jan 04, 2018 16:58

I created bug COM-6195 so we can look into it. Thanks.

Jan 04, 2018 18:04

What are you guys doing in this forum??

"Discuss error messages and Episerver CMS behaviors and features."

You've fallen into the CMS trap!

Jan 04, 2018 20:13

It's a hidden gem. 

I can move this to Commerce forum instead 

Jan 04, 2018 20:49
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.