You need to sign in to do that
Don't have an account?

Learning how to bulkify trigger code, but stuck
Alright, as a newbie to bulkifying trigger code, I'm scratching my head on this one. I feel like I've read all I can on List collections, but I still can't figure how to get going in this situation. Here's what we've got cooking.
Objects in play: CampaignMember, Campaign, Lead
Goal: after the insert of a new campaignmember record, convert the campaignmember's associated Lead record.
We created this without the bulkifying process, and as one would expect, when someone goes to add a bunch of campaignmembers to a campaign, our trigger fires, and often times quite quickly hits the SOQL governor limit due to queries within a loop.
Here's the core snippet of code we have created, unbulkified. I'm trying to learn how to get better at bulkifying things, and this one seems a bit complex.
trigger ECampaignMember on CampaignMember (after insert) { for(CampaignMember myCampaignMember: Trigger.new){ // Find the lead record related to this campaign member Lead l = [SELECT FirstName, LastName, Email, Street, City, State, PostalCode, RecordTypeId, IsConverted, RegistrationMatchReviewNeeded__c FROM Lead WHERE Id = :myCampaignMember.LeadId LIMIT 1]; // Find the name of the campaign that this campaign member is related to Campaign campaign = [SELECT Name FROM Campaign WHERE id = :myCampaignMember.CampaignId LIMIT 1]; // Find the RecordType ID for the Lead RecordType that has DeveloperName = Registration_Lead RecordType rlrt = [SELECT Id FROM RecordType WHERE SobjectType = 'Lead' AND DeveloperName = 'Registration_Lead' LIMIT 1]; // Make sure this is a Registration lead record type. If not, don't do any of this. if(l.IsConverted==false && l.RecordTypeId == rlrt.id){ // Set the variables String c = '1'; String a = '1'; Database.LeadConvert lc = new database.LeadConvert(); lc.setLeadId(myCampaignMember.LeadId); // need to assign the conversion status to match the dropdown options lc.convertedStatus = 'Closed - Converted'; // If the lead is not already converted, AND if the lead record type has a DeveloperName = Registration_Lead. If not, don't create an opportunity record. if(l.IsConverted==false && l.RecordTypeId == rlrt.Id){ // create a new opportunity upon conversion lc.setDoNotCreateOpportunity(false); } else { // create a new opportunity upon conversion lc.setDoNotCreateOpportunity(true); } // If the lead is not already converted, AND if the lead record type has a DeveloperName = Registration_Lead if((l.IsConverted==false && (l.RecordTypeId == rlrt.Id))){ // name the opportunity in the format: "<firstname> <lastname> - <campaign_name> - Event Registration" lc.setOpportunityName(l.FirstName + ' ' + l.LastName + ' - ' + campaign.Name + ' - Event Registration'); } // If there is an existing contact that matches on last name, first name, and email address... if(i>0){ // set the contact ID lc.setContactId(c); // set the account ID lc.setAccountId(a); } Database.LeadConvertResult lcr = Database.convertLead(lc); System.assert(lcr.isSuccess()); } } } }
Now, I generally understand the following:
1) I need to get all the SOQL queries out from under the for loop
2) I need to build a list of the campaign members that I need to iterate through
The biggest challenge is that you can see down towards the bottom of the code, that I need to grab values in related objects (like the Campaign object), so that I can include them in the conversion process. For instance, I need to get the name of the Campaign related to the current campaign member so that I can include that in the sting that will be used to create the new Opportunity record name upon conversion.
How the heck do I do that?
Thanks in advance for even the first step of help on this. It's greatly appreciated.
Cheers!
Hi,
Try the below code as reference:
trigger ECampaignMember on CampaignMember (after insert)
{
list<id> ids=new list<id>();
for(CampaignMember myCampaignMember: Trigger.new)
{
ids.add(myCampaignMember.LeadId);
}
// Find the lead record related to this campaign member
for(Lead l :[SELECT FirstName, LastName, Email, Street, City, State, PostalCode, RecordTypeId, IsConverted, RegistrationMatchReviewNeeded__c FROM Lead WHERE Id in :ids])
{
// Find the name of the campaign that this campaign member is related to
Campaign campaign = [SELECT Name FROM Campaign WHERE id = :myCampaignMember.CampaignId LIMIT 1];
// Find the RecordType ID for the Lead RecordType that has DeveloperName = Registration_Lead
RecordType rlrt = [SELECT Id FROM RecordType WHERE SobjectType = 'Lead' AND DeveloperName = 'Registration_Lead' LIMIT 1];
// Make sure this is a Registration lead record type. If not, don't do any of this.
if(l.IsConverted==false && l.RecordTypeId == rlrt.id)
{
// Set the variables
String c = '1';
String a = '1';
Database.LeadConvert lc = new database.LeadConvert();
lc.setLeadId(myCampaignMember.LeadId);
// need to assign the conversion status to match the dropdown options
lc.convertedStatus = 'Closed - Converted';
// If the lead is not already converted, AND if the lead record type has a DeveloperName = Registration_Lead. If not, don't create an opportunity record.
if(l.IsConverted==false && l.RecordTypeId == rlrt.Id){
// create a new opportunity upon conversion
lc.setDoNotCreateOpportunity(false);
} else {
// create a new opportunity upon conversion
lc.setDoNotCreateOpportunity(true);
}
// If the lead is not already converted, AND if the lead record type has a DeveloperName = Registration_Lead
if((l.IsConverted==false && (l.RecordTypeId == rlrt.Id))){
// name the opportunity in the format: "<firstname> <lastname> - <campaign_name> - Event Registration"
lc.setOpportunityName(l.FirstName + ' ' + l.LastName + ' - ' + campaign.Name + ' - Event Registration');
}
// If there is an existing contact that matches on last name, first name, and email address...
if(i>0){
// set the contact ID
lc.setContactId(c);
// set the account ID
lc.setAccountId(a);
}
Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());
}
}
}
Did this answer your question? If not, let me know what didn't work, or if so, please mark it solved.
Hi Navatar_DbSup and Tej,
Thanks for the good ideas. I'm going to try both out, and let you know the results. This is extremely helpful!