Discount is not getting applied to price properties

Vote:
 

Hi,

In a Commerce 11.8.5 project we have a custom FixedPrice promotion.

After orderGRoup.ApplyDiscounts() I can see the applied promo in orderGroup.Promotions, but lineItem.TryGetDiscountValue(d => d.EntryAmount) returns zero.

In short, the processor checks two separate contentRef lists and applies a reward for each pair from the two groups. Problem is that I can see the promotion info on the orderGroup but TryGetDiscountValue always return 0 so the discount isn't reflected in the totals.

Any ideas? I haven't been able to find anything missing regarding price entries, AffectedEntries, redemption descriptions, reward description or orderForm.Promotions.

// for each pair from the two group
                    var entry1 = new PriceEntry(lineItem1.PlacedPrice, 1, lineItem1);
                    var entry2 = new PriceEntry(lineItem2.PlacedPrice, 1, lineItem2);
                    entry1.Promotion = promotionData;
                    entry2.Promotion = promotionData;

                    var priceEntries = new List<PriceEntry>() { entry1, entry2 };
                    var affected = new AffectedEntries(priceEntries);
                    redemptions.Add(CreateRedemptionDescription(affected));

// After going through all pairs, return reward description
return new RewardDescription(fulfillmentStatus, redemptions, promotionData, fixedPrice * fulfilledQuantity, decimal.Zero, RewardType.FixedPrice, "Combo price");
#205187
Edited, Oct 15, 2019 17:55
Vote:
 

Try CreatePercentageReward to achieve this.

return RewardDescription.CreatePercentageReward(
               fulfillmentStatus,
               redemptions,
               promotionData,
               promotionData.Percentage,
               fulfillmentStatus.GetRewardDescriptionText(localizationService));

#205229
Jul 02, 2019 12:53
Vote:
 

I cant use percentage reward since each item will have different percentages. Maybe I wasn't clear enough what I'm trying to do.

What I'm after is that one set (a combo of 1 qty from group A + 1 qty from group B) has a fixed price, for example $15 for both.

The cart could look like this

Group A (sku - price - qty)

1001 - $10 - 2

1004 - $12 - 1

Group B (sku - price - qty)

1002 - $11 - 1

1003 - $13 - 2

And the result should then look like 

1001 + 1002 = $15

1001 + 1003 = $15

1004 + 1003 = $15

#205234
Jul 02, 2019 13:09
Vote:
 

Anyone?

I've created a promotion type now which returns a FixedPrice reward description with the items paired together in one redemption each.

I get the following error which doesnt really make sense to me:

at EPiServer.Commerce.Marketing.OrderFormPriceMatrix.CalculateAndCommit(AffectedEntries item, Func`3 apply)
at EPiServer.Commerce.Marketing.RewardApplicatorBase`1.<>c__DisplayClass1_0.<Apply>b__0(TAffectedObject item)
at EPiServer.Commerce.Marketing.RewardApplicatorBase`1.ForEach(Func`2 apply, IEnumerable`1 affectedItems)
at EPiServer.Commerce.Marketing.RewardApplicatorBase`1.Apply(RewardDescription reward, Int32 remainingRedemptions, PromotionProcessorContext processorContext)
at EPiServer.Commerce.Marketing.PromotionEngine.Run(IOrderGroup orderGroup, PromotionEngineSettings settings)
at EPiServer.Commerce.Order.IOrderGroupExtensions.ApplyDiscounts(IOrderGroup orderGroup, IPromotionEngine promotionEngine, PromotionEngineSettings settings)

#205326
Jul 05, 2019 11:08
Vote:
 

Mattias, your stack trace does not include the actual exception - only where it occured.

#205329
Jul 05, 2019 11:24
Vote:
 

Sorry...

System.NullReferenceException: Object reference not set to an instance of an object.
at EPiServer.Commerce.Marketing.OrderFormPriceMatrix.CalculateAndCommit(AffectedEntries item, Func`3 apply)
at EPiServer.Commerce.Marketing.RewardApplicatorBase`1.<>c__DisplayClass1_0.<Apply>b__0(TAffectedObject item)
at EPiServer.Commerce.Marketing.RewardApplicatorBase`1.ForEach(Func`2 apply, IEnumerable`1 affectedItems)
at EPiServer.Commerce.Marketing.RewardApplicatorBase`1.Apply(RewardDescription reward, Int32 remainingRedemptions, PromotionProcessorContext processorContext)
at EPiServer.Commerce.Marketing.PromotionEngine.Run(IOrderGroup orderGroup, PromotionEngineSettings settings)
at EPiServer.Commerce.Order.IOrderGroupExtensions.ApplyDiscounts(IOrderGroup orderGroup, IPromotionEngine promotionEngine, PromotionEngineSettings settings)
at HiddenCustomer.Commerce.Workflow.Activities.CalculateDiscountsActivity.Execute(ActivityExecutionContext executionContext) in C:\Projects\Backup\HiddenCustomer\HiddenCustomer.Commerce.Workflow.Activities\OrderGroupActivities\CalculateDiscountsActivity.cs:line 32
at Mediachase.Commerce.WorkflowCompatibility.Activity.Execute()
at Mediachase.Commerce.Engine.ActivityFlowRunner.<>c__DisplayClass15_0`1.<Do>b__0()
at Mediachase.Commerce.Engine.ActivityFlowRunner.Execute()
at Mediachase.Commerce.Engine.ExecutionManager.ExecuteActivityFlow(String name, ActivityFlowContext context)

#205330
Jul 05, 2019 11:43
Vote:
 

Well, that doesn't help much ;)

Looking at the decompiled code, at least there's not many lines in that method:

    protected internal Decimal CalculateAndCommit(
      AffectedEntries item,
      Func<IEnumerable<PriceEntry>, Decimal, Decimal> apply)
    {
      IEnumerable<PriceEntry> source = item.DiscountRange();
      Decimal num1 = source.Sum<PriceEntry>((Func<PriceEntry, Decimal>) (pe => pe.ActualTotal));
      Decimal num2 = num1 == Decimal.Zero ? Decimal.Zero : apply(source, num1);
      this.CommitPrices(item);
      return num2;
    }

Maybe this gives you any clue. If not, I would create my own implementation of EntryRewardApplicator and replace the original one in the dependency container. Doing so, you would be able to override ApplyFixedPrice to see what variables that are used.

    protected override Decimal ApplyFixedPrice(
      AffectedEntries item,
      Decimal fixedPrice,
      PromotionProcessorContext processorContext)
    {
      return processorContext.EntryPrices.CalculateAndCommit(item, (Func<IEnumerable<PriceEntry>, Decimal, Decimal>) ((entries, totalAmount) => this._priceCalculator.ApplyFixedPrice(entries, totalAmount, fixedPrice)));
    }
#205332
Jul 05, 2019 12:01
Vote:
 

Thanks for the hint. I tried that and ApplyFixedPrices() do get an AffectedEntries with two price entries which seem to be complete, the fixedPrice is there and also the processorContext.

Hard to know what the processorContext should contain though, for example processorContext.EntryPrices aka the price matrix is empty. Can't see that it's being used in the classes I've decompiled though.

#205363
Jul 09, 2019 0:47
Vote:
 

Hi Mattias

how did you get this to work? 
i seem to have the same problem you had.

#208147
Oct 15, 2019 9:57
Vote:
 

@Stijn,

Since Mattias wrote this, I've also experienced that issue:

System.NullReferenceException: Object reference not set to an instance of an object.
at EPiServer.Commerce.Marketing.OrderFormPriceMatrix.CalculateAndCommit(AffectedEntries item, Func`3 apply)

I found out that the cause was manually using context.EntryPrices.ExtractEntries, probably in the wrong way. The result of the issue, was that the parameter AffectedEntries item became null in the stack trace above.

I also found that I would get the exception not for my custom entry discount, but for another order discount in the cart which was applied at the same time.

So, for some reason - when I extracted entries in my custom entry promotion, it affected another order promotion, and the method OrderRewardApplicator.ExtractPrices (decompile to find) would return null instead of an actual value. Why - probably because Episerver tried to extract more entries than possible. You can try this yourself - if you try context.EntryPrices.ExtractPrices(null, int.MaxValue, promotion), you will get null back, because of the quantity parameter being too large.

Hopefully this gives you some leads.

#208149
Edited, Oct 15, 2019 10:15
Vote:
 

Hi Andreas

I experienced the same issue today. So if what you say above is right, how can we fix it? Any thoughts?

Regards

Ritu

#211448
Jan 08, 2020 20:09
* 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.