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
Synthia BeauvaisSynthia Beauvais 

Trigger to Count the Number of Active Contacts

I would like to modify the code below to count the number of active contacts on an account. How can I make this change? 

Inactive__c (Checkbox)

 
//Test Class

@isTest
public class testClass1{
    @isTest
    public static void unitTest1(){
        List<Account> lstAccount = new List<Account>();
        lstAccount.add(new Account(name='testAccount1'));
        lstAccount.add(new Account(name='testAccount2'));
        lstAccount.add(new Account(name='testAccount3'));
        insert lstAccount;
        List<Contact> lstContact = new List<Contact>();
        lstContact.add(new Contact(lastName='testLast1',accountId=lstAccount[1].id));                
        lstContact.add(new Contact(lastName='testLast2',accountId=lstAccount[1].id));
        lstContact.add(new Contact(lastName='testLast3',accountId=lstAccount[1].id));                
        insert lstContact;
        delete lstContact[1];
    }
}


//On Contact

trigger NumberOfContactsOnAccount on Contact (after insert, after update, after delete, after undelete) {
    List<Contact> contacts = new list<contact>();
    Map<Id,account> accounts = new map<id,account>();
    if(trigger.new!=null)
        contacts.addAll(trigger.new);
    if(trigger.old!=null)
        contacts.addAll(trigger.old);
    for(contact c:contacts)
        accounts.put(c.accountid,new account(id=c.accountid));
    accounts.remove(null);
    update accounts.values();
}


//On Account

trigger NumberOfContacts on Account (before insert, before update) {
    if(trigger.isinsert)
        for(account a:trigger.new)
            a.Number_of_contacts_2__c = 0;
    else
        for(account a:[select id,(select id from contacts) from account where id in :trigger.new])
            trigger.newmap.get(a.id).Number_of_contacts_2__c = a.contacts.size();
}


 
Best Answer chosen by Synthia Beauvais
Synthia BeauvaisSynthia Beauvais
This has been resolved!! Here is the updated the trigger on account object.
 
trigger NumberOfContacts on Account (before insert, before update) {
    if(trigger.isinsert)
        for(account a:trigger.new)
            a.Number_of_contacts__c = 0;
    else
        for(account a:[select id,(select id from contacts) from account where id in :trigger.new])
            trigger.newmap.get(a.id).Number_of_contacts__c = a.contacts.size();
            
        for(account b:[select id,(select id from contacts where Inactive__c = False) from account where id in :trigger.new])
            trigger.newmap.get(b.id).Number_of_active_contacts__c = b.contacts.size();
}

Thanks!!
 

All Answers

Vishal ShelarVishal Shelar
You can create a map of Account and list of contacts and check the size of contacts.
Map<ID,List<Contacts>> mapoAccountWithContacts  =  new Map<ID,List<Contacts>> ();
List<Contact> listOfContact = new List<Contact>();
listOfContact = [select Id, Name from Contact where Id IN: Trigger.New(id of account from trigger.new ) AND Inactive__c == False];

for(Contact eachContact  : listOfContact ){
   if(mapoAccountWithContacts.containsKey(eachContact.AccountID)){
      List<Contact> existingList = mapoAccountWithContacts.get(eachContact.AccountID);
        existingList.add(eachContact);
    mapoAccountWithContacts.put(existingList);
   }else{
      List<Contact> newList = new List<Contact>();
newList.add(eachContact);
mapoAccountWithContacts.put(newList)
   }  


And then get list of each account and check the size of the list. You will get number of active contacts related to account.

Thanks,
Vishal

 
Synthia BeauvaisSynthia Beauvais
Hi Vishal!!

Forgive me I am still learning Apex. I created  two fields on the account object (Number_of_Contacts__c & Number_of_Active_Contacts__c). 
The triggers in my intial post updates the total number of contacts on the Number_of_Contacts__c  field. 

And I would like for the Number_of_Active_Contacts__c field to pouplate the total number of active contacts only.  The field that determines an inactive contact is a checkbox (Inactive__c​) field. 

Where in your trigger can I incorporate field Number_of_Active_Contacts__c and is your trigger going to be added to my trigger that is on the account object or the contact object? 
 
Map<ID,List<Contacts>> mapoAccountWithContacts  =  new Map<ID,List<Contacts>> ();
List<Contact> listOfContact = new List<Contact>();
listOfContact = [select Id, Name from Contact where Id IN: Trigger.New(id of account from trigger.new ) AND Inactive__c == False];

for(Contact eachContact  : listOfContact ){
   if(mapoAccountWithContacts.containsKey(eachContact.AccountID)){
      List<Contact> existingList = mapoAccountWithContacts.get(eachContact.AccountID);
        existingList.add(eachContact);
    mapoAccountWithContacts.put(existingList);
   }else{
      List<Contact> newList = new List<Contact>();
newList.add(eachContact);
mapoAccountWithContacts.put(newList)
   }
Thanks in advance! 


 
Synthia BeauvaisSynthia Beauvais
This has been resolved!! Here is the updated the trigger on account object.
 
trigger NumberOfContacts on Account (before insert, before update) {
    if(trigger.isinsert)
        for(account a:trigger.new)
            a.Number_of_contacts__c = 0;
    else
        for(account a:[select id,(select id from contacts) from account where id in :trigger.new])
            trigger.newmap.get(a.id).Number_of_contacts__c = a.contacts.size();
            
        for(account b:[select id,(select id from contacts where Inactive__c = False) from account where id in :trigger.new])
            trigger.newmap.get(b.id).Number_of_active_contacts__c = b.contacts.size();
}

Thanks!!
 
This was selected as the best answer
Vishal ShelarVishal Shelar
Good to hear that you solved the error :) 

Thanks