Copied to clipboard

Flag this post as spam?

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


  • Tim 6 posts 66 karma points
    Sep 12, 2013 @ 01:33
    Tim
    0

    IShippingCalculator shipping cost update not immediately available

    Hi,

    I have extended the IShippingCalculator to apply some rules for shipping costs and this is working well.

    However: I have a basket page which allows users to update order quantities. When you update the quantities this can result in a change to the shipping calculation. The calculation itself appears to work fine, however the delivery cost is not updated when I re-render the basket. The process I've tried is:

    1. Arrive on basket page with order with a low value that attracts a shipping fee
    2. Update the order quantity so that the shipping is now free and submit
    3. The posted quantity changes are handled in the page's razor scripting and TC.UpdateOrderLine is called.
    4. The basket is then re-rendered, using the order object
    5. The total price and delivery price do not reflect the changes
    6. Refresh the page and all the costs are now fine.

    As a work around I tried doing a response.redirect if the delivery rules have changed the price, but this doesn't help. It seems to only be refreshing that results in the order values being updated.

    Is there anything obvious about this approach that might cause this?

    For what it's worth, here is my current shipping price calculator. The part where I'm saving the order is only a recent addition when trying some things out to see if I could work around the problem.

    Many thanks in advance for any advice.

    Tim

     

        [SuppressDependency("TeaCommerce.Api.PriceCalculators.IShippingCalculator", "TeaCommerce.Api")]
        public class CustomShippingCalculator : ShippingCalculator
        {
            public CustomShippingCalculator(IVatGroupService vatGroupService, ICurrencyService currencyService)
                : base(vatGroupService, currencyService)
            {
            }
            protected override decimal CalculatePrice(ShippingMethod shippingMethod, Currency currency, Order order)
            {
                long countryId = order.ShipmentInformation.CountryId ?? default(long);
                long? countryRegionId = order.ShipmentInformation.CountryRegionId;
                decimal currentShippingPrice = shippingMethod.GetOriginalPrice(currency.Id, countryId, countryRegionId);
                var deliveryThresholdSettings = new Node(1225); //delivery settings node
                var lastAppliedThreshold = -1m;
                foreach (var child in deliveryThresholdSettings.ChildrenAsList)
                {
                    var price = 0m;
                    var basketValue = 0m;
                    if (decimal.TryParse(child.GetProperty("deliveryPrice").Value, out price) && decimal.TryParse(child.GetProperty("basketValue").Value, out basketValue))
                    {
                        if (basketValue > lastAppliedThreshold)
                        {
                            if (basketValue <= order.TotalPrice.Value)
                            {
                               //Log.Add(LogTypes.Notify, 1225, "Found delivery rule, setting price as " + price);
                                currentShippingPrice = price;
                                lastAppliedThreshold = basketValue;
                            }
                        }
                    }
                }
                if (order.ShipmentInformation.TotalPrice.Value != currentShippingPrice)
                {
                    order.ShipmentInformation.TotalPrice = new Price(currentShippingPrice, order.VatRate, currency);
                    order.Save();
                }
                return currentShippingPrice;
            }
        }
  • Anders Burla 2560 posts 8256 karma points
    Sep 12, 2013 @ 13:54
    Anders Burla
    0

    You should not do this coding in a calculator - because it is a calculator that runs and actually changes the total price based on what decimal you return.

    if(order.ShipmentInformation.TotalPrice.Value!= currentShippingPrice)
    {
      order.ShipmentInformation.TotalPrice=newPrice(currentShippingPrice, order.VatRate, currency);
      order.Save();
    }

    But I dont understand your use case. Are you using the starter kit or have you created yor own cart flow? The shipping calculator is executed everytime the order is saved - when adding products, adding order properties etc. So if it calculates correct - then you should properly update your UI using ajax or using the Razor file. BUT that depends on your actual implementation.

    Kind regards
    Ander

  • Tim 6 posts 66 karma points
    Sep 12, 2013 @ 14:32
    Tim
    0

    Hi Ander,

    Thank you for your reply. Yep I should have taken that out - as I mentioned it was something I was testing as I was at a bit of a loss as to why the order value wasn't updated when I went to use it.

    The cart is bespoke. The flow is:

    1. User updates quantities in cart and submits
    2. The cart script (macro / razor) alters the orderlines accordingly using the Update Order Line function.
    3. The cart is re-rendered.
    At the time of re-rendering the order shipping cost has not been updated. If you refresh the page, the shipping cost is right.
    The site is running on a single machine with inproc sessions (if that matters).
    As I mentioned a response redirect does not seem to yield the same result as refreshing the page.
    Here is my razor that's updating the order (Note that whether or not I do order.Save() the results appear to be identical...again I just did it to test):
    if(Request.Form.AllKeys.Any(x=>x.StartsWith("OrderLine_"))) {
            foreach ( OrderLine orderLine in order.OrderLines ) {
                var orderLinePostedQuantity = 0;
                int.TryParse(Request.Form["OrderLine_" + orderLine.Id], out orderLinePostedQuantity);
                if(orderLinePostedQuantity != orderLine.Quantity) {
                    if(orderLinePostedQuantity > 0) {
                        TC.UpdateOrderLine(storeId, orderLine.Id, orderLinePostedQuantity, null, true);
                    } else {    
                        TC.RemoveOrderLine(storeId, orderLine.Id);
                    }
                }
                orderRecordDirty = true;
            }
        }
    
        if(orderRecordDirty) {
            order.Save();
        }
    
    After this the checkout page is re-rendered and the resulting shipping cost has not been recalculated, however, as I mentioned, refreshing the page (with or without the form data) results in the right prices being displayed...
    Any other advice on what I might be doing wrong?
    Many thanks,
    Tim
  • Anders Burla 2560 posts 8256 karma points
    Sep 13, 2013 @ 10:37
    Anders Burla
    0

    Hi Tim

    So the calculation is working - because a refresh shows the new numbers - so Tea Commerce works. Now you need to figure out what about the flow is wrong. It is hard for me to help with this using the forum and just you posting code. If you would want us to help with more in depth supervision for this problem - you need to write us - info (at) teacommerce.net. We will charge an hourly feed for helping solve this problem as it is not a problem with Tea Commerce.

    Kind regards
    Anders

  • Tim 6 posts 66 karma points
    Sep 13, 2013 @ 13:00
    Tim
    0

    Anders,

    Ok thank you for your reply. I will continue debugging and update here if I'm able to find what I'm doing wrong.

    Regards,

    Tim

  • Tim 6 posts 66 karma points
    Sep 16, 2013 @ 23:00
    Tim
    100

    Although I suspect the issues I faced were down to some way I'm doing things in the wrong way for TeaCommerce I was able to work around the issue I was having, so thought I would post my findings here in case it affects anyone else in the future.

    The problem I had meant that after updating the order quantities, the order was being updated, but the prices appeared wrong. This was after overriding both the subtotal calculator and the shipping calculator - so perhaps there's some behaviour I don't know about when overriding them. At any rate, the calculations were called when I updated the order lines, but they were called with the quantities prior to the update - even though the update appeared to be triggering them. Only when refreshing the page would the calculations be triggered again with the correct quantities.

    The way I was able to work around this (as wrong as it may be!) was to add a call to get the order again, then save it. This triggered the calculations again with the right values:

    if(Request.Form.AllKeys.Any(x=>x.StartsWith("OrderLine_"))) {
            foreach ( OrderLine orderLine in order.OrderLines ) {
                var orderLinePostedQuantity = 0;
                int.TryParse(Request.Form["OrderLine_" + orderLine.Id], out orderLinePostedQuantity);
                if(orderLinePostedQuantity != orderLine.Quantity) {
                    if(orderLinePostedQuantity > 0) {
                        TC.UpdateOrderLine(storeId, orderLine.Id, orderLinePostedQuantity, null, true);
                    } else {    
                        TC.RemoveOrderLine(storeId, orderLine.Id);
                    }
                }
                orderRecordDirty = true;
            }
        }
    
        //This works around the quirk in the custom calculators
        if(orderRecordDirty) {
            order = TC.GetCurrentOrder( storeId );
            order.Save();
        }
    

    I wasn't able to trace why this helped / what the true source of my problem was, however this fixed it for me.

    Note that I did experiment with updating the order lines directly via the orderlines collection on the order, but the results were the same.

Please Sign in or register to post replies

Write your reply to:

Draft