0

I am trying to display total related accounts in contact detail records page where Account object configured as 'Contacts to Multiple Accounts'. I created below trigger in contact that displays total accounts but is not working as intended. Once I add account to contact the page gets refreshed but the total account value does not get reflected until I edit the contact and save it. I would like to have total account value updated after I add account to contact.

trigger totalAccounts on Contact (before insert, before update) {   
    for(Contact c : Trigger.New) {
       Integer totalAcct = [SELECT count() FROM AccountContactRelation WHERE ContactId =:c.id];

         if (c.Total_Accounts__c ==NULL) {

             c.Total_Accounts__c = 1;
         } else {
             c.Total_Accounts__c = totalAcct;
         }

    }    
}

/* Suggested Code */

public class CountTotalAccountHandler {

public static void countTotalNumberOfAccount(set<id> contactIdSet) {
    Map<Id, Integer> cntIdvsTotalAccount = new Map<Id, Integer>();
    List<contact> contactUpdateList = new List<contact>();
    for(AggregateResult arObj: [SELECT count(Id) total,
                                       ContactId 
                                FROM AccountContactRelation 
                                WHERE ContactId IN: contactIdSet
                                GROUP BY ContactId]){
        cntIdvsTotalAccount.put((Id)arObj.get('ContactId'),(Integer)arObj.get('total'));
    }

    for(Contact cntObj: [SELECT Id,Total_Accounts__c FROM Contact Where Id IN: contactIdSet]) {
        if(cntIdvsTotalAccount.containsKey(cntObj)) {
            cntObj.Total_Accounts__c = cntIdvsTotalAccount.get(cntObj);
        } else {
            cntObj.Total_Accounts__c = 0;
        }
        contactUpdateList.add(cntObj);
    }

    update contactUpdateList;
}


}

/* Trigger code */

trigger countTotalNoAccount on Contact(after delete,after update, after insert, after undelete)  
    {

        CountTotalAccountHandler handler = new CountTotalAccountHandler();

        handler.countTotalNumberOfAccount(Trigger.new);

    }
  • You'll need to handle this on delete event as well. And also on account trigger as well when an account is deleted the associated contact should be updated with the latest count. 1 more thing in above code you should remove that query from for loop. – RCS Apr 13 '18 at 5:11
  • There code needs to be reworked in a better way. You are running this code on before insert. There are no AccountContactRelation records created while the contact is getting inserted, so no value is populated. During update, it works because the AccountContactRelationship already exist. Also, i see you are using SOQL inside for loop, which is not the right way. – the_phantom Apr 13 '18 at 5:14
0

Update the trigger to handle all the events after delete,after update, after insert, after undelete and from every trigger instance call the handler method and pass the contactIdSet. In case of delete you can create idSet from trigger.old values.

Create a handler class and use below method to countTotalNoAccount on Contact

public static void countTotalNumberOfAccount(set<id> contactIdSet) {
    Map<Id, Integer> cntIdvsTotalAccount = new Map<Id, Integer>();
    List<contact> contactUpdateList = new List<contact>();
    for(AggregateResult arObj: [SELECT count(Id) total,
                                       ContactId 
                                FROM AccountContactRelation 
                                WHERE ContactId IN: contactIdSet
                                GROUP BY ContactId]){
        cntIdvsTotalAccount.put((Id)arObj.get('ContactId'),(Integer)arObj.get('total'));
    }

    for(Contact cntObj: [SELECT Id,Total_Accounts__c FROM Contact Where Id IN: contactIdSet]) {
        if(cntIdvsTotalAccount.containsKey(cntObj)) {
            cntObj.Total_Accounts__c = cntIdvsTotalAccount.get(cntObj);
        } else {
            cntObj.Total_Accounts__c = 0;
        }
        contactUpdateList.add(cntObj);
    }

    update contactUpdateList;
}

Similarly the on the Account trigger as well you'll need write the same code if the account record is deleted or undeleted

  • So, I am kind of new on triggers and Apex, do I create a class with above method and invoke method within trigger? – I. Lami Apr 13 '18 at 6:08
  • Yes create a handler class and call the handler method from trigger – RCS Apr 13 '18 at 6:13
  • I am getting this error: Error: Compile Error: Method does not exist or incorrect signature: void containsKey(Contact) from the type Map<Id,Integer> at line 15 column 32 when I try to save the handler class: public class CountTotalAccountHandler { //Inserted the above method in this class } – I. Lami Apr 13 '18 at 7:01
  • Can you please add you code under the question what you tried – RCS Apr 13 '18 at 9:36
  • I just added the code under the question. Both class and trigger. – I. Lami Apr 13 '18 at 17:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.