I’m building an online request system–it’s basically forms that do what web-to-case does, but without the web-to-case.
One thing I wanted for my system was a way to create Contact records for people submitting Cases if I haven’t seen them before, and use their existing Contact record if I have seen them before. I talked a bunch with Kathy Dunne and even got a look at some code she deployed for a client.
My needs were a bit different, so I thought I’d post the code. In short, this is what it does:
- The trigger doesn’t fire on bulk loads, like data loader loads
- On Case creation, the trigger fires and checks to see if the case came from the web
- It looks for a Contact with the same email as was provided on the Case, if it finds it, the Case is then related to that Contact and that Contact’s Account.
- If a Contact match wasn’t found, it tries to match the Account Name with the Supplied Organization Name. If a match is found, the Contact is created in that Account, and the Case is related to the Account and the new Contact.
Here is the Case Trigger, it breaks the page, but better to see the white space than have the page look nice:
// Written by Steve Andersen, copyright (c) 2008 ONE/Northwest
// This program is released under the GNU General Public License. http://www.gnu.org/licenses/
trigger ONEN_CreateContactFromCase on Case (before insert) {
//only fire when the batch size is one. Should only be relevant when a case is created from the website
if (trigger.new.size() == 1) {
//process the created lead
for (Case createdCase : Trigger.New) {
//variable to hold the New Account Id
Id newAccountId;
//if an email is given, process the Contact info
if(createdCase.SuppliedEmail!=null) {
//look for a Contact that matches the email address
Contact[] contactsMatched = [Select Id,AccountId,email from Contact where email =:createdCase.SuppliedEmail LIMIT 1];
//if we found a match, use it
if (contactsMatched.size()>0) {
createdCase.ContactId = contactsMatched[0].Id;
createdCase.ContactId = contactsMatched[0].AccountId;
} else {
//if the Company name was supplied, match it or create a new one
if (createdCase.SuppliedCompany!=null) {
Account[] accountsMatched = [Select Id from Account where Name =:createdCase.SuppliedCompany LIMIT 1];
//if a match was found, use it
if (accountsMatched.size()>0) {
newAccountId= accountsMatched[0].Id;
createdCase.AccountId= newAccountId;
} else {
//create a new Account
Account createdAccount = new Account();
createdAccount.Name = createdCase.SuppliedCompany;
createdAccount.BillingStreet = createdCase.SuppliedCompanyAddress__c;
createdAccount.BillingCity = createdCase.SuppliedCompanyCity__c;
createdAccount.BillingState = createdCase.SuppliedCompanyState__c;
createdAccount.BillingPostalCode = createdCase.SuppliedCompanyPostalCode__c;
insert createdAccount;
newAccountId = createdAccount.Id;
createdCase.AccountId = createdAccount.Id;
}
}
//create the contact
Contact theContact = new Contact();
theContact.FirstName = createdCase.SuppliedFirstName__c;
theContact.LastName = createdCase.SuppliedLastName__c;
theContact.AccountId = newAccountId;
theContact.Email = createdCase.SuppliedEmail;
theContact.Phone = createdCase.SuppliedPhone;
theContact.MailingStreet = createdCase.SuppliedCompanyAddress__c;
theContact.MailingCity = createdCase.SuppliedCompanyCity__c;
theContact.MailingState = createdCase.SuppliedCompanyState__c;
theContact.MailingPostalCode = createdCase.SuppliedCompanyPostalCode__c;
insert theContact;
//set the contact Id on the case
createdCase.ContactId = theContact.Id;
}
}
}
}
}
And here is the Test:
// Written by Steve Andersen, copyright (c) 2008 ONE/Northwest
// This program is released under the GNU General Public License. http://www.gnu.org/licenses/
public class ONEN_TEST_ContactFromCase {
static testMethod void TestCreateCase() {
//create first case
Case firstCase = new Case (
Subject='Test Case',
SuppliedFirstName__c='Joe',
SuppliedLastName__c='Johanssen',
SuppliedEmail='joe@email.com',
SuppliedCompany = 'Test Company',
SuppliedCompanyAddress__c = '1234 Elm St.'
);
insert firstCase;
Case thisCase = [select AccountId,ContactId from Case where Id =:firstCase.id];
//the Company and Contact Ids should not be null
System.assertNotEquals(null,thisCase.AccountId);
System.assertNotEquals(null,thisCase.ContactId);
Account thisAccount = [select Name,BillingStreet from Account where Id=:thisCase.AccountId];
System.assertEquals(’Test Company’,thisAccount.Name);
System.assertEquals(’1234 Elm St.’,thisAccount.BillingStreet);
Contact thisContact = [select FirstName,LastName,Email,MailingStreet from Contact where Id=:thisCase.ContactId];
//the name should be as expected
System.assertEquals(’Joe’,thisContact.FirstName);
System.assertEquals(’Johanssen’,thisContact.LastName);
System.assertEquals(’1234 Elm St.’,thisContact.MailingStreet);
//create second case
Case secondCase = new Case (
Subject=’Test Case’,
SuppliedFirstName__c=’Joe’,
SuppliedLastName__c=’Billings’,
SuppliedEmail=’joe@email.com’,
SuppliedCompany = ‘Test Company’
);
insert secondCase;
Case thisSecondCase = [select AccountId,ContactId from Case where Id =:secondCase.id];
Contact thisSecondContact = [select FirstName,LastName,Email from Contact where Id=:thisSecondCase.ContactId];
System.assertEquals(’Joe’,thisSecondContact.FirstName);
System.assertEquals(’Johanssen’,thisSecondContact.LastName);
//we should not have created another contact
System.assertEquals(thisCase.ContactId,thisSecondCase.ContactId);
}
}
You’ll see there are some custom fields required in the code. Here is an Appexchange package of those fields.
We create these forms with the awesome PloneFormGen and the SalesforcePFGAdapter to get data into Salesforce. PloneFormGen has an automatic CAPTCHA field, so we’ll likely protect ourselves from spam by requiring CAPTCHA on all web submitted Cases.
I’m really loving working with Plone and Salesforce on this project. The tools are coming together nicely and I’m really excited about the potential of this integration between the best open-source CMS and the best on-demand CRM.