-
Notifications
You must be signed in to change notification settings - Fork 11
Batch Code to create campaign members asynchonously
mscholtz edited this page Apr 3, 2012
·
1 revision
This code by Nick from Dogwood
global class GW_AddToCampaign implements Schedulable {
global void execute(SchedulableContext sc){
//if already scheduled, don't schedule it again
// check running batches in case there is already one running
AsyncApexJob[] batchInProgress = [select id from AsyncApexJob where (status = 'Queued' or status = 'Processing') and ApexClass.Name = 'GW_AddToCampaign'];
if (batchInProgress.size() < 1) {
GW_AddToCampaign gwatc = new GW_AddToCampaign();
//change query in tests to not modify production data
if (!test.isrunningtest()) gwatc.createCampaignMember([SELECT Id, Campaign_Id__c, Campaign_Member_Status__c FROM Contact WHERE Campaign_Id__c!=NULL LIMIT 1000]);
else gwatc.createCampaignMember([SELECT Id, Campaign_Id__c, Campaign_Member_Status__c FROM Contact WHERE Campaign_Id__c!=NULL AND FirstName='Tester8' LIMIT 1000]);
}
}
public class TestException extends Exception {} public string memo;
public void createCampaignMember(list contactsToProcess){
list<CampaignMember> membershipRecords = new list<CampaignMember>();
map<id,id> contactIds = new map<id,id>();
set<string> concatIds = new set<string>();
for (Contact thisContact : contactsToProcess) contactIds.put(thisContact.id, thisContact.Campaign_Id__c);
for (CampaignMember cm:[SELECT Id, ContactId, CampaignId FROM CampaignMember WHERE ContactId in :contactIds.keySet() and CampaignId in :contactIds.values()]) {
concatIds.add((string)cm.ContactId + ((string)cm.CampaignId).tolowercase().substring(0,15));
}
for (Contact thisContact : contactsToProcess) {
if (thisContact.Campaign_Id__c != NULL && !concatIds.contains(thisContact.Id + thisContact.Campaign_Id__c.tolowercase())) {
CampaignMember cmContact = new CampaignMember (
CampaignId=thisContact.Campaign_Id__c,
ContactId=thisContact.Id
);
if (thisContact.Campaign_Member_Status__c!=null) cmContact.Status = thisContact.Campaign_Member_Status__c;
membershipRecords.add(cmContact);
} else system.debug('This Contact already has a CampaignMember: '+thisContact);
}
boolean membersInserted = false;
try{
// test exception handling!
if (this.memo == 'cause exception') throw new TestException('You asked, we delivered: your exception!');
if (membershipRecords.size()>0) insert membershipRecords;
membersInserted=true;
} catch (System.Exception ex) {
/*if (StatusCode.UNABLE_TO_LOCK_ROW==ex.getDmlType(0)) {
system.debug('UNABLE_TO_LOCK_ROW received');
}*/
Messaging.reserveSingleEmailCapacity(1);
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(new String[] {'[email protected]'});
mail.setSubject('Dogwood Campaign Error');
mail.setPlainTextBody('Exception: ' + ex +' Contacts: ' + contactsToProcess);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
Datetime sysTime = System.now().addMinutes(5);
String chron_exp = '' + sysTime.second() + ' ' + sysTime.minute() + ' ' + sysTime.hour() + ' ' + sysTime.day() + ' ' + sysTime.month() + ' ? ' + sysTime.year();
GW_AddToCampaign batch = new GW_AddToCampaign();
System.schedule('GW_AddToCampaign scheduled job ' + sysTime.getTime(), chron_exp, batch);
}
//if the insert succeeded, blank the contact fields.
if (membersInserted) blankContactFields(contactIds.keyset());
}
@future //because fields on Contact can't be updated in an After Insert trigger call static void blankContactFields (set contactIds){ list contactsToBlank = [SELECT Id, Campaign_Id__c, Campaign_Member_Status__c FROM Contact WHERE Id in :contactIds];
for (Contact c: contactsToBlank) {
c.Campaign_Id__c = null;
c.Campaign_Member_Status__c = null;
}
update contactsToBlank;
}
static testmethod void addMember(){ Campaign tc = new Campaign( Name='Foobar', isactive=true ); insert tc;
CampaignMemberStatus cms = new CampaignMemberStatus(
Label='FOO',
CampaignId = tc.id,
HasResponded=true,
SortOrder = 8
);
insert cms;
list<Contact> testcons = new list<Contact>();
for(integer i=0;i<5;i++) {
Contact c = new Contact(
FirstName='Tester8',
LastName='LN_'+i,
Email='[email protected]',
Campaign_Id__c = tc.id,
Campaign_Member_Status__c='FOO'
);
testcons.add(c);
}
test.startTest();
insert testcons;
test.stopTest();
//Verify CampaignMembers
list<CampaignMember> querycm = [SELECT Id, Status FROM CampaignMember WHERE CampaignId=:tc.id ];
system.assertequals(5, querycm.size(), 'Five Campaign Members should be created');
system.assertequals('FOO', querycm[0].Status, 'Status should be set correctly');
//Verify Contact fields are blanked out
list<Contact> querycon = [SELECT Id, Campaign_Id__c, Campaign_Member_Status__c FROM Contact WHERE Email='[email protected]'];
system.assertequals(null,querycon[0].Campaign_Id__c,'Campaign_Id__c should be null');
system.assertequals(null,querycon[0].Campaign_Member_Status__c,'Campaign_Member_Status__c should be null');
}
static testmethod void existingCampaignMember(){
GW_AddToCampaign atc = new GW_AddToCampaign();
Campaign tc = new Campaign(
Name='Foobar',
isactive=true
);
insert tc;
Contact con = new Contact(
LastName='o,o',
FirstName='Tester8',
Email='[email protected]'
);
insert con;
//setting this variables after insert so the trigger doesn't fire
con.Campaign_Id__c = tc.id;
update con;
CampaignMember cm = new CampaignMember(
ContactId = con.id,
CampaignId = tc.id
);
insert cm;
atc.createCampaignMember([SELECT Id, Campaign_Id__c, Campaign_Member_Status__c FROM Contact WHERE ID=:con.id]);
}
static testmethod void testException(){
GW_AddToCampaign atc = new GW_AddToCampaign();
atc.memo='cause exception';
Campaign tc = new Campaign(
Name='Foobar',
isactive=true
);
insert tc;
Contact con = new Contact(
LastName='o,o',
FirstName='Tester8',
Email='[email protected]'
);
insert con;
//setting this variables after insert so the trigger doesn't fire
con.Campaign_Id__c = tc.id;
update con;
test.startTest();
//this should fail gracefully
atc.createCampaignMember([SELECT Id, Campaign_Id__c, Campaign_Member_Status__c FROM Contact WHERE id=:con.id ]);
list<CampaignMember> cm = [SELECT Id, Status FROM CampaignMember WHERE CampaignId=:tc.id ];
system.assertequals(0, cm.size(), 'Campaign Member should not exist due to the exception thrown');
// causes queued code to run.
test.stopTest();
cm = [SELECT Id, Status FROM CampaignMember WHERE CampaignId=:tc.id ];
system.assertequals(1, cm.size(), 'Campaign Member should be created');
} }