Currently the CommerceShippingMethod plugin takes the shipping amount and fixed currency to calculate shipping rates. This is fine for a single currency site. But site with multiple currencies will have a incompatible currency shipping rate currency.

This is one blocker for commerce_multicurrency, which breaks the flow. This is the related issue : https://www.drupal.org/node/2916211

Proposed solution:

1. Get the amount and convert into the resolved currency and return. below is one example for flat rate. $shipment has the order reference which can be used to get resolved final currency. Problem is taht how do we achieve this? since functionality depends on external multicurrency module.

  /**
   * {@inheritdoc}
   */
  public function calculateRates(ShipmentInterface $shipment) {
    // Rate IDs aren't used in a flat rate scenario because there's always a
    // single rate per plugin, and there's no support for purchasing rates.
    $rate_id = 0;
    $amount = $this->configuration['rate_amount'];
    $amount = new Price($amount['number'], $amount['currency_code']);
    $rates = [];
    $rates[] = new ShippingRate($rate_id, $this->services['default'], $amount);

    return $rates;
  }

2. Provide all the rates for all the different currencies in plugin itself. problem is, what happens if new currency is added and value is not set?? or only calculate if corresponding currency in plugin is set which matches with the order currency.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sumanthkumarc created an issue. See original summary.

Lukas von Blarer’s picture

Status: Active » Needs review
FileSize
1.52 KB

I tried to use ChainPriceResolver::resolve to get the correct price, but I didn't understand what the correct parameters are for this method.

I came up with a temporary solution which gets the order total and uses that currency code to convert the prices.

What is the correct solution for this?

sumanthkumarc’s picture

Status: Needs review » Needs work

Since no rate is passed, This patch makes say 1$ == 1 INR but in reality actual exchange rate is (1$ ~= 65 INR).

Lukas von Blarer’s picture

Ok, how do we solve this? Since exchange rates are not part of commerce core, how is this supposed to be handled?

Lukas von Blarer’s picture

I just realized that this only works before the adjustment is added to the order. Switching the currency aftwerwards still throws this error:

Drupal\commerce_price\Exception\CurrencyMismatchException: in Drupal\commerce_price\Price->assertSameCurrency() (line 279 of /var/www/drupal/public_html/web/modules/contrib/commerce/modules/price/src/Price.php).

Lukas von Blarer’s picture

Can anyone chime in on this?

valic’s picture

Hi, I am maintainer of commerce_currency_resolver module.

Without contrib module it's not possible to make changes regarding exchange.
I wish to add full support for shipping in the mentioned module.

Just thinking where is best to start. Maybe to extend shipment type in the commerce_currency_resolver module?
Better then making dependancy or checks in shipping module if a user has the multicurrency module?

It will not solve the general problem, but it will give people the option to use multicurrency with shipping.

On other hand, you can calculate prices like this (but dependency on the module is needed probably)

$amount = new Price ('100', 'USD')
$getResolver = \Drupal::service('commerce_currency_resolver.current_currency');
$currentCurrency = $getResolver->getCurrency();
$calculated = CurrencyHelper::priceConversion($amount, $currentCurrency);
valic’s picture

If you are still pursuing a solution, have added support for commerce_shipping in commerce_currency_resolver module (dev branch still)

Lukas von Blarer’s picture

@valic Thank you for the comment making me aware of your module! I am still getting the error. I commented on your existing issue regarding commerce_shipping: #2917737: Shipping should take resolved price currency into account while calculating shipping rates

bmcclure’s picture

Just a note that I am using commerce_currency_resolver, and I've been getting this error ever since I enabled commerce_shipping, it seems to be the same error that is in this commerce_currency_switcher issue: https://www.drupal.org/project/commerce_currency_switcher/issues/2916211

creatile’s picture

Is anyone has found a solution ? I have tested patch #2 but the price is not well calculated. 1€ = 1$

valic’s picture

@creatile, which version of resolver are you using? It is the latest, please import exchange rates (commerce_exchanger).

There is a case where we should throw an exception, not handling it gracefully as now, it leads to bad logic.
If exchange rates are not imported, or there is not value, it fallbacks to 1 (which is bad)

bojanz’s picture

1) Beta8 has a SHIPPING_RATES event which allows altering the calculated rates, and performing currency conversion. I have opened #3111998: Rework the shipping integration in commerce_currency_resolver to track its adoption.

2) #2934142: Shipping method entity does not support translations will allow each translation to have its own rate amount, which might be enough for some sites (which have 1 currency per language).

3) We can't perform currency conversion ourselves cause we don't have the exchange rates. And we can't ask for an amount per currency without breaking backwards compatibility, that would need to be done in different plugins (probably provided by a contrib).

I think that the only remaining thing that we can do is filter out rates with a non-matching currency, either in ShipmentManager after the event is fired, or in ShippingRateWidget. That would avoid the crash in question.