CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Case: dynamically calculate the "Other Amount" field on membership form
Pages: [1]

Author Topic: Case: dynamically calculate the "Other Amount" field on membership form  (Read 883 times)

herb

  • I’m new here
  • *
  • Posts: 27
  • Karma: 2
Case: dynamically calculate the "Other Amount" field on membership form
July 04, 2012, 02:15:19 pm
The client is using Drupal 6 and CiviCRM 3.3.5 (they'll be upgraded to 4.1 soon). They wanted to have the "Other amount" field on their membership form. They also use Paypal Pro. The problem is that they couldn't then send two transactions to Paypal with the same transaction id. Instead CiviCRM requires the total of the donation plus the membership fee to be entered into the Other Amount field. This is a hassle and is confusing. So the client wanted the Other Amount to be updated automatically to include the member fee plus the donation.

In order to accomplish that I implemented a bit of a hack, but clever in my mind. I created a custom field on the contribution to hold the donation amount. Then the Other Amount field can be hidden, it is just used to pass the total to the Confirmation screen.

The calculation is done in javascript but the fee amounts for the membership types are not on the page, instead CiviCRM uses the value attribute on the input field to hold the id of the type. So an ajax call was made to retrieve the membership amount via an CiviCRM api call. I did this by using the Drupal approach of making ajax calls since I was familiar with it. In CiviCRM api v3 it may be possible to make a more direct ajax call with something like this, though I haven't tried it:

Code: [Select]
$().crmAPI ('MembershipType','get',{ 'sequential' :'1', 'id' :'1'}}
  ,{ success:function (data){   
      $.each(data, function(key, value) {// do something });
    }
});

I created a Drupal module called add_donation, including add_donation.module, add_donation.js and add_donation.info. add_donation.module adds the js file to the right form and to use hook_menu to create a callback for the ajax call:

Code: [Select]
<?php
/**
 * @file
 * Calculate an additional donation on membership forms
 */

function add_donation_civicrm_buildForm($fname, &$form) {

  if ( 
$form->getVar( '_id' ) == 1) { // Only include on form #1
    
drupal_add_js(drupal_get_path('module','add_donation') . '/add_donation.js');
  }
}

/**
 * Implements hook_menu()
 *
 */
function add_donation_menu(){
  
$items = array();
$items['memberfee.json'] = array(
  'title' => 'Member fee',
  'type' => MENU_CALLBACK,
  'page callback' => '_memberfee',
  'access arguments' => array('access content'),
);
return $items;
}

/**
 * Callback for memberfee.json
 *
 * @return 
 */
function _memberfee ($memberid){

  
drupal_set_header('Content-Type: text/plain; charset: utf-8');
  
  
civicrm_initialize( true );
  require_once 
'CRM/Core/Config.php';
  
$config =& CRM_Core_Config::singleton( );

  require_once 
'api/v2/Membership.php';
  
$param = array(
                
'id' => $memberid
                
);
 
  
$result= & civicrm_membership_types_get( $param );
  
  if ( 
civicrm_error ( $result )) {
    
printf(drupal_to_js($result));
    
// prints "is_error": 1 or 0
  
} else {
    
printf(drupal_to_js($result[$memberid]));
  }
}


Then I created a file called add_donation.js to do three functions: hide/move fields to improve the UI of the form with the added custom field (custom_30); retrieve the membership fee associated with the membership type; and calculate the total contribution.

Code: [Select]
/*
 * Calculate total contribution based on member fee + donation
 */
Drupal.behaviors.add_donation = function(context) {
 
  // Hide the Make a Donation so it can be set with the calculation
  $('.amount_other-section').hide();
     
  // Move custom field to just below the Other Amount field
  $('.custom_post_profile-group').insertAfter('.amount_other-section');
 
  // Move Donation profile up on confirm page 
  $('#Confirm .custom_post-group').insertAfter('.amount_display-group');

  // Calculate on page load
  Drupal.add_donation.feeCalculate();
   
  // Calculate when membership selected
  $('input[name="selectMembership"]').click(function() {
    Drupal.add_donation.feeCalculate();
  });
 
  // Calculate when amount in custom "Donation Amount" field is changed
  $('input[name="custom_30"]').change(function() {         
    Drupal.add_donation.feeCalculate();
  });
  $('input[name="custom_30"]').keyup(function() {         
    Drupal.add_donation.feeCalculate();
  });
}

/**
 * Helper functions.
 */

Drupal.add_donation = {

  /**
   * Calculate the total contribution
   */
  'feeCalculate': function() {

  var memberId = $('input[name="selectMembership"]:checked').val();
 
  var memberDetails = function(data) {
    result = Drupal.parseJson(data);
   
    if(!result.status || result.status == 0) {
   
      var memberFee;
      var donation = $('input[name="custom_30"]').val();
      var total;
   
      if (typeof parseFloat(donation) == 'number' && donation != null && donation != '') {
        donation = parseFloat(donation);
      } else {
        donation = 0;
      }
      memberFee = parseFloat(result.minimum_fee);
   
      total = memberFee + donation;
   
      //console.log('total',total);

      // Input the total into the Other Amount field
      $('input[name="amount_other"]').val(total);
    }
  }
 
  // Make an ajax call and pass it the membership type Id
  // The result is handled with memberDetails
  $.get('/memberfee.json/' + memberId, memberDetails);

  }
}

add_donation.info is more standard Drupal .info stuff:

Code: [Select]
name = Additional Donation
description = Customizations for calculating an additional donation in CiviCRM.
core = 6.x
version = "6.x-1.0-dev"
package = Custom

dependencies[] = civicrm
« Last Edit: July 04, 2012, 02:51:27 pm by herb@freeform »
Web Developer
Freeform Solutions

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Case: dynamically calculate the "Other Amount" field on membership form

This forum was archived on 2017-11-26.