Andreas,
Does this thread help?
https://world.episerver.com/forum/developer-forum/Episerver-Commerce/Thread-Container/2017/3/get-promotion-for-a-specific-entry/
If you just want to check if the product has a discounted value, then you can do as
bool hasDiscount = Model.IsAvailable && Model.DiscountedPrice.GetValueOrDefault().Amount < Model.PlacedPrice.Amount;
@model EPiServer.Reference.Commerce.Site.Features.Shared.Models.IProductModel
bool hasDiscount = Model.IsAvailable && Model.DiscountedPrice.GetValueOrDefault().Amount < Model.PlacedPrice.Amount;
The above code sample is from QuickSilver demo site. (_Product.cshtml)
Evaluate is the way to go:
_promotionEngine.Evaluate(variant,market,market.DefaultCurrency,RequestFulfillmentStatus.Fulfilled | RequestFulfillmentStatus.PartiallyFulfilled);
You can also call the Run method directly if you think that might be more effecient, but i doubt it will be noticeable.
Even then it isn't really fast enough to be used on a page load and even less so for a listing, the result needs to be cached, if you already use a search engine for the listing you can call evaluate when doing the indexing and store the result in there. As with all caching don't forget to handle the invalidation.
There are of course more pitfalls as the result from Evaluate will contain promotions you probably aren't interesting in, as a start I would suggest you filter down to LineItem discounts without an code:
_promotionEngine.Evaluate(variant, market, market.DefaultCurrency, RequestFulfillmentStatus.Fulfilled | RequestFulfillmentStatus.PartiallyFulfilled)
.Where(x => x.Promotion.DiscountType == DiscountType.LineItem && string.IsNullOrEmpty(x.Promotion.Coupon.Code)).ToList();
Is there a efficient way to find out if a product/variant is part of a campaign/promotion? For example, lets say I want to know this on a product listing page containing like 20 products.
My best bet would be to use GetPromotionItemsForCampaign(...), but I'm not sure how to use in a efficient way. Probably I want to batch it in some way.
An other suggestion would be to run _promotionEngine.Evaluate(...) and if that returns a partially fulfilled promotion, then maybe I can consider it part of that campaign?