London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!

Visitor group based campaign / promotions [Commerce v. 10.2.3 / CMS v. 10.3.2]

Vote:
 

Hi

I am currently implementing visitor group based campaigns / promotions on our site, but have gotten some odd results from the promotionEngine.

I have a campaign, which is limited to a single visitor group, this campaign has a single entry promotion (BuyQuantityGetItemDiscount). 

Calling the 
_promotionEngine.GetDiscountPrices( new List { variation.ContentLink }, currentMarket, currentMarket.DefaultCurrency, _referenceConverter, _lineItemCalculator);
yields no results.

But calling the 
_promotionEngine.Evaluate(variation.ContentLink, currentMarket, currentMarket.DefaultCurrency, RequestFulfillmentStatus.Fulfilled)
yields the wanted rewardDescription.

When placing the item in a cart (thus calling the cart.ApplyDiscounts(_promotionEngine, new PromotionEngineSettings()); ) the unit price is correctly calculated if and when being in the correct visitor group, but since I need to show the correct (discounted) price for the current user (based on the users visitor group), i need to get the users discounted price for the variation.

/Swensson 

#179150
Jun 01, 2017 11:05
Vote:
 

You can always use the _promotionEngine.Evaluate call and calculate the discount from the RewardDescription.SavedAmount yourself.

The correct discounted price should be the price minus the saved amount, no?

var discountedPrice = price - _promotionEngine.Evaluate().Sum(r=>r.SavedAmount);
#179169
Jun 01, 2017 17:22
Vote:
 

Hi Erik

That seems to work, but this leads me to a new question. 

Is there any way to get the discounted price for a variation for a specific visitor group, without actually being in the group? 

To elaborate, we have a scheduled job that replicates our products to ElasticSearch (for searching). In this scheduled job i need to get a specific visitor groups price, as well as the normal price. 

#179176
Jun 02, 2017 9:22
Vote:
 

I'm sorry Mads, I have nothing but bad news for You.

We have run into the exact same issue, the promotionengine always uses HttpContext.Current when evaluating.

We have a ticket registered with Episerver developer support and they have made a bug for it #COM-4431.

However it is still not visible in the bug list: http://world.episerver.com/support/Bug-list/

So the status is unknown, We do not know when a solution will be forthcoming.

#179192
Jun 02, 2017 14:02
Vote:
 
<p>Bad news indeed, I have marked your previous answer since it answered the original question! :)<br /><br />Thanks for your time!</p>
#179193
Jun 02, 2017 14:09
Vote:
 

Erik Norberg

We have a ticket registered with Episerver developer support and they have made a bug for it #COM-4431.
However it is still not visible in the bug list: http://world.episerver.com/support/Bug-list/
So the status is unknown, We do not know when a solution will be forthcoming.

Good to hear! I created a feature request for something similar but got no response.

A way to pass in a contactId or visitor group to the promotion engine would be awesome.

My request:

http://world.episerver.com/forum/developer-forum/Feature-requests/Thread-Container/2017/5/commerce-enable-promotion-system-to-look-at-purchaseorder-data-when-applying-discounts/

#179208
Edited, Jun 04, 2017 11:44
Vote:
 
<p>Hi Erik and Jafet<br /><br />I have just recieved this from Episerver Developer support today:&nbsp;<br /><br /><span>In case you need a&nbsp;</span>workaround<span>&nbsp;</span><span>for your issue, you can create a&nbsp;</span>custom promotion filter&nbsp;<span>of your own.</span><br /><span>Please follow these steps as below:<br /></span><span></span></p> <ol> <li><span>Create a class&nbsp;</span>CustomCampaignVisitorGroupFilter<span>&nbsp;</span><span>inherited from&nbsp;</span>CampaignVisitorGroupFilter<span>&nbsp;</span><span>(reference to the attach file CustomCampaignVisitorGroupFilter.cs)</span><br /><span></span></li> <li><span>Add this line to the method ConfigureContainer in the SiteInitialization class:&nbsp;<br /></span> <pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">services.AddTransient&lt;CampaignVisitorGroupFilter, CustomCampaignVisitorGroupFilter&gt;();</pre> <br /><br /></li> </ol> <p><span>and done, then you can get&nbsp;the discounted&nbsp;price by the method as below:</span></p> <pre class="brush:html;auto-links:false;toolbar:false" contenteditable="false">GetDiscountedPrice(price, promotionEngine, visitorGroupName) { &nbsp;&nbsp;CustomCampaignVisitorGroupFilter.CurrentVisitorGroupName = visitorGroupName; &nbsp;&nbsp;var discountedPrice = price - promotionEngine.Evaluate().Sum(r=&gt;r.SavedAmount); &nbsp;&nbsp;return discountedPrice; }</pre> <p><br /><br /></p> <pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">using EPiServer.Commerce.Marketing; using System; using System.Collections.Generic; using System.Linq; using System.Web; using EPiServer.Personalization.VisitorGroups; using EPiServer.ServiceLocation; using EPiServer.Core; namespace EPiServer.Reference.Commerce.Site.CustomPromotionFilter { public class CustomCampaignVisitorGroupFilter : CampaignVisitorGroupFilter { public static string CurrentVisitorGroupName; private readonly IContentLoader _contentLoader; private readonly IVisitorGroupRepository _visitorGroupRepository; public CustomCampaignVisitorGroupFilter(ServiceAccessor&lt;HttpContextBase&gt; httpContextAccessor, IVisitorGroupRepository visitorGroupRepository, IVisitorGroupRoleRepository visitorGroupRoleRepository, IContentLoader contentLoader) : base(httpContextAccessor, visitorGroupRepository, visitorGroupRoleRepository, contentLoader) { _contentLoader = contentLoader; _visitorGroupRepository = visitorGroupRepository; } public override PromotionFilterContext Filter(PromotionFilterContext filterContext) { var shouldFilterCampaign = new Dictionary&lt;ContentReference, bool&gt;(); var cachedVisitorGroupLookup = new Dictionary&lt;Guid, bool&gt;(); foreach (var promotion in filterContext.IncludedPromotions) { var campaignLink = promotion.ParentLink.ToReferenceWithoutVersion(); bool shouldFilter; if (!shouldFilterCampaign.TryGetValue(campaignLink, out shouldFilter)) { shouldFilter = ShouldFilter(campaignLink, cachedVisitorGroupLookup, filterContext); shouldFilterCampaign[campaignLink] = shouldFilter; } if (!shouldFilter) { continue; } filterContext.ExcludePromotion( promotion, FulfillmentStatus.VisitorGroupRequired, filterContext.RequestedStatuses.HasFlag(RequestFulfillmentStatus.NotFulfilled)); } return filterContext; } private bool ShouldFilter(ContentReference campaignLink, IDictionary&lt;Guid, bool&gt; cachedVisitorGroupLookup, PromotionFilterContext filterContext) { SalesCampaign campaign; if (!_contentLoader.TryGet(campaignLink, out campaign)) { return true; } if (campaign.VisitorGroups == null || !campaign.VisitorGroups.Any()) { return false; } foreach (var guid in campaign.VisitorGroups) { bool isValidate; if (!cachedVisitorGroupLookup.TryGetValue(guid, out isValidate)) { var visitorGroup = _visitorGroupRepository.Load(guid); if (CurrentVisitorGroupName == null) { isValidate = true; } else { isValidate = String.Equals(visitorGroup.Name, CurrentVisitorGroupName, StringComparison.OrdinalIgnoreCase); } cachedVisitorGroupLookup[guid] = isValidate; } if (isValidate) { filterContext.AddVisitorGroup(campaignLink, guid); return false; } } return true; } } }</pre> <p>I havent tried this out yet, but wanted to share it with you guys!<br /><br />/Swensson<br /><br /></p>
#179584
Jun 15, 2017 15:22
Vote:
 

I am not entirely sure but I automatically repel at the sight of them setting a static property for the current visitor group name, it makes me suspect the risk of some really hairy threading issues.

Getting customer specific prices would mean a lot of calls to evaluate with different values of the visitor group...

If you only have the one visitor group I guess you can get it to work thou.

#179585
Jun 15, 2017 15:44
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.