Copied to clipboard

Flag this post as spam?

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


  • David Peck 599 posts 1579 karma points c-trib
    Nov 25, 2020 @ 12:52
    David Peck
    0

    Can't add a Product to an Order where there is no price for the Order currency.

    I note that there is a similar query here.

    I'm trying to add a "Contribution" product to the cart. This product is a bit like a donation, and doesn't really exist. I created it like this:

    internal class ContributionProduct : IProductSnapshot
    {
        public const string ContributionName = "Contribution";
        public const string ContributionSku = "Contrib";
    
        public ContributionProduct(Guid storeId, Guid? taxClassId, ProductPrice price)
        {
            this.StoreId = storeId;
            this.Prices = new[] { price };
            this.TaxClassId = taxClassId;
    
            this.Properties = new Dictionary<string, string>() { { MyConstants.Store.ContributionProductIdentifierPropertyName, bool.TrueString } };
        }
    
        public Guid StoreId { get; }
        public IEnumerable<ProductPrice> Prices { get; }
        public IDictionary<string, string> Properties { get; }
        public bool IsGiftCard => false;
        public string ProductReference => nameof(ContributionProduct);
        public string Sku => ContributionSku;
        public string Name => ContributionName;
        public Guid? TaxClassId { get; }
    
        public static ContributionProduct Create(OrderReadOnly order, decimal contributionValue)
        {
            return new ContributionProduct(order.StoreId, order.TaxClassId, new ProductPrice(contributionValue, order.CurrencyId));
        }
    }
    

    and I add it like this

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult AddContribution(AddContributionDto postModel)
        {
            try
            {
                var store = this.CurrentPage.GetStore();
    
                using (var uow = this._uowProvider.Create())
                {
                    var order = this._sessionManager.GetOrCreateCurrentOrder(store.Id)
                        .AsWritable(uow);
    
                    var contributionProduct = ContributionProduct.Create(order, postModel.ContributionValue);
    
                    var productPrices = contributionProduct.Prices;
                    var currencyPrice = productPrices?.FirstOrDefault(x => x.CurrencyId == order.CurrencyId);
                    if (currencyPrice == null)
                    {
                        Debug.WriteLine($"Can't add a Product to an Order where there is no price for the Order currency.");
                    }
    
                    order.AddProduct(contributionProduct, 1);
    
                    this._orderService.SaveOrder(order);
    
                    uow.Complete();
                }
            }
            catch (ValidationException)
            {
                this.ModelState.AddModelError("productReference", "Failed to add contribution to cart");
    
                return this.CurrentUmbracoPage();
            }
    
            return this.RedirectToCurrentUmbracoPage();
        }
    

    However I'm getting an exception stating "Can't add a Product to an Order where there is no price for the Order currency." at AddProduct(...) and my Debug.WriteLine(...) is never hit.

    I'm a bit lost. Any points appreciated.

  • Matt Brailsford 2889 posts 15083 karma points MVP 7x c-trib
    Nov 25, 2020 @ 13:31
    Matt Brailsford
    100

    Hi David,

    So ProductSnapshots are generally meant to be used in combination with a ProductAdapter (https://vendr.net/docs/core/1-3-0/key-concepts/product-adapters/) and so you are seeing this error because there is a validation rule setup to ensure a price is available for the given currency, but that validation rule uses the product adapter to get the snapshot to validate against, rather than the snapshot that you've passed to AddProduct.

    For custom priced products, how I'd be tempted to approach this is to store the donation amount as a property on the order line against a donation product node with a 0 value price and then use an order line calculator (https://vendr.net/docs/core/1-3-0/key-concepts/calculators/) to detect order lines with that product and for it's CalculateOrderLineUnitPrice method, get the value from the order line property and use that instead of the default value from the product.

    Hope this helps

    Matt

  • David Peck 599 posts 1579 karma points c-trib
    Nov 25, 2020 @ 14:52
    David Peck
    0

    If you say it's the way to go, then I'm sure you're correct. I'll go with that. Cheers.

  • David Peck 599 posts 1579 karma points c-trib
    Nov 25, 2020 @ 14:52
    David Peck
    1

    And thank you for the quick response

  • David Peck 599 posts 1579 karma points c-trib
    Nov 25, 2020 @ 17:52
    David Peck
    0

    FYI: I got this working without needing to have a false product in the content tree. I just created a ProductAdapter which used Umbraco content + my snapshot. This preferable in case an editor decided to remove my contribution product.

    I still needed to use the IOrderLineCalculator and properties though, because the ProductAdapter doesn't have the ability to create snapshots with varying prices (AFAIK).

Please Sign in or register to post replies

Write your reply to:

Draft