- Home
- Blogs
- Guy Schneerson's blog
- Drupal 7 commerce multi currency site using a price list
Drupal 7 commerce multi currency site using a price list
Below are my notes taken as I investigate techniques to achieve my Objective,
(This post is not a normalised set of instructions but the process I went through to figure out the best way to handle multiple currencies c objective)
if I get a chance ill create another post with a normalised set of instructions/explanation.
Objective
Create a Drupal 7 commerce site supporting two currencies: GBP (pound sterling) and Euro; both currencies should have a fixed price per product i.e. no automatic currency rate conversion.
I am using the Commerce Kickstart Drupal 7 installation profile.
Add euro price to the commerce product type
Add the Euro currency and add a new price field to the product entity type called field_euro_price.
This doesn’t need to be a price field, infact it can be an integer as we are only interested in the value and commerce price fields store this as a integer, however a price field may be easier to display to the user for editing.
Enter euro prices for your products
Create a new rule with a condition to switch to Euro for non UK languages
The first step was to identify when to switch and the solution “Rules 2”
I created a new “product Pricing rule” called “euro_price”
And added a Custom PHP condition with the following code:
<?php global $language; $lang_name = $language->language ; return ($lang_name != "en";); ?>
I can also check that I actually have the euro price field available using a similar technique to "Adding a Taxonomy Term To Drive Discounts" http://www.drupalcommerce.org/node/461 however I shouldn't have a mixture of pound and euro prices so will have to handle this at a later stage.
First action: Switch to the euro currency symbol
Create an action using the commerce “Set the unit price's currency code” to set the line_item to EUR
Second action (using custom action): Convert the price to the euro value.
As I don’t have access to my field_price_euro I have decided to create a custom action as the first step (see notes about improvements in 'looking forward')
Declared my action in “hook_rules_action_info” with a parameter of type “commerce_line_item”
<?php t('Convert the unit price to the euro currency'), 'parameter' => array( 'line_item' => array('type' => 'commerce_line_item', 'label' => t('Line item'), ), ), 'group' =' t('Commerce Line Item', ); return $actions; } ?>
And in the implementation I get the product_id from the line item (debugged to see how I can access it $line_item->commerce_product['und'][0]['product_id'];
looks a bit messy - must be a better way). Loaded the product using the commerce_product_load() function and retrieved my euro price field
<?php /** * Rules action: convert the unit price to a different currency. */
function mymodule_line_item_unit_price_currency_convert_to_euro($line_item) { $wrapper = entity_metadata_wrapper('commerce_line_item', $line_item); //Load the product and get the euro price $pid = $line_item->commerce_product['und'][0]['product_id']; $prod = commerce_product_load($pid); $wrapper->commerce_unit_price->amount = $prod->field_euro_price['en']['0']['amount']; } ?>
Looking forward Although this worked I have a few problems with the techniques I used and I will be looking at those next
- Do I need to load the entire product? maybe I can use EntityFieldQuery() to load only the euro price.
- Do I need a custom action? I should try and make my euro price available to the line_item using hook_entity_property_info()
- I should make sure I have a euro price, if not I can maybe call the commerce commerce_line_item_unit_price_currency_convert action to dynamically convert it using an exchange rate.
Revised code for Convert the price to the euro value (using standard actions)
This will replace our "second action (using custom action)"
in order to use the commerce "Set the unit price to a specific amount" action we will need to make sure rules knows about our euro price field. for this to happen we need to do two things
- Bring the commerce_product referenced by the line item into scope
- Add metadata to the commerce_product about our euro price field
Once that is done we will be able to set our line item amount to that of the euro field amount using the rules 2 "Data selector"
Bring the commerce_product referenced by the line_item into scope
add a condition:
- "Entity has field" Entity = "line-item", Field value = "commerce_product".
We should also add drill down rules from the product down to the euro amount:
- "Entity has field" Parameter: Entity: [line-item:commerce-product], Field: field_euro_price
- "NOT Data value is empty" Parameter: Data to check: line-item:commerce-product:field-euro-price.
- "NOT Data value is empty" Parameter: Data to check: line-item:commerce-product:field-euro-price:amount.
to get the "NOT" use a "Data value is empty" with the "Negate" check-box ticked.
Add metadata to the commerce_product about our euro price field
the commerce drupal module provides metadata about the commerce_product using the hook hook_entity_property_info().
In order to add our new price field we will need to use the hook_entity_property_info_alter() that will allow us to make changes to the commerce_product.
<?php /** * Implements hook_entity_property_info_alter() * */ function mymodule_entity_property_info_alter(&$info) { // Copy metadata about our euro field from the product bundle to the // commerce_product entity, referenced by the line_item $euro_field = $info['commerce_product']['bundles']['product']['properties']['field_euro_price']; $info['commerce_product']['properties']['field_euro_price'] = $euro_field; } ?>
Update Fri 3 June 2011
After speaking to Ryan, I realised that my new price field was already in scope and did not need the hook_entity_property_info_alter(), its ok to use it if all your product types have the euro field (as is our case) but not essential as the conditions bring the euro field into scope see http://www.drupalcommerce.org/faq/rules-field-data-selection and the Product Pricing Rules (with screencasts) "Adding a Taxonomy Term To Drive Discounts" section
Update Mon 6 June 2011
Attempted to implement my Friday notes and could not get it to work – I am under the impression that bringing addional commerce product fields into scope using Rules 2 only makes them available to the conditions and if you need to use them in actions you will need to use the hook_entity_property_info_alter() technique to let rules know of their existence.
I will try and get confirmation on this or if anyone has an answer please comment.
Contact Details
Blue-Bag Ltd
- info [at] blue-bag.com
- Telephone: 0843 2894522
- Blue-Bag HQ:
The Garage, Manor Farm
Chilcompton, Radstock
Somerset, BA3 4HP, United Kingdom - Telephone: (+44) 01761 411542
- Blue-Bag Brighton:
Unit 35 Level 6 North, New England House
New England Street, Brighton
BN1 4GH United Kingdom - Telephone: (+44) 07944 938204
- VAT GB 748125034
- UK Company Reg: 3932829