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
Eric BEric B 

Trigger to count total contacts related to an account

Hi all,
i'am new to Apex and trying to write a trigger that  counts the number of contacts with phone number related to an account and populate it on a custom field on account (Contacts_With_Phone_Numbers__c). this is the code, the problem when add a new contact to the related list, the number of contacts field is not updated! any help please!?

trigger accountsRelatedContacts on Contact (After insert,after update){ 
        // create a set of contact Ids to querry against
        List<Contact> contactsWithPhone = new List<Contact>();
        Set<Id> accIds = new Set<Id>();
        for (Contact con : contactsWithPhone){
            accIds.add(con.AccountId);
        }
    
        // querry for all the accounts with related contacts in the set of contacts           
        List<Account> accountsRelatedContacts = [Select Id, 
                                                     Name,
                                                     Contacts_With_Phone_Numbers__c,
                                                     (Select Id from Contacts)                                                   
                                                       From Account
                                                      Where Id in :accIds];
    
        // Loop through accounts to find matching contacts with phone numbers
        for (Account c : accountsRelatedContacts){
            List<Contact> s = c.Contacts;
            System.debug('Account:' + c.Name + ' No. of Contacts: '+ s.size());
            c.Contacts_With_Phone_Numbers__c = s.size();
        }
        Update accountsRelatedContacts;      
}

Thanks
Best Answer chosen by Eric B
Maharajan CMaharajan C
Hi Tarik,

Your trigger should be like below:

trigger accountsRelatedContacts on Contact (after insert,after update,after delete){ 
        // create a set of contact Ids to querry against
        Set<Id> accIds = new Set<Id>();
        List<Account> accListtoUpdate = new List<Account>();
        
        if(Trigger.isInsert){
        for(Contact con : trigger.new){
            if(con.Phone != null){
                accIds.add(con.AccountId);
            }
        }
        }
        
        else if(Trigger.isUpdate){
            for(Contact con : trigger.new){
            if(con.Phone != null && con.Phone != Trigger.oldMap.get(con.Id).Phone){
                accIds.add(con.AccountId);
            }
        }
        }

        else if(Trigger.isDelete){
        for(Contact con : trigger.old){
            if(con.Phone != null){
                accIds.add(con.AccountId);
            }
        }
        }
    
        // querry for all the accounts with related contacts in the set of contacts           
        List<Account> accountsRelatedContacts = [Select Id, 
                                                     Name,
                                                     Contacts_With_Phone_Numbers__c,
                                                     (Select Id from Contacts WHERE Phone!=null)                                                   
                                                       From Account
                                                      Where Id in :accIds];
    
        // Loop through accounts to find matching contacts with phone numbers
        for (Account c : accountsRelatedContacts){
            List<Contact> s = c.Contacts;
            System.debug('Account:' + c.Name + ' No. of Contacts: '+ s.size());
            c.Contacts_With_Phone_Numbers__c = s.size();
            accListtoUpdate.add(c);
        }
        
        if(accListtoUpdate.size() > 0)
        Update accountsRelatedContacts;      
}


Can you please Let me know if it helps or not!!!

If it helps don't forget to mark this as a best answer!!!


Thanks,
Maharajan.C

All Answers

Martha VMartha V
your variable contactsWitPhone at the begining of the for loop is empty, so the accIds has no values. This something you could do with a Rollop field where you count only the contacts that have a phone number. No need to do a trigger. But if you insist on doing a trigger then you need to first gather all the contacts with the same account id sent in the trigger and query any others in the object to see if they have phone number. Add the number of records you found and then update the account field.
Eric BEric B
Thank you Martha,

Are you suggesting that i should query all contact Ids such that:

trigger accountsRelatedContacts on Contact (After insert,after update){ 
        // create a set of contact Ids to querry against
        List<Contact> contactsWithPhone = [ Select Id from Contact];
        Set<Id> accIds = new Set<Id>();
        for (Contact con : contactsWithPhone){
            accIds.add(con.AccountId);
        }
    
        // querry for all the accounts with related contacts in the set of contacts           
        List<Account> accountsRelatedContacts = [Select Id, 
                                                     Name,
                                                     Contacts_With_Phone_Numbers__c,
                                                     (Select Id from Contacts)                                                   
                                                       From Account
                                                      Where Id in :accIds];
    
        // Loop through accounts to find matching contacts with phone numbers
        for (Account c : accountsRelatedContacts){
            List<Contact> s = c.Contacts;
            System.debug('Account:' + c.Name + ' No. of Contacts: '+ s.size());
            c.Contacts_With_Phone_Numbers__c = s.size();
        }
        Update accountsRelatedContacts;      
}
Maharajan CMaharajan C
Hi Tarik,

Your trigger should be like below:

trigger accountsRelatedContacts on Contact (after insert,after update,after delete){ 
        // create a set of contact Ids to querry against
        Set<Id> accIds = new Set<Id>();
        List<Account> accListtoUpdate = new List<Account>();
        
        if(Trigger.isInsert){
        for(Contact con : trigger.new){
            if(con.Phone != null){
                accIds.add(con.AccountId);
            }
        }
        }
        
        else if(Trigger.isUpdate){
            for(Contact con : trigger.new){
            if(con.Phone != null && con.Phone != Trigger.oldMap.get(con.Id).Phone){
                accIds.add(con.AccountId);
            }
        }
        }

        else if(Trigger.isDelete){
        for(Contact con : trigger.old){
            if(con.Phone != null){
                accIds.add(con.AccountId);
            }
        }
        }
    
        // querry for all the accounts with related contacts in the set of contacts           
        List<Account> accountsRelatedContacts = [Select Id, 
                                                     Name,
                                                     Contacts_With_Phone_Numbers__c,
                                                     (Select Id from Contacts WHERE Phone!=null)                                                   
                                                       From Account
                                                      Where Id in :accIds];
    
        // Loop through accounts to find matching contacts with phone numbers
        for (Account c : accountsRelatedContacts){
            List<Contact> s = c.Contacts;
            System.debug('Account:' + c.Name + ' No. of Contacts: '+ s.size());
            c.Contacts_With_Phone_Numbers__c = s.size();
            accListtoUpdate.add(c);
        }
        
        if(accListtoUpdate.size() > 0)
        Update accountsRelatedContacts;      
}


Can you please Let me know if it helps or not!!!

If it helps don't forget to mark this as a best answer!!!


Thanks,
Maharajan.C
This was selected as the best answer
Eric BEric B
Thank you Maharajan,

When i try to add a related contact to an existing account with other related contacts, i got this error

User-added image
Maharajan CMaharajan C
Please Confirm do you have the below query or did you changed any thing in Line 31:

// querry for all the accounts with related contacts in the set of contacts           
        List<Account> accountsRelatedContacts = [Select Id,Name,Contacts_With_Phone_Numbers__c,
                                                     (Select Id from Contacts WHERE Phone!=null)                                                   
                                                       From Account
                                                      Where Id in :accIds];
    
Remove the Debug Line:39 
 
Eric BEric B
Just removed the system.debug line and retest...this time the Contacts_With_Phone_Numbers__c field don't take into account older values!! it is set to 1 !!
Maharajan CMaharajan C
Check all the Contacts having the Phone Number in Phone Field for that Account
Eric BEric B
here are the screenshots:

Related contacts:

User-added image
and account detail page:

User-added image

Thanks
 
Eric BEric B
Thanks Maharajan !
It is working fine now...
Maharajan CMaharajan C
Hi Tarik,

Use the below Updated one it will cover all the scenario's and Optimized one :

trigger accountsRelatedContacts on Contact (after insert,after update,after delete,after undelete){ 
        // create a set of contact Ids to querry against
        Set<Id> accIds = new Set<Id>();
        List<Account> accListtoUpdate = new List<Account>();
        
        if(Trigger.isInsert){
        for(Contact con : trigger.new){
            if(con.Phone != null){
                accIds.add(con.AccountId);
            }
        }
        }
        
        else if(Trigger.isUpdate){
            for(Contact con : trigger.new){
            if(con.Phone != Trigger.oldMap.get(con.Id).Phone || con.AccountId != Trigger.oldMap.get(con.Id).AccountId){
                accIds.add(con.AccountId); 
                if(con.AccountId != Trigger.oldMap.get(con.Id).AccountId)
                accIds.add(Trigger.oldMap.get(con.Id).AccountId);     
            }
        }
        }

        else if(Trigger.isDelete){
        for(Contact con : trigger.old){
            if(con.Phone != null){
                accIds.add(con.AccountId);
            }
        }
        }
    
        else if(Trigger.isUndelete){
        for(Contact con : trigger.new){
            if(con.Phone != null){
                accIds.add(con.AccountId);
            }
        }
        }
    
    if(!accIds.isEmpty()){
    
        // querry for all the accounts with related contacts in the set of contacts           
        List<Account> accountsRelatedContacts = [Select Id, 
                                                     Name,
                                                     Contacts_With_Phone_Numbers__c ,
                                                     (Select Id from Contacts WHERE Phone!=null)                                                   
                                                       From Account
                                                      Where Id in :accIds];
        if(!accountsRelatedContacts.IsEmpty()){
        // Loop through accounts to find matching contacts with phone numbers
        for (Account c : accountsRelatedContacts){
            List<Contact> s = c.Contacts;
            //System.debug('Account:' + c.Name + ' No. of Contacts: '+ s.size());
            c.Contacts_With_Phone_Numbers__c  = s.size();
            accListtoUpdate.add(c);
        }
        
        if(accListtoUpdate.size() > 0)
        Update accountsRelatedContacts;  
        }
    }
}

Thanks,
Maharajan.C