In Commerce 12, SerializedShipment now implements a new interface: IShipmentCalculatedAmount, which has IsShippingCostUpToDate and IsShippingTaxUpToDate. If a line item in the cart is updated with new quantity, these flags are not reset in our solution, which leads to wrong shipping cost in many cases since the weight increases when you increase quantity. Might this be a bug or is it most probably something in our solution that causes this?
The same goes for changing properties on the IShipment.ShippingAddress. We have to replace the entire object with a new one for the flags to be reset. There is an extension method for IShipmentCalculatedAmount called ResetUpToDateFlags, but it's in internal namespace so I assume we are not supposed to call that method?
That is strange. When you update the lineitem quantity it should reset the flag. Is your lineitem SerializableLineItem, or an implementation that implement ILineItemCalculatedAmount?
Same goes to IShipment.ShippingAddress. It should reset the flag ...
Yes, it must be SerializableLineItem since it's a SerializableCart and we call IOrderGroup.CreateLineItem when it's added the first time.
Where are changes to IShipment.ShippingAddress properties handled? I'm looking around in assemblies but can't figure out how they are reset when you set properties on the IOrderAddress. However, if you set a new address on the shipment, I see that ResetUpToDateFlags is called.
If you are changing the address of a SerializableShipment, this will be called:
if (_shippingAddress != value)
_shippingAddress = value;
// Changing the shipping address will leading to change the sales tax of containing line items.
If you have a test case which can reproduce the issue, we're happy to look into it
Yes, I see that. But what if you change properties on an already existing address on the shipment? I'm trying to figure out what's going on here so I'll get back to you if/when I have a test case.
As you can see it's in set operator, so as long as you change it to a different address, that part should be called
Yes, then at least I know that this is the way to change a shipping adress. In other words, don't change properties on existing shipping address. Instead, create a new one, copy values from existing if necessary, change desired properties and finally set the new shipping address.
Ah yes, I misunderstood. Good point - I will need to think about it...
I had a look at SerializableLineItem and as far as I can see, only IsShippingTaxUpToDate is reset when quantity is changed. The default IShippingCalculator only checks IsShippingCostUpToDate. Or am I missing something here? :)
To be honest I'm not 100% sure here (this is ... complicated), but it seems you are correct. I will discuss with the developers who worked on this. Thanks for bringing this into our attention.
I have checked and found that, our implementation for reduce tax calculation is missing two cases:
We are working on those bugs and I hope it will be fixed in the next Commerce release.
Thanks for the info. Then we'll work around these issues until you release bugfixes.
Hi, Mattias Olsson.
Commerce 12.4.1 has released and fixed for:
Currently, we don't support clear IsShippingCostUpToDate flag when changing property of Address.You must create new Address and assign it to Shipment.Address.We will document or support it.
@cuvu: I upgraded to 12.9.0 but I am still facing the issue where my shipping cost is not being updated if a new line item is added. I see that my shipping calculation method is not being called when I add a new line item.
Note: we are not implementing serialized carts.
@Siddharth: the shipping cost is not automatically updated when you add a new line item. This thread is about it is cached (i.e. not being recalculated) when you add a new line item AND run the calculator again
@Quan Mai: I understand, but doesnt OrderGroup GetShippingSubTotal method use the IsShippingCostUpToDate behind the scenes? And when I add a new line item or change the qty of an existing line item I expect this to be set to false which will trigger a re-calculation of shipping cost.
OK. Can you share how do you add a new lineitem/change quantity. The code I am looking at says that would reset the flag ...
@Quan Mai: Thank you for the quick respose:
Add line item:
lineItem = cart.CreateLineItem(model.Code);
lineItem.Quantity = model.Quantity;
CreateOrGetFirstShipment(cart, orderForm, orderGroupFactory).LineItems.Add(lineItem);
public static IOrderForm CreateOrGetFirstForm(IOrderGroup orderGroup, IOrderGroupFactory orderGroupFactory)
IOrderForm item = orderGroup.Forms.FirstOrDefault<IOrderForm>();
if (item == null)
item = orderGroupFactory.CreateOrderForm(orderGroup);
item.Name = orderGroup.Name;
Update Line Item:
public virtual RedirectToRouteResult UpdateCart(int? quantity, string sku)
var cartService = ServiceLocator.Current.GetInstance<ICartService>();
var cart = cartService.LoadActiveShoppingCart();
var lineItem = cart.GetAllLineItems().FirstOrDefault(x => x.Code == sku);
if (lineItem != null)
if (quantity.Value > 0)
var shipment = cart.GetFirstShipment();
cart.UpdateLineItemQuantity(shipment, lineItem, (decimal)quantity);
Hmm, I can see the bug now - you are working on In memory lineitem and when the item is added/quantity is changed it does not reset the flag. Thanks for letting us know - I will file a bug for this. I think the workaround in this case is to save the cart first.
@Quan Mai: Thank you, also as a work around can I override CalculateShippingSubTotal from DefaultOrderFormCalculator to have my shipping cost calculated or will this slow down performace?
Anything that by pass the cache will have performance implications. However you will have to decide if that outweighes the problem you are solving.
Siddharth Gupta Hi again. To help us fix this bug, can you look into the debugger to see at the point you set the quantity or you add an item to cart, which is the real implemenation type of lineitem, shipment and cart?
@Quan: Hope this is of help to you:
Shipment -> Mediachase.Commerce.Orders.Shipment
Cart -> Mediachase.Commerce.Orders.Cart
Line Item -> Mediachase.Commerce.Orders.LineItem
Cart LineItems -> EPiServer.Commerce.Order.Internal.InMemoryLineItem
https://www.screencast.com/t/qYmM2DRD1H https://www.screencast.com/t/nnpk1XG3Jz https://www.screencast.com/t/5B6vQHF4AFfv https://www.screencast.com/t/MpBE3ylsvHn
I am also attaching the quick watch snippets of each of these for reference. Please let me know if you need something else.