Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more

Remove variant from Reward.Items if out of stock

Vote:
 

HI!

I would like to rmove a variant from a promotion reward when it goes out of stock but the reward collection is read-only.

I would like to do something liek this:

var promotions = promotionEngine.Service.GetPromotionItemsForCampaign(campaign.ContentLink);
foreach (var promotionData in promotions.Where(p => p.Promotion.IsActive))
{
    if (promotionData.Reward.Items.Contains(new EPiServer.Core.ContentReference(1234)))
    {
        promotionData.Reward.Items.Remove(new EPiServer.Core.ContentReference(1234))
    }
}

Is this doable?

Thanks!

/Kristoffer

#337257
Mar 19, 2025 13:40
Vote:
 

You can, in theory, do something like this

var targetItems = new CatalogItemSelection(promotionItems.Reward.Items.Except(outOfStockItems), promotionItems.Reward.Type, promotionItems.Reward.IncludesSubcategories);
return new PromotionItems(promotionItems.Promotion, promotionItems.Condition, targetItems);

I am not sure what you are using the PromotionItems for so no further comment. but you can (and have to) reconstruct the object 

#337412
Mar 20, 2025 8:25
Vote:
 

Thanks, I would like to remove from the saved content, something like this:

var promotionItems = _promotionProcessor.Service.GetPromotionItems(promotionData);

var clone = (PromotionData) promotionData.CreateWritableClone();
var targetItems = new CatalogItemSelection(promotionItems.Reward.Items.Except(outOfStockItems), 
    promotionItems.Reward.Type, 
    promotionItems.Reward.IncludesSubcategories);

clone.? //TargetItems
_contentRepository.Service.Save(clone);

Is that doable? 

I guess I could use:

clone.ExcludedItems.Add(variantLink);

Which probably is the best, then it will work even if it is a product in the rewards.

#337416
Edited, Mar 20, 2025 10:17
Vote:
 

It seems you have to update promotionData.Condition.Items, but it depends on the actual promotion content type. Condition is a block of type PurchaseQuantity which available on several built in promotions, but not all 

#337417
Mar 20, 2025 10:32
Vote:
 

I could not find Condtion on the PromotionData, but this code actually worked just fine:

var variantLink = _referenceConverter.Service.GetContentLink(lineItem.Code);
if (promotionData.ExcludedCatalogItems == null || !promotionData.ExcludedCatalogItems.Contains(variantLink))
{
    var clone = (PromotionData)promotionData.CreateWritableClone();
    if (clone.ExcludedCatalogItems == null)
    {
        clone.ExcludedCatalogItems = new List<ContentReference>();
    }

    clone.ExcludedCatalogItems.Add(variantLink);
    _contentRepository.Service.Publish(clone, EPiServer.Security.AccessLevel.NoAccess);
}

Even though Items and ExcludedItems will contain the same variant in this case, the result is what I wanted.

/Kristoffer

#337418
Mar 20, 2025 10:55
Vote:
 

You need to cast the PromotionData to specific types that have Condition property - it's not available on the base type.

using ExcludedCatalogItems is a bit hacky as it should be used for things you want to exclude from discount. Like Gift cards etc.

Another approach is to implement IEntryFilter (easiest = inherit from EntryFilter), and filter out out of stock items. That means you won't have to care about updating your promotions dynamically 

#337419
Mar 20, 2025 11:09
Vote:
 

Agree, a bit hacky it is.

Thanks, I think I will solve it on some way from here.

#337420
Mar 20, 2025 12:18
Vote:
 

Hmm, what should I cast it to? Condition seems to be at the PromotionItems and not the PromotionData?

#337422
Mar 20, 2025 12:35
Vote:
 

You need to cast it to BuyQuantityGetFreeItems, BuyQuantityGetOrderDiscount, BuyQuantityGetSelectedItemsDiscount etc. Unfortunately there is no universal interface to cast to. With that said, IEntryFilter is a more general approach 

#337424
Mar 20, 2025 13:07
Vote:
 

Thanks Quan, really appriciated with all the input.

#337425
Mar 20, 2025 13:21
Vote:
 

Implemenation, at this moment:

var buyQuantityGetFreeItems = promotionData as BuyQuantityGetFreeItems;
if (buyQuantityGetFreeItems != null)
{
    var clone = (BuyQuantityGetFreeItems)buyQuantityGetFreeItems.CreateWritableClone();
    clone.Condition.Items.Remove(variantLink);
    _contentRepository.Service.Save(clone, SaveAction.Publish | SaveAction.SkipValidation, EPiServer.Security.AccessLevel.NoAccess);
}

#337426
Mar 20, 2025 13:54
Vote:
 

Implemenation, at this moment:

var buyQuantityGetFreeItems = promotionData as BuyQuantityGetFreeItems;
if (buyQuantityGetFreeItems != null)
{
    var clone = (BuyQuantityGetFreeItems)buyQuantityGetFreeItems.CreateWritableClone();
    clone.Condition.Items.Remove(variantLink);
    _contentRepository.Service.Save(clone, SaveAction.Publish | SaveAction.SkipValidation, EPiServer.Security.AccessLevel.NoAccess);
}

#337427
Mar 20, 2025 13:54
* 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.