Technology in Education

  • Home
  • CES Blog
  • Technology at CES

Customize Syncing Between Drupal Commerce and Salesforce – Part 2

March 9, 2016 by Travis Johnston

So in the last article, Customize Syncing Between Drupal Commerce and Salesforce – Part 1, we covered the initial checks to make sure we were targeting the right entities and also making sure they contain the right values before moving forward with our syncing to Salesforce. Now we can focus on the actual syncing with Salesforce.

Registrations synced with Contacts

Our first step is to check to see if each registrant entered is new or if they already exist as a Contact in Salesforce. We found that matching based on email alone wasn’t enough, since some people share email accounts within their household or organization, so we want to check if the person exists based on email + first name + last name.

function MYMODULE_SALESFORCE_registration_contact_push($entity) {  
  
  	global $attendee;
	
	// Clean possible special characters
	$address = addslashes($entity->field_event_user_address['und'][0]['value']);
	$firstName = addslashes($entity->field_first_name['und'][0]['value']);
	$lastName = addslashes($entity->field_last_name['und'][0]['value']);
	
        // Query Salesforce	
	$sfapi = salesforce_get_api();	
	$query = new SalesforceSelectQuery('Contact');
	$query->fields = array('Email', 'FirstName', 'LastName', 'Id');
	$query->addCondition('Email', "'" . $entity->anon_mail . "'");
	$query->addCondition('FirstName', "'" . $firstName . "'" );
	$query->addCondition('LastName', "'" . $lastName . "'");
	$result = $sfapi->query($query);  
	//If we find the record, update some of the Contact fields
	if ($result['records']) {
		foreach ($result['records'] as $record) {
		  try {
			  $sfapi->objectUpdate('Contact', $record['Id'], array(
				  'MailingStreet' => $address,
				  'Address_Line_2__c' => $field_event_user_address_line_2,
				  'MailingCity' => $entity->field_user_city['und'][0]['value'],
				  'MailingState' => $entity->field_user_state['und'][0]['value'],
				  'MailingPostalCode' => $entity->field_user_zip_code['und'][0]['value'],
				  'Phone' => $entity->field_phone_number['und'][0]['value'],
			  ));
			  $attendee = $record['Id'];
			  watchdog('debug', '' . $firstName . ' ' . $lastName . ' already exists and has been synced to Contact #'. $attendee . '.');
		  } catch(SalesforceException $e) {
			  watchdog_exception('salesforce_push', $e);
			  salesforce_set_message(t('Error updating Contact in Salesforce with record ' . $attendee . '. Error message: "@msg".', array('@msg' => $e->getMessage(),)), 'error');
		  }
	     }
	}
	//If we don't find a record, make a new Contact
	else {
	  try {
		  $newContact = $sfapi->objectCreate('Contact', array(
			  'Email' => $entity->anon_mail,
			  'FirstName' => $firstName,
			  'LastName' => $lastName,
			  'MailingStreet' => $entity->field_event_user_address['und'][0]['value'],
			  'Address_Line_2__c' => $field_event_user_address_line_2,
			  'MailingCity' => $entity->field_user_city['und'][0]['value'],
			  'MailingState' => $entity->field_user_state['und'][0]['value'],
			  'MailingPostalCode' => $entity->field_user_zip_code['und'][0]['value'],
			  'Phone' => $entity->field_phone_number['und'][0]['value'],	  
		  ));
		  $attendee = $newContact["id"];
		  watchdog('debug', '' . $firstName. ' ' . $lastName . ' is new and has been synced to Contact #'. $attendee . ' for Order #' . $orderSFID . '.');
	  } catch(SalesforceException $e) {
             watchdog_exception('salesforce_push', $e);
             salesforce_set_message(t('Error creating new Contact in Salesforce. Error message: "@msg".', array('@msg' => $e->getMessage(),)), 'error');
          }
     }
}

Ok let’s break down what’s happening since we will be following the same logic for the other Drupal entities to Salesforce objects.

The first thing we do is setup a global $attendee variable to contain the returned Salesforce ID which we pass back to our initial calling function.

global $attendee;

Next we need to clean up and replaces special characters for the query. I added this because I was hitting Salesforce exception errors for people that have apostrophes in their name.

// Clean possible special characters
$address = addslashes($entity->field_event_user_address['und'][0]['value']);
$firstName = addslashes($entity->field_first_name['und'][0]['value']);
$lastName = addslashes($entity->field_last_name['und'][0]['value'])

Next we run our query, which follows the same technique we used in Part 1 for looking up the Price Book Entry.

// Query Salesforce	
$sfapi = salesforce_get_api();	
$query = new SalesforceSelectQuery('Contact');
$query->fields = array('Email', 'FirstName', 'LastName', 'Id');
$query->addCondition('Email', "'" . $entity->anon_mail . "'");
$query->addCondition('FirstName', "'" . $firstName . "'" );
$query->addCondition('LastName', "'" . $lastName . "'");
$result = $sfapi->query($query);

This query looks for the Contact object and adds a condition for 3 fields – Email, FirstName, and LastName. We include Id so we can assign it later to $attendee if a Contact already existed.

Next we look to see if there were any returned results, which we wrap in a try/catch to catch any exceptions that occur. If a record exists, we update the record with some of the fields we have in our registration object. The field mapping works like this, “Salesforce Field” => “Drupal Field”.

//If we find the record, update some of the Contact fields
if ($result['records']) {
	foreach ($result['records'] as $record) {
	  try {
		  $sfapi->objectUpdate('Contact', $record['Id'], array(
			  'MailingStreet' => $address,
			  'Address_Line_2__c' => $field_event_user_address_line_2,
			  'MailingCity' => $entity->field_user_city['und'][0]['value'],
			  'MailingState' => $entity->field_user_state['und'][0]['value'],
			  'MailingPostalCode' => $entity->field_user_zip_code['und'][0]['value'],
			  'Phone' => $entity->field_phone_number['und'][0]['value'],
		  ));
		  $attendee = $record['Id'];
		  watchdog('debug', '' . $firstName . ' ' . $lastName . ' already exists and has been synced to Contact #'. $attendee . '.');
	  } catch(SalesforceException $e) {
		  watchdog_exception('salesforce_push', $e);
		  salesforce_set_message(t('Error updating Contact in Salesforce with record ' . $attendee . '. Error message: "@msg".', array('@msg' => $e->getMessage(),)), 'error');
	  }
     }
}

In the above, we loop through the returned results and use the objectUpdate method to update the Contact, which uses the found ID to identify which record you are updating. After assigning the Salesforce fields with the Drupal fields we assign the found ID to the $attendee and log a message in watchdog that states the person that was synced to a specific Salesforce ID.

Though if we do not find a record, we can run the following to create a new Contact.

else {
  try {
	  $newContact = $sfapi->objectCreate('Contact', array(
		'Email' => $entity->anon_mail,
		'FirstName' => $firstName,
		'LastName' => $lastName,
		'MailingStreet' => $entity->field_event_user_address['und'][0]['value'],
		'Address_Line_2__c' => $field_event_user_address_line_2,
		'MailingCity' => $entity->field_user_city['und'][0]['value'],
		'MailingState' => $entity->field_user_state['und'][0]['value'],
		'MailingPostalCode' => $entity->field_user_zip_code['und'][0]['value'],
		'Phone' => $entity->field_phone_number['und'][0]['value'],	  
	  ));
	  $attendee = $newContact["id"];
	  watchdog('debug', '' . $firstName. ' ' . $lastName . ' is new and has been synced to Contact #'. $attendee . ' for Order #' . $orderSFID . '.');
  } catch(SalesforceException $e) {
          watchdog_exception('salesforce_push', $e);
          salesforce_set_message(t('Error creating new Contact in Salesforce. Error message: "@msg".', array('@msg' => $e->getMessage(),)), 'error');
  }
}

The code is almost all the same, only difference is we use the objectCreate method, and assign the Salesforce fields with the Drupal fields.

For the remaining Salesforce functions

The top code can be reproduced for the MYMODULE_SALESFORCE_organization_push, MYMODULE_SALESFORCE_order_push, and MYMODULE_SALESFORCE_line_item_push functions which you would only need to change the object you are querying, add in any conditions that apply to you, and modify the fields you are updating or inserting – each time passing back the Salesforce ID so you can move on to the next step in the sync.

Filed Under: Drupal, Salesforce, Web Tagged With: Custom Drupal Modules, Drupal, PHP, Salesforce

Like what you're reading? Share it.

Share this:

  • Facebook
  • Twitter
  • Email
  • Print
  • More
  • Tumblr
  • LinkedIn
  • Reddit
  • Pocket

Welcome to the Technology in Education Blog

Join the conversation about technology, teaching and learning.

Subscribe by Email


Follow us on Twitter

My Tweets

Categories

  • Assistive Tech (2)
  • Digital Citizenship (2)
    • Digital Literacy (1)
  • EdTech Review (6)
  • Events (2)
  • GAFE (5)
  • Google Apps (7)
  • In the Classroom (1)
  • Monthly Challenge (1)
  • Monthly Theme (1)
  • News (21)
  • Policy and Standards (1)
  • Product (2)
  • Social Media (1)
  • TiE (6)
  • Web (8)
    • Drupal (2)
    • Salesforce (2)

Archives

Quick Links

Technology Services at CES

Search Technology Professional Development Workshops

Follow me on Twitter

My Tweets

Copyright 2023 Collaborative for Educational Services · All Rights Reserved