Commerce will always use the default currency code as for the commerce_order_total field instead of trying to use the currency code of the line item it has. Fixing this should provide a good default for shopping sites where it's only possible to add a single product to the cart at once.

Comments

googletorp’s picture

Status: Active » Needs review

I've created a patch for this and committed it to my sandbox

googletorp’s picture

Title: If an order only has a single line item, it should always the that line item's currency code for commerce_order_total. » If an order only has a single line item, it should always use that line item's currency code for commerce_order_total.

Fixing typo in title

googletorp’s picture

I've created a bigger and better patch for this and committed it to my sandbox

rszrama’s picture

Read it over and will give a shot at integrating it first thing in the morning... I'm just too wiped to move on it this evening. I think we need two additional steps before it's ready to commit, though. At a minimum, we'll want to move this logic out of the controller alone into an API function so we can use it in other contexts than saving. Also, I may have read it / the existing code incorrectly, but I think we might want to iterate over the line items once to determine which currency to use and then a second time to actually total all the values. (This might give us an interesting spot to allow the order total currency selection to be pluggable via some sort of hook, though that's not a major priority here at this point.)

rszrama’s picture

Status: Needs review » Fixed
Issue tags: +rcblocker

Ok, I did move this code out into an API function. I also did what I mentioned in #4, front loading the currency selection process and converting line item / component price amounts to the proper currency in the single foreach() loop. Currency selection happens like so:

  1. It initializes to the default currency for the site.
  2. A foreach() on the line items array creates a $currencies array that calculates how many line items use each currency on the order.
  3. If only one currency is on the order, that becomes the currency for the order total.
  4. If there are multiple currencies represented and the site default is one of them, the site default is still used.
  5. If there are multiple currencies represented and the site default is not one of them, the first currency is used. At first I was trying to figure out the most dominant currency, but that seemed unwise. With a predictable determining factor, we leave the door open for modules to reorder line items to achieve a different order total currency.
  6. In any other scenario, the initial value remains.

It may be that we end up adding a hook at the end of the currency selection process allowing other modules to alter this currency before all the calculation happens. I'm happy with it as it is right now - it's dependable and appears to fix a few bugs.

Commit: http://drupalcode.org/project/commerce.git/commitdiff/2c6b598

I also turned up a bug in commerce_price_components_combine() that was allowing price components to be merged with the incorrect currency. I had only been doing currency conversion when merging a component from $price2 into a component already on $price1, but we really want to convert the currency up front whether the component from $price2 matches a component in $price1 or not.

Commit: http://drupalcode.org/project/commerce.git/commitdiff/c081a50

Finally, I realized that the function commerce_line_items_total() became out of date by this fix. I had to add the same currency selection logic to the beginning of that function. It would probably be worthwhile to abstract the currency selection process out to a separate API function that these functions can call, especially if we end up adding a hook in here. Happily making this change got rid of a long standing TODO item in the code here. : )

Commit: http://drupalcode.org/project/commerce.git/commitdiff/cdf6d68c34e9712f57...

rszrama’s picture

Title: If an order only has a single line item, it should always use that line item's currency code for commerce_order_total. » Provide more robust logic to determine the currency of an order's total

Updating the title.

Automatically closed -- issue fixed for 2 weeks with no activity.