function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
NightShadeNightShade 

Urgent - Help with Trigger

Hi ,

 

I have a requirement where I need to count the total number of Contacts of  type " Lead_Source_Detail__c == 'freemium LP' " for an account and put that total in a field on Account called " Number_Of_Contacts__c". When some contact upgrades to a different type (i.e other than freemium ) I need to update the Number_of_Contacts__c field so as it reflects the current total. I was initially thinking of  roll up summary fields but that would not work since there is no Master Detail relationship. So I wrote the below trigger . Now it is adding the freemium contacts for the first time but when the contact is upgraded it is not updating the Number_Of_Contacts__c field  to reflect the new total . I have tried a lot of different ways so I  apologize if the code seems messy but i never had to write a trigger at such a scale . Need help urgently .

 

 

Thanks and Regards

 

 

 

trigger UpdAct on Contact (after insert , after delete , after update ) {

Set<id> acctsids = new Set<id>();
    List<Account> ActtoUpdate = new List<Account>();
 

for (Contact c : Trigger.new)

    if (c.Lead_Source_Detail__c=='freemium LP'){
    
   
        acctsids.add(c.AccountId);
 }
    if (Trigger.isUpdate || Trigger.isDelete) {
        for (Contact c : Trigger.old){
       if  (c.Lead_Source_Detail__c =='freemium LP'){
         
         acctsids.add(c.AccountId);
         }
         
         
       else if (c.Lead_Source_Detail__c!='freemium LP'){
          
          acctsids.remove(c.AccountId);
     }
    }
    }
  database.update(ActtoUpdate);
 
 
Map<id,Account> AcctMap = new Map<id,Account>([select id, Number_Of_Contacts__c from Account where id IN :acctsids]);

 //  for (Account acc : [ Select Count_distinct(id), Number_Of_Contacts__c, (select Contact.id from Account.Contacts) from Account where Id IN :acctsids]){


// for (Contact c : [ Select Count(AccountId) from Contact where AccountId IN : acctsids]){


  for (Account acc: [select Id, Name,Number_Of_Contacts__c ,(select Contact.id from Account.Contacts) from Account where Id IN :acctsids]) {
        
        
       Contact c;  
        
       
      //  Account acc;
        
        AcctMap.get(acc.Id).Number_Of_Contacts__c = acc.Contacts.size();       
        
       // [Select Count_distinct(Name) from Contact where Lead_Source_Detail__c='freemium LP'];
        
      
        
       ActtoUpdate.add(AcctMap.get(acc.Id));
    
    
   
 // if(c.Lead_Source_Detail__c != 'freemium LP'){
 
 
//  AcctMap.get(acc.Id).Number_Of_Contacts__c = acc.Contacts.size();
 
 //Delete(ActtoUpdate);
 
   // }
 
}


    update ActtoUpdate;


}

Best Answer chosen by Admin (Salesforce Developers) 
NightShadeNightShade

I may be missing something but , when I tried the code without trigger.isupdate and I updated a contact to "freemium LP" the "Number_Of_Contacts "field was not being updated . 

 

 

I think its working now with the below code . Thanks again for all your help .

 

 

 

trigger UpdAct on Contact (after insert , after delete , after update ) {

Set<id> acctids = new Set<id>();
    List<Account> ActtoUpdate = new List<Account>();
 


     if(trigger.isDelete || trigger.isUpdate){
        for (Contact c : Trigger.old){
           // if (c.Lead_Source_Detail__c=='freemium LP'){
                acctids.add(c.AccountId);
          //  }
        }
        
        
  //  database.update(ActtoUpdate);
    }
    
    
    
    else{
        for (Contact c : Trigger.new){
           // if (c.Lead_Source_Detail__c=='freemium LP'){
                acctids.add(c.AccountId);
          //  }
    
    
       }
       
      //  database.update(ActtoUpdate);
    }
 
 
      
      
   
 
 
Map<id,Account> AcctMap = new Map<id,Account>([select id, Number_Of_Contacts__c from Account where id IN :acctids]);

  for (Account acc: [select Id, Name,Number_Of_Contacts__c ,(select Contact.Id from Account.Contacts where Lead_Source_Detail__c = 'freemium LP') from Account where Id IN :acctids]) {
           
        
        AcctMap.get(acc.Id).Number_Of_Contacts__c = acc.Contacts.size();
                
       ActtoUpdate.add(AcctMap.get(acc.Id));     
}
    update ActtoUpdate;




}

All Answers

kyle.tkyle.t

Assuming the code after Map<id,Account> already worked, I think you just need to update the code that builds the acctsids set.  Maybe somthing like this.

 

 

trigger UpdAct on Contact (after insert , after delete , after update ) {

	Set<id> acctsids = new Set<id>();
	List<Account> ActtoUpdate = new List<Account>();
	 
	if(trigger.isDelete){
		for (Contact c : Trigger.old){
			if (c.Lead_Source_Detail__c=='freemium LP'){
				acctsids.add(c.AccountId);
			}
		}
	}else{
		for (Contact c : Trigger.new){
			if (c.Lead_Source_Detail__c=='freemium LP'){
				acctsids.add(c.AccountId);
			}
		}
	}
 
	Map<id,Account> AcctMap = new Map<id,Account>([select id, Number_Of_Contacts__c from Account where id IN :acctsids]);
	for (Account acc: [select Id, Name,Number_Of_Contacts__c ,(select Contact.id from Account.Contacts) from Account where Id IN :acctsids]) {
		Contact c; 			
		AcctMap.get(acc.Id).Number_Of_Contacts__c = acc.Contacts.size();       
		ActtoUpdate.add(AcctMap.get(acc.Id));
	}
	update ActtoUpdate;
}

 

 

NightShadeNightShade

Hi Kyle,

 

Thanks a lot for your help , you kinda saved my day . Here is the final working code just for your reference.

 

 

 

trigger UpdAct on Contact (after insert , after delete , after update ) {

Set<id> acctids = new Set<id>();
    List<Account> ActtoUpdate = new List<Account>();
 


     if(trigger.isDelete || trigger.isUpdate){
        for (Contact c : Trigger.old){
            if (c.Lead_Source_Detail__c=='freemium LP'){
                acctids.add(c.AccountId);
            }
        }
    }
    
    
    else{
        for (Contact c : Trigger.new){
            if (c.Lead_Source_Detail__c=='freemium LP'){
                acctids.add(c.AccountId);
            }
        }
    }
 
 
      
      
    database.update(ActtoUpdate);
 
 
Map<id,Account> AcctMap = new Map<id,Account>([select id, Number_Of_Contacts__c from Account where id IN :acctids]);

  for (Account acc: [select Id, Name,Number_Of_Contacts__c ,(select Contact.Id from Account.Contacts where Lead_Source_Detail__c = 'freemium LP') from Account where Id IN :acctids]) {
           
        
        AcctMap.get(acc.Id).Number_Of_Contacts__c = acc.Contacts.size();
                
       ActtoUpdate.add(AcctMap.get(acc.Id));     
}
    update ActtoUpdate;

}

kyle.tkyle.t

Glad to help... don't forget to mark  this a solved

NightShadeNightShade

hey Kyle,

 

I think I counted my chickens too fast . The trigger is now giving me a weird behaviour , when I update the contact to freemium contact it does not update the Number_of_Contacts field the first time I press save . When I go back to the contact page and press save again only then does the field get updated . Any ideas why this may be happening ?

 

Thanks and Regards

kyle.tkyle.t

Why did you change the if statment to

 

if(trigger.isDelete || trigger.isUpdate){

 

My if the trigger is a delete then you want to look at trigger.old to see if it WAS a freemium LP otherwise you want to look at the new state of the contact, which is in trigger.new.

 

Try making the if statment just

 

if(trigger.isDelete)

NightShadeNightShade

I may be missing something but , when I tried the code without trigger.isupdate and I updated a contact to "freemium LP" the "Number_Of_Contacts "field was not being updated . 

 

 

I think its working now with the below code . Thanks again for all your help .

 

 

 

trigger UpdAct on Contact (after insert , after delete , after update ) {

Set<id> acctids = new Set<id>();
    List<Account> ActtoUpdate = new List<Account>();
 


     if(trigger.isDelete || trigger.isUpdate){
        for (Contact c : Trigger.old){
           // if (c.Lead_Source_Detail__c=='freemium LP'){
                acctids.add(c.AccountId);
          //  }
        }
        
        
  //  database.update(ActtoUpdate);
    }
    
    
    
    else{
        for (Contact c : Trigger.new){
           // if (c.Lead_Source_Detail__c=='freemium LP'){
                acctids.add(c.AccountId);
          //  }
    
    
       }
       
      //  database.update(ActtoUpdate);
    }
 
 
      
      
   
 
 
Map<id,Account> AcctMap = new Map<id,Account>([select id, Number_Of_Contacts__c from Account where id IN :acctids]);

  for (Account acc: [select Id, Name,Number_Of_Contacts__c ,(select Contact.Id from Account.Contacts where Lead_Source_Detail__c = 'freemium LP') from Account where Id IN :acctids]) {
           
        
        AcctMap.get(acc.Id).Number_Of_Contacts__c = acc.Contacts.size();
                
       ActtoUpdate.add(AcctMap.get(acc.Id));     
}
    update ActtoUpdate;




}

This was selected as the best answer