Copied to clipboard

Flag this post as spam?

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


  • David Brendel 792 posts 2970 karma points MVP 3x c-trib
    Mar 02, 2021 @ 13:56
    David Brendel
    0

    Dynamic price from API for products

    Hi,

    we are currently evaluating Vendr for a shop implementation. Our more or less single "pain-point" is that Vendr is calculating prices based on the property on the actual product. In our use-case the product price is calculated based on values the customer provides. These values will get send to an API which then returns the price.

    In our case these are two dates, the selected product and some additional information.

    Is it possible to set a fixed price when a product is added to the cart and disable all calculation based on the product node?

    Regards David

  • Nik 1591 posts 7148 karma points MVP 6x c-trib
    Mar 02, 2021 @ 16:12
    Nik
    0

    Hi David,

    I'm pretty sure you can. I think you can create your own ProductCalculator which is responsible for calculating the prices of an order line.

    https://vendr.net/docs/core/1.5.0/key-concepts/calculators/#content

    You might need a "OrderLineCalculator" though

    Cheers

    Nik

  • Matt Brailsford 4123 posts 22194 karma points MVP 9x c-trib
    Mar 02, 2021 @ 18:53
    Matt Brailsford
    101

    Nik is pretty close but the IProductCalculator is only used when you ask a ProductSnapshot to calculate a price, which usually only occurs when you want to display the product price on a product page.

    What you would want to use is an IOrderLineCalculator as this is used for calculating the price on an order line during order calculation, ie, after the item is added to the order.

    There are two approaches you could take here:

    1. Which I think might be what you are thinking, is to do the price calculation externally in your own code, then store the product price on the order line as a property. You could then implement a custom IOrderLineCalculator that in it's CalculateOrderLineUnitPrice you check to see if the order line property is defined, and if it is, return that price for the order line. If not, and assuming you inherit from our base calculator, then you could fallback to the original calculation logic (for order lines where there isn't a defined price).
    2. Rather than storing the price on the order line manually, you store the details that price is based upon and then in the IOrderLineCalculator you put your logic here for getting the price. You could then cache the result (possibly using our PriceFreezer to store the returned unit price).

    The two are essentially the same, it just depends where you want to put your calculation logic.

    Hope this helps

    Matt

  • Nick Hoang 51 posts 180 karma points
    Mar 15, 2023 @ 17:30
    Nick Hoang
    0

    Hi Matt,

    I have the same situation (I'm using Umbraco 8 + Vendr 1.8), the product's price is calling from API but to add a product to the cart, I still need to add a vendr: Price property to my product content type and set a dummy price to my products. Is there any way to avoid the adding dummy price like that? I expect have no price properties if possible.

    Could you give some advices?

    Thanks, Nick

  • Matt Brailsford 4123 posts 22194 karma points MVP 9x c-trib
    Mar 16, 2023 @ 08:53
    Matt Brailsford
    1

    If you didn't want to have a price property on your node, you'd probably need to override the default Product Adapter (https://vendr.net/docs/core/3.0.0/key-concepts/product-adapters/) and change how it return no value for the Price property of the product snapshot.

  • Nick Hoang 51 posts 180 karma points
    Mar 17, 2023 @ 03:01
    Nick Hoang
    0

    Thanks Matt, it works. Here's my code:

    public class ClearanceProductSnapshot : ProductSnapshotBase
    {
        public override Guid StoreId => AppSettings.Instance.VendrStoreId;        
        public override string ProductReference => _snapshot.ProductReference;
        public override string ProductVariantReference => _snapshot.ProductVariantReference;
        public override string Sku => _snapshot.Sku;
        public override string Name => _snapshot.Name;
        public override Guid? TaxClassId => _snapshot.TaxClassId;
        public override IEnumerable<ProductPrice> Prices { get; }
        public override IDictionary<string, string> Properties => _snapshot.Properties;
        public override bool IsGiftCard => _snapshot.IsGiftCard;
        private readonly IProductSnapshot _snapshot;
        public ClearanceProductSnapshot(IProductSnapshot snapshot, IEnumerable<CurrencyReadOnly> currencies)
        {
            _snapshot = snapshot;
            //return dummy numbers for the Prices to get rich of the Vendr:price property on the product node     
            Prices = currencies.Select(e => new ProductPrice(1, e.Id));
        }        
    }
    
    public class ClearanceProductAdapter : UmbracoProductAdapter
    {
        readonly IVendrCustomService _vendrCustomService;
        public ClearanceProductAdapter(IUmbracoContextFactory contentFactory, IContentService contentservice, IVendrCustomService vendrCustomService) : base(contentFactory, contentservice)
        {
            _vendrCustomService = vendrCustomService;
        }
    
        public override IProductSnapshot GetProductSnapshot(string productReference, string languageIsoCode)
        {
            var snapshot = base.GetProductSnapshot(productReference, languageIsoCode);
            if (snapshot != null)
            {                
                var availableCurrencies = _vendrCustomService.GetCurrenciesCached();
                return new ClearanceProductSnapshot(snapshot, availableCurrencies);                
            }
            return base.GetProductSnapshot(productReference, languageIsoCode);
        }
    
        public override IProductSnapshot GetProductSnapshot(string productReference, string productVariantReference, string languageIsoCode)
        {
            var snapshot = base.GetProductSnapshot(productReference, productVariantReference, languageIsoCode);       
            if (snapshot != null)
            {                
                var availableCurrencies = _vendrCustomService.GetCurrenciesCached();
                return new ClearanceProductSnapshot(snapshot, availableCurrencies);                
            }
            return base.GetProductSnapshot(productReference, productVariantReference, languageIsoCode);
        }
    }
    

    Cheers, Nick

  • David Brendel 792 posts 2970 karma points MVP 3x c-trib
    Mar 10, 2021 @ 08:17
    David Brendel
    1

    Hi Matt,

    sorry for the late response, needed some time to test it all out. :)

    We decided to go with the property and custom OrderLineCalculator which works like a charm.

    Setting the property: order.WithOrderLine(orderLine.Id).SetProperty("apiPrice", "15");

    Calculator:

    var apiPriceReturn = orderLine.Properties["apiPrice"].Value;
    if (string.IsNullOrEmpty(apiPriceReturn))
    {
        return base.CalculateOrderLineUnitPrice(order, orderLine, currencyId, taxRate);
    }
    
    var priceDecimal = Convert.ToDecimal(apiPriceReturn);
    
    return Price.Calculate(priceDecimal, taxRate, currencyId);
    

    Thanks for the help!

  • Matt Brailsford 4123 posts 22194 karma points MVP 9x c-trib
    Mar 10, 2021 @ 08:27
    Matt Brailsford
    0

    Fantastic!

    And thanks for sharing your working code. I’m sure that’ll come in real handy for others wishing to do similar 🙌🏻

Please Sign in or register to post replies

Write your reply to:

Draft