Try CreatePercentageReward to achieve this.
return RewardDescription.CreatePercentageReward(
fulfillmentStatus,
redemptions,
promotionData,
promotionData.Percentage,
fulfillmentStatus.GetRewardDescriptionText(localizationService));
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
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)
Mattias, your stack trace does not include the actual exception - only where it occured.
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)
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)));
}
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.
Hi Mattias
how did you get this to work?
i seem to have the same problem you had.
@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.
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
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.