Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Bjarne Fyrstenborg 1280 posts 3990 karma points MVP 7x c-trib
    May 23, 2020 @ 11:37
    Bjarne Fyrstenborg
    0

    Get discounts which are target on a product

    In Vendr you can get active discounts within a store using the following method:

    var discounts = Vendr.Core.Web.Api.VendrApi.Instance.GetActiveDiscounts(store.Id);
    

    However is there a way to get discounts directly giving reward on specific products when using Order Line (with Product) Amount Reward?

    enter image description here

    For this case it doesn't need to look at complex rule, but just if the reward it target specific on the product and the type is a percentage reward.

    On the product page I was able to do something like the following, but is there a better way to handle this?

    var store = Model.GetStore();
    
    var udi = new GuidUdi("document", Model.Key);
    decimal? percentageDiscount = null;
    
    var discounts = Vendr.Core.Web.Api.VendrApi.Instance.GetActiveDiscounts(store.Id);
    discounts = discounts.Where(x => x.Rules.Children.Count == 0 && x.Rewards.Count == 1);
    
    var discountsTargetOnProduct = discounts.FirstOrDefault(x => x.Rewards.Any(r => r.Settings.Any(y => y.Key == "nodeId" && y.Value == udi.ToString())));
    
    if (discountsTargetOnProduct != null)
    {
        var percentageReward = discountsTargetOnProduct.Rewards.FirstOrDefault(x => x.Settings.Any(y => y.Key == "adjustmentType" && y.Value == "Percentage"));
        if (percentageReward != null)
        {
            var pctDiscount = percentageReward.Settings["percentage"];
    
            var attempt = pctDiscount.TryConvertTo<decimal>();
            if (attempt.Success)
            {
                percentageDiscount = attempt.Result;
            }
        }
    }
    

    /Bjarne

  • Bjarne Fyrstenborg 1280 posts 3990 karma points MVP 7x c-trib
    Jul 01, 2020 @ 11:49
    Bjarne Fyrstenborg
    100

    I ended up with an extension method like the following:

    public static decimal? CalculatePercentageDiscount(this IProductComp content)
    {
        var product = content.AsVendrProduct();
        if (product == null)
            return null;
    
        var udi = new GuidUdi("document", content.Key);
    
        // Get active discounts
        var discounts = Vendr.Core.Web.Api.VendrApi.Instance.GetActiveDiscounts(product.StoreId);
    
        // Filter to single rule
        discounts = discounts.Where(x => x.Rules.Children.Count == 1 && x.Type == DiscountType.Automatic);
    
        if (discounts.Any() == false)
            return null;
    
        var productService = Current.Factory.GetInstance<Vendr.Core.Services.IProductService>();
        var ruleProvider = new Vendr.Web.Discounts.Rules.PropertyDiscountRuleProvider();
    
        var kvps = new List<KeyValuePair<string, string>>()
        {
            new KeyValuePair<string, string>("propertySource", "OrderLine"),
            new KeyValuePair<string, string>("propertyAlias", "myOrderProperty"),
            new KeyValuePair<string, string>("comparisonOperator", "NotEqual"),
            new KeyValuePair<string, string>("value", "True")
        };
    
        var discountsTargetOnProduct = discounts.FirstOrDefault(x => x.Rules.Children.Any(r => r.RuleProviderAlias == ruleProvider.Alias && r.Settings.ContainsAll(kvps)));
    
        if (discountsTargetOnProduct != null)
        {
            var contentCache = Current.UmbracoContextAccessor.UmbracoContext.Content;
    
            var awardKvps = new List<KeyValuePair<string, string>>()
            {
                //new KeyValuePair<string, string>("nodeId", udi.ToString()),
                new KeyValuePair<string, string>("adjustmentType", "Percentage")
            };
    
            var productOrderLineAmountDiscountRewardProvider = new Vendr.Web.Discounts.Rewards.ProductOrderLineAmountDiscountRewardProvider(productService);
    
            var percentageReward = discountsTargetOnProduct.Rewards
                .FirstOrDefault(r =>
                {
                    return r.RewardProviderAlias == productOrderLineAmountDiscountRewardProvider.Alias
                    && r.Settings.ContainsAll(awardKvps)
                    && contentCache.GetById(Udi.Parse(r.Settings["nodeId"]))?.IsAncestorOrSelf(content) == true;
                });
    
            if (percentageReward != null)
            {
                var pctDiscount = percentageReward.Settings["percentage"];
    
                if (string.IsNullOrEmpty(pctDiscount))
                    return null;
    
                var attempt = pctDiscount.TryConvertTo<decimal>();
                if (attempt.Success)
                {
                    return attempt.Result;
                }
            }
        }
    
        return null;
    }
    

    In the view I could then use this extension method to get the percentage discount.

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<ProductPage>
    @using Vendr.Core;
    @using Vendr.Core.Api;
    @using Vendr.Core.Models;
    @{
        decimal? percentageDiscount = Model.CalculatePercentageDiscount();
    
        if (percentageDiscount.HasValue)
        {
            <span class="discount d-flex align-self-start align-items-center justify-content-center position-absolute">
                @($"{percentageDiscount.Value}%")
            </span>
        }
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft