Copied to clipboard

Flag this post as spam?

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


  • Arne 15 posts 68 karma points
    Nov 16, 2021 @ 19:09
    Arne
    0

    ShippingCalculator - SubtotalPrice is unavailable

    I struggle to get the ShippingCalculator to update the shipping price on the order.

    If I hard code new shipping price, the calculator works, but if shipping price is calculated based on the SubtotalPrice of the order, it does not work.

    The price displayed on the selected shipping option is updated, only orders are not updated.

    It seems that SubtotalPrice is 0 when the calculation is done.

        public override Price CalculateShippingMethodPrice(ShippingMethodReadOnly shippingMethod, Guid currencyId, Guid countryId, Guid? regionId, TaxRate taxRate, ShippingCalculatorContext context)
        {
            decimal ShippingPrice = 0;
    
                    var subtotalExTax = 0m;
                    if (context.OrderCalculation != null)
                    {
                        subtotalExTax = Decimal.Round(context.OrderCalculation.SubtotalPrice.Value.WithoutTax);
                    }
                    else
                    {
                        subtotalExTax = Decimal.Round(context.Order.SubtotalPrice.Value.WithoutTax);
                    }
    
                    ShippingPrice = _productController.calculateDelivery(context.Order.Properties["UserId"], context.Order.Properties["billingZipCode"], subtotalExTax.ToString());
    
            return new Price(ShippingPrice, ShippingPrice * taxRate, currencyId);
        }
    
  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Nov 17, 2021 @ 09:09
    Matt Brailsford
    0

    Hi Arne,

    You need to review the docs here about order calculation state https://vendr.net/docs/core/2.0.0/umbraco-v9/key-concepts/order-calculation-state/

    Basically, whenever you are mid calculation, you need to use the active OrderCalculation object to retrieve prices, rather than the order object. The order object is really a snapshot of the order prior to the calculation commencing (which can be useful for reading properties or previously calculated prices, hence why it's passed). The OrderCalculation though is what holds all active price calculations and then this is applied to the order once the calculation process is complete.

    Hope this helps

    Matt

  • Arne 15 posts 68 karma points
    Nov 17, 2021 @ 09:32
    Arne
    0

    Thank you for your reply.

    As you can see in the code, I am using the OrderCalculation object. I do a null check for the OrderCalculation object and try to retrieve the price if it holds a value. Isn't this the correct way?

                var subtotalExTax = 0m;
                if (context.OrderCalculation != null)
                {
                    subtotalExTax = Decimal.Round(context.OrderCalculation.SubtotalPrice.Value.WithoutTax);
                }
                else
                {
                    subtotalExTax = Decimal.Round(context.Order.SubtotalPrice.Value.WithoutTax);
                }
    
  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Nov 17, 2021 @ 09:41
    Matt Brailsford
    0

    Dang, sorry, I clearly wasn't paying attention. I just saw the second line where you were accessing the order 🤦‍♂️

    So if you debug into that method, does subtotalExTax get a value?

  • Arne 15 posts 68 karma points
    Nov 17, 2021 @ 10:28
    Arne
    101

    The subtotalExTax didnt get a value when using the OrderCalculation object.

    I think I found a solution to the problem now

    It works when i requesting the OrderCalculation .SubtotalPrice.WithoutAdjustments insted of OrderCalculation.SubtotalPrice.Value

    Working code:

    public override Price CalculateShippingMethodPrice(ShippingMethodReadOnly shippingMethod, Guid currencyId, Guid countryId, Guid? regionId, TaxRate taxRate, ShippingCalculatorContext context)
    {
        decimal ShippingPrice = 0;
    
                var subtotalExTax = 0m;
                if (context.OrderCalculation != null)
                {
                    subtotalExTax = Decimal.Round(context.OrderCalculation.SubtotalPrice.WithoutAdjustments.WithoutTax);
                }
                else
                {
                    subtotalExTax = Decimal.Round(context.Order.SubtotalPrice.Value.WithoutTax);
                }
    
                ShippingPrice = _productController.calculateDelivery(context.Order.Properties["UserId"], context.Order.Properties["billingZipCode"], subtotalExTax.ToString());
    
        return new Price(ShippingPrice, ShippingPrice * taxRate, currencyId);
    }
    
  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Nov 17, 2021 @ 10:45
    Matt Brailsford
    0

    Hi Arne,

    Yea, this was probably going to be my next suggestion to experiment with.

    Ultimately, the calculation goes through a series of "loops", first creating the initial price without adjustments, then calculating the adjustments and then adding them all together. Thinking about it, the shipping calculator is probably called within that first "without adjustments" loop so you're right that the total won't have been calculated yet so what you have is spot on.

    Glad you were able to get it working 👍

    Matt

  • Arne 15 posts 68 karma points
    Nov 17, 2021 @ 11:33
    Arne
    0

    Thanks for helping me out 👍

Please Sign in or register to post replies

Write your reply to:

Draft