I have built a large Apex trigger that really belongs in a class, but I am not sure how to transition my code from a trigger to a trigger/class/method schema.
So my question: How would I migrate these triggers into a trigger/class/methods structure?
(This code could also use some bulkifying, so forgive the vain repetitions and excessive SOQL calls.)
TRIGGER 1 OF 2
trigger LC_Update_LD on LeadCompany__c (after update){
for (LeadCompany__c LC: Trigger.new) {
List<LeadCompany__c> LClist = [SELECT ID, OwnerId, Name, Lead_Count__c, Status__c FROM LeadCompany__c WHERE ID = :LC.Id LIMIT 1];
List<Lead> LDList = [SELECT Id, OwnerID, Company, LC_Lead_Company__c FROM Lead WHERE LC_Lead_Company__C in :LClist AND isConverted = False];
LeadCompany__c oldLC = Trigger.oldMap.get(LC.ID);
if(LC.Lead_Count__c != null){
// Update Leads Owner
if(LC.OwnerID != oldLC.OwnerID) {
System.debug('--*Lead Company Owner is changed*--');
System.debug('**Old Owner :'+oldLC.OwnerID);
System.debug('**New Owner :'+LC.OwnerID);
String OldOwnerId = oldLC.OwnerId;
String NewOwnerId = LC.OwnerId;
//Logic to change lead owners
for(integer i = 0; i < LdList.size(); i++){
LdList[i].OwnerID = LC.OwnerID;
}
update LdList;
}
// Update Leads Company Name
if(LC.Name != oldLC.Name) {
System.debug('--*Lead Company Name is changed*--');
System.debug('**Old Name :'+oldLC.Name);
System.debug('**New Name :'+LC.Name);
for(integer i = 0; i < LdList.size(); i++){
LdList[i].Company = LC.Name;
}
update LdList;
}
}
}
}
TRIGGER 2 OF 2
trigger LD_Update_LC on Lead (before insert, before update, after delete, after insert, after update){
Set<ID> LeadCompanyIds = new Set<ID>();
Set<ID> OldLcId = new Set<Id>();
if(Trigger.isBefore){
// For New Leads
if(Trigger.isInsert){
for (Lead ld: Trigger.new){
// If no blank email, check blacklist
if (ld.LC_Email_Domain__c != null){
// If domain not on blacklist, associate existing or create new
List<Blacklist_Domain__c> Blacklist = [SELECT Name FROM Blacklist_Domain__c WHERE Name = :ld.LC_Email_Domain__c];
if (Blacklist.size() == 0){
// Search for existing company
List<LeadCompany__c> lc = [SELECT ID, Name, OwnerId, Status__c, Domain__c FROM LeadCompany__c WHERE Domain__c = :ld.LC_Email_Domain__c LIMIT 1];
//If company exists, associate LD, change LD Owner, compare LC Status
if (lc.size() > 0) {
for(integer i = 0; i < lc.size(); i++){
// Associate Lead to Company
ld.LC_Lead_Company__c = lc[i].id;
// Change Lead Owner to Company Owner
ld.OwnerId = lc[i].ownerId;
// Compare Lead Status to Company Status
if(lc[i].Status__c != Ld.Status){
Map<String, Integer> status_value = new Map<String, Integer>{
'Open - Not Contacted' => 2,
'Working - Contacted' => 3,
'Working - Initial Meeting Scheduled' => 4,
'Closed - Qualified' => 5,
'Closed - Unqualified' =>1,
null => 0
};
Integer LC_Status_Value = status_value.get(lc[i].Status__c);
Integer LD_Status_Value = status_value.get(Ld.Status);
//Set Lead Company Status
if(LD_Status_Value > LC_Status_Value){
lc[i].Status__c = Ld.Status;
}
}
}
update lc;
}
// If no company exists, create new LC, associate LD
else {
// Create new company
LeadCompany__c nlc = new LeadCompany__c (
Domain__c = ld.LC_Email_Domain__c,
Name = ld.Company,
OwnerId = ld.OwnerId,
Status__c = ld.Status
);
insert nlc;
// Associate new lead to new company
ld.LC_Lead_Company__c = nlc.id;
}
}
}
}
}
// For Existing Leads
if(Trigger.isUpdate){
for (Lead ld: Trigger.new){
//Get old record values
Lead oldLd = Trigger.oldMap.get(Ld.ID);
// If no email, email is changed, or company left blank, check blacklist
if (ld.LC_Email_Domain__c != null && (ld.LC_Email_Domain__c != oldld.LC_Email_Domain__c || string.isblank(ld.LC_lead_Company__c))){
// If domain not on blacklist, associate existing or create new
List<Blacklist_Domain__c> Blacklist = [SELECT Name FROM Blacklist_Domain__c WHERE Name = :ld.LC_Email_Domain__c];
if (Blacklist.size() == 0){
// Search for existing company
List<LeadCompany__c> lc = [SELECT ID, Name, OwnerId, Status__c, Domain__c FROM LeadCompany__c WHERE Domain__c = :ld.LC_Email_Domain__c LIMIT 1];
//If company exists, associate LD, change LD Owner, compare LC Status
if (lc.size() > 0) {
for(integer i = 0; i < lc.size(); i++){
// Associate Lead to Company
ld.LC_Lead_Company__c = lc[i].id;
// Change Lead Owner to Company Owner
ld.OwnerId = lc[i].ownerId;
// Compare Lead Status to Other Leads, Set Company Status
if(lc[i].Status__c != Ld.Status){
Map<String, Integer> status_value = new Map<String, Integer>{
'Open - Not Contacted' => 2,
'Working - Contacted' => 3,
'Working - Initial Meeting Scheduled' => 4,
'Closed - Qualified' => 5,
'Closed - Unqualified' =>1,
null => 0
};
Map<Integer, String> status_name = new Map<Integer, String>{
2 => 'Open - Not Contacted',
3 => 'Working - Contacted',
4 => 'Working - Initial Meeting Scheduled',
5 => 'Closed - Qualified',
1 => 'Closed - Unqualified',
0 => null
};
List<Lead> Lds = [SELECT ID, Status FROM Lead WHERE LC_Lead_Company__c = :ld.LC_Lead_Company__c];
List<Integer> LD_Stat_Values = new List<Integer>();
Integer LC_Stat_Value = status_value.get(lc[i].Status__c);
//Convert Picklist values to numbered list
for(integer j = 0; j < Lds.size(); j++){
LD_Stat_Values.add(status_value.get(lds[j].Status));
}
//Get Highest Picklist Value
Integer LD_Stat_Val = 0;
for(integer j = 0; j < Lds.size(); j++){
if(status_value.get(lds[j].Status) > LD_Stat_Val){
LD_Stat_Val = status_value.get(lds[j].Status);
}
}
//Set Lead Company Status
if(LD_Stat_Val != LC_Stat_Value){
lc[i].Status__c = status_name.get(LD_Stat_Val);
}
}
}
update lc;
}
// If no company exists, create new LC, associate LD
else {
// Create new company
LeadCompany__c nlc = new LeadCompany__c (
Domain__c = ld.LC_Email_Domain__c,
Name = ld.Company,
OwnerId = ld.OwnerId,
Status__c = ld.Status
);
insert nlc;
// Associate new lead to new company
ld.LC_Lead_Company__c = nlc.id;
}
}
// If domain is on blacklist, remove association, update old company
else {
// Remove company association
Ld.LC_Lead_Company__c = null;
//Update Old Company [HOW DO I DO THIS!!]
LeadCompanyIds.add(oldld.LC_Lead_Company__c);
}
}
}
}
}
if(Trigger.isAfter ){
// For Deleted Leads, add company to update list
if(trigger.isDelete){
for(Lead ld : trigger.old){
if(ld.LC_Lead_Company__c != null)
LeadCompanyIds.add(ld.LC_Lead_Company__c);
}
}
// For Inserted Leads, add company to update list
if(trigger.isInsert){
for(Lead ld : trigger.new){
if(ld.LC_Lead_Company__c != null)
LeadCompanyIds.add(ld.LC_Lead_Company__c);
}
}
// For Updated Leads
if(Trigger.isUpdate ){
for (Lead Ld: Trigger.new) {
// For Converted Leads
if (ld.IsConverted == True && ld.LC_Lead_Company__c != null){
//Find related Leads
ID AccId = ld.ConvertedAccountId;
List<Lead> LeadConvertList = [SELECT Id, LC_Lead_Company__c FROM Lead WHERE LC_Lead_Company__C = :ld.LC_Lead_Company__c AND IsConverted = False];
//Convert all related Leads
if(LeadConvertList.size() > 0){
for(integer i = 0; i < LeadConvertList.size(); i++){
Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(LeadConvertList[i].id);
lc.setAccountId(AccId);
lc.setDoNotCreateOpportunity(TRUE);
LeadStatus convertStatus = [SELECT Id, MasterLabel, IsConverted FROM LeadStatus WHERE IsConverted=true limit 1];
lc.setConvertedStatus(convertStatus.MasterLabel);
Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());
}
}
}
// For Unconverted Leads
else {
// Get old values
Lead oldLd = Trigger.oldMap.get(Ld.ID);
//Check for Lead transfers
if(ld.LC_Lead_Company__c != oldLd.LC_Lead_Company__c){
if(ld.LC_Lead_Company__c != null){
LeadCompanyIds.add(ld.LC_Lead_Company__c);
}
if(oldLd.LC_Lead_Company__c != null){
OldLcId.add(oldLd.LC_Lead_Company__c);
}
}
//Update New Lead Company
List<LeadCompany__c> NewLC = [SELECT Id, Name, OwnerID, Domain__c, Status__c FROM LeadCompany__c WHERE ID = :Ld.LC_Lead_Company__c LIMIT 1];
if(NewLC.size() > 0){
for(integer i = 0; i < NewLC.size(); i++){
//Update lead company owner
if(Ld.OwnerID != oldLd.OwnerID) {
NewLC[i].OwnerID = Ld.OwnerID;
}
//Update lead company name
if(Ld.Company != oldLd.Company) {
NewLC[i].Name = Ld.Company;
}
//Update lead company status
if(NewLC[i].Status__c != Ld.Status){
Map<String, Integer> status_value = new Map<String, Integer>{
'Open - Not Contacted' => 2,
'Working - Contacted' => 3,
'Working - Initial Meeting Scheduled' => 4,
'Closed - Qualified' => 5,
'Closed - Unqualified' =>1,
null => 0
};
Map<Integer, String> status_name = new Map<Integer, String>{
2 => 'Open - Not Contacted',
3 => 'Working - Contacted',
4 => 'Working - Initial Meeting Scheduled',
5 => 'Closed - Qualified',
1 => 'Closed - Unqualified',
0 => null
};
List<Lead> Lds = [SELECT ID, Status FROM Lead WHERE LC_Lead_Company__c = :ld.LC_Lead_Company__c];
List<Integer> LD_Stat_Values = new List<Integer>();
Integer LC_Stat_Val = status_value.get(NewLC[i].Status__c);
Integer LD_Stat_Val = 0;
//Convert Picklist values to numbered list
for(integer j = 0; j < Lds.size(); j++){
LD_Stat_Values.add(status_value.get(lds[j].Status));
}
//Get highest Lead Status
for(integer j = 0; j < Lds.size(); j++){
if(status_value.get(lds[j].Status) > LD_Stat_Val){
LD_Stat_Val = status_value.get(lds[j].Status);
}
}
//Compare Lead Status with Lead Company Status
if(LD_Stat_Val != LC_Stat_Val){
NewLC[i].Status__c = status_name.get(LD_Stat_Val);
}
}
}
//Update lead company
update NewLC;
}
//Update Old Lead Company
List<LeadCompany__c> OldLC = [SELECT Id, Name, OwnerID, Domain__c, Status__c FROM LeadCompany__c WHERE ID = :oldLd.LC_Lead_Company__c AND ID != :Ld.LC_Lead_Company__c LIMIT 1];
if(OldLC.size() > 0){
//Update lead company status
for(integer i = 0; i < OldLC.size(); i++){
if(OldLC[i].Status__c == OldLd.Status){
Map<String, Integer> status_value = new Map<String, Integer>{
'Open - Not Contacted' => 2,
'Working - Contacted' => 3,
'Working - Initial Meeting Scheduled' => 4,
'Closed - Qualified' => 5,
'Closed - Unqualified' =>1,
null => 0
};
Map<Integer, String> status_name = new Map<Integer, String>{
2 => 'Open - Not Contacted',
3 => 'Working - Contacted',
4 => 'Working - Initial Meeting Scheduled',
5 => 'Closed - Qualified',
1 => 'Closed - Unqualified',
0 => null
};
List<Lead> Lds = [SELECT ID, Status FROM Lead WHERE LC_Lead_Company__c = :oldld.LC_Lead_Company__c];
List<Integer> LD_Stat_Values = new List<Integer>();
Integer LC_Stat_Value = status_value.get(OldLC[i].Status__c);
//Convert Picklist values to numbered list
for(integer j = 0; j < Lds.size(); j++){
LD_Stat_Values.add(status_value.get(lds[j].Status));
}
Integer LD_Stat_Val = 0;
for(integer j = 0; j < Lds.size(); j++){
if(status_value.get(lds[j].Status) > LD_Stat_Val){
LD_Stat_Val = status_value.get(lds[j].Status);
}
}
if(LD_Stat_Val != LC_Stat_Value){
OldLC[i].Status__c = status_name.get(LD_Stat_Val);
}
update NewLC;
}
}
update OldLC;
Set<Id> OldLCset = (new Map<Id,LeadCompany__c>(OldLC)).keySet();
LeadCompanyIds.addall(OldLCset);
}
}
}
}
}
if(LeadCompanyIds != Null){
List<AggregateResult> aggs = [select LC_Lead_Company__c, count(ID) LeadCount from Lead where LC_Lead_Company__c in : LeadCompanyIds Group By LC_Lead_Company__c];
Map<Id,Integer> LeadCountMap = new Map<Id,Integer>();
for (AggregateResult agg : aggs) {
LeadCountMap.put(string.valueOf(agg.get('LC_Lead_Company__c')),Integer.valueOf(agg.get('LeadCount')));
}
List<LeadCompany__c> LeadCompaniesToUpdate = new List<LeadCompany__c>();
if(LeadCompanyIds != null){
for(Id LcId : LeadCompanyIds ){
LeadCompany__c newLc = new LeadCompany__c(id=LcId);
newLc.Lead_Count__c = LeadCountMap.get(LcId);
LeadCompaniesToUpdate.add(newLc);
}
}
update LeadCompaniesToUpdate;
}
// Update Lead Count For Old Lead Company
if(OldLcId != Null){
List<AggregateResult> aggsOld = [select LC_Lead_Company__c, count(ID) LeadCount from Lead where LC_Lead_Company__c in : OldLcId Group By LC_Lead_Company__c];
Map<Id,Integer> LeadCountMap = new Map<Id,Integer>();
for (AggregateResult agg : aggsOld) {
LeadCountMap.put(string.valueOf(agg.get('LC_Lead_Company__c')),Integer.valueOf(agg.get('LeadCount')));
}
List<LeadCompany__c> LeadCompaniesToUpdateOld = new List<LeadCompany__c>();
if(OldLcId!= null){
for(Id LcId : OldLcId){
LeadCompany__c newLc = new LeadCompany__c(id=LcId);
newLc.Lead_Count__c = LeadCountMap.get(LcId);
LeadCompaniesToUpdateOld.add(newLc);
}
}
update LeadCompaniesToUpdateOld;
}
}
A best practice is to have a class to attend trigger calls for a particular Object.
i.e.
and your trigger...
Hope that helps!