When currency for a customer is changed for any reason, the products in order are properly updated, because it will update their new prices via price resolvers \Drupal\commerce_order\OrderRefresh::refresh
. But shipping will not do anything, because it has protection in \Drupal\commerce_shipping\EarlyOrderProcessor::shouldRefresh
.
The problem is that it is not possible to use the ShippingOrderManagerInterface::FORCE_REFRESH
indicator on order, because when an order is loaded, it runs an order refresh on load, which changes the order item prices to a new currency, but the shipping processor will add existing shipments to that order with the previous currency, which leads to an exception.
Drupal\Core\Entity\EntityStorageException: The provided prices have mismatched currencies: 100.00 EUR, 100.00 USD.
It's a kind of race condition: you need to set a force refresh for shipments, because it leads to an exception, but you can't set it because the process runs before you can even do it.
Create a cart with order items and shipping, change currency to a different one, open the cart or anything that will load that order (even the admin page with orders throws an exception).
\Drupal\commerce_shipping\EarlyOrderProcessor::shouldRefresh
should also check for currency mismatch for shipments and order total. If the order total is in a different currency (which it will be at this point), then shipments definitely should be updated.\Drupal\commerce_shipping\EarlyOrderProcessor::shouldRefresh
and this will allow developers to adjust the logic to specific behaviors.Decide how to solve it.
Needs review
2.0
Code