Multi-currency support for CiviCRM v2.2.3

Published
2009-05-05 14:28
Written by
The CiviCRM team is planning to hold a UK and Europe developer camp and user meetup in the last week of June 23-27 (if you are interested in attending, please do take this survey.) A couple of months ago, we decided to run CiviCRM on the civicrm.org servers. Eating your own dog food does spur quite a bit of changes and tweaks to make the product a lot more usable :). For the event in the UK, we needed to accept payment in either euros or pounds. However we do not have multi-currency support within CiviEvent :( Once again, Drupal hooks and custom templates to the rescue. I implemented two hooks, the buildForm hook to set the currency in the config object
function civicrm_civicrm_buildForm( $formName,
                                    &$form ) {
    if ( ( ( strpos( $formName, 'CRM_Event_Form_Registration_' ) !== false ) && ( $form->getVar( '_eventId' ) == 1 ) ) ||
         ( ( strpos( $formName, 'CRM_Contribute_Form_Contribution_' ) !== false ) && ( $form->getVar( '_id' ) == 1 ) ) ) {
        civicrm_set_currency( $form );
    }
}
function civicrm_set_currency( &$form ) {
    static $processed = false;
    if ( $processed ) {
        return;
    }
    $processed = true;
    $currency  = CRM_Utils_Request::retrieve( 'currency', 'String', $form, false, 'GBP' );
    $config    =& CRM_Core_Config::singleton( );
    if ( strtoupper( $currency ) == 'EUR' ) {
        $config->defaultCurrency = 'EUR';
    } else {
        $config->defaultCurrency = 'GBP';
    }
    return $config->defaultCurrency;
}
and the buildAmount hook to modify the amount based on the currency chosen
function civicrm_civicrm_buildAmount( $pageType,
                                      &$form,
                                      &$amount ) {
    // only modify the event pages for the UK event                                                                                                                                       
    if ( $form->getVar( '_id' ) == 1 ||
         $form->getVar( '_eventId' ) != 1 ) {
        $currency = civicrm_set_currency( $form );
        // as of may 5th: 1 USD = 0.75 EUR, 1 USD = 0.667 GBP                                                                                                                             
        $ratio = ( $currency == 'EUR' ) ? 0.75 : ( 2.0 / 3.0 );
        foreach ( $amount as $amountID =>& $amountInfo ) {
            $amountInfo['value'] = ceil( $amountInfo['value'] * $ratio );
        }
    }
}
I also needed a way to allow folks to switch to the currency of their choice. I created a custom template for that event and added the following section to the Register.tpl file just above the payment options
{if $config->defaultCurrency eq 'EUR'}
{ts}If you want to pay in pounds, click {/ts}<a href="{crmURL p='civicrm/event/register' q="reset=1&id=`$event.id`¤cy=GBP"}"title="{ts}Pay for Camp in pounds.{/ts}">{ts}here{/ts}</a>
{else}
{ts}If you want to pay in euros, click {/ts}<a href="{crmURL p='civicrm/event/register' q="reset=1&id=`$event.id`¤cy=EUR"}"title="{ts}Pay for Camp in euros.{/ts}">{ts}here\{/ts}</a>
{/if}
Finally i had to go in and make some changes to some of the core files to allow multiple currencies and group together currencies of the same type. I made the required changes to the contribution search and summary screens. I think I've got most of it. Some of the issues filed for this feature are here: Allow hooks to control defaultCurrency Add multi currency support to CiviCRM Participant record does not have a fee_currency field Big tip of the hat to Tom (mrfelton on #civicrm) for his initial thoughts and ideas on how to go about addressing this issue
Filed under

Comments

Anonymous (not verified)
2009-06-08 - 06:59

mrfelton on #civicrm = Tom, not Ken! but thanks all the same!!

Guest (not verified)
2009-09-28 - 10:16

How can I use this information to build an event that works with Euros while the default currency of my site is USD?

Neeraj Saxena (not verified)
2009-10-30 - 03:56

hi did you finish this one or else working