1

I just want to remove the inner for loop from the below code using

map<id,list<contact>();

My scenario is:

Contact object have field called Gender of picklist type which contains male and female values. Account (parent of Contact) has two fields called No_Of_Males__c and No_Of_Females__c of type number.

If we add contact on related account and choose male or female value then the No_Of_Males__c or No_Of_Females__c value should be incremented respectively on account object.

CODE SNIPPET:

trigger ContactSumTrigger on Contact (after delete, after insert, after undelete, after update) {
  set<Id> accIds = new set<Id>();    
    if(trigger.IsInsert || trigger.IsUpdate || trigger.IsUndelete){
        for(Contact con : trigger.new){
            if(con.AccountId!=null){
                accIds.add(con.AccountId);
            }
        }
    }

    if(trigger.IsDelete || trigger.IsUpdate){
        for(Contact con : trigger.old){
            accIds.add(con.AccountId);
        }
    }

    Map<Id,List<Contact>> mapConList = new map<Id,List<Contact>>();

    if(accIds.size()>0){
        list<Account> accList = new list<Account>([SELECT Id,No_Of_Males__c,No_Of_Females__c,(SELECT Id,Gender__c FROM Contacts) FROM Account WHERE ID In: accIds]);
        if(accList.size()>0){
            for(Account acc : accList ){
                acc.No_Of_Males__c = 0;
                acc.No_Of_Females__c = 0;
                if(acc.Contacts.size()>0){
                   for(Contact con : acc.Contacts){                  
                        if(acc.contacts.Gender__c !=null){
                            if(acc.contacts.Gender__c=='Male'){
                                acc.No_Of_Males__c+=1;
                            }
                            if(acc.contacts.Gender__c=='Female'){
                                acc.No_Of_Females__c+=1;
                            }
                        }
                    }
                }
            }
            update accList;
        }
    }




}   

1 Answer 1

3

May need a bit of work but use of an aggregate query may be helpful:

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

    set<Id> accIds = new set<Id>();
    for (Contact con : trigger.isDelete ? trigger.old : trigger.new) {
        if (con.AccountId != null) {
            accIds.add(con.AccountId);
        }
    }

    Map<ID, Integer[]> accMap = New Map<Id, Integer[]>();

    for (AggregateResult ar : [
            Select
                    AccountId,
                    Count(Id)num,
                    Gender__c
            From Contact
            Where AccountId IN:accIds
            Group BY AccountId, Gender__c
    ]) {

        Integer[] vals = accMap.get((Id) ar.get('AccountId'));
        if (vals == null) vals = New Integer[]{0, 0};

        if ((String) ar.get('Gender__c') == 'Male') {
            vals[0] = (Decimal) ar.get('num');
        } else if ((String) ar.get('Gender__c') == 'Female') {
            vals[1] = (Decimal) ar.get('num');
        }
        accMap.put((Id) ar.get('AccountId'), vals);
    }


    Account[] accList = New Account[]{};

    for (Contact c : trigger.new) {
        Account tmp = New Account(
                Id = c.AccountId,
                No_Of_Males__c = 0,
                No_Of_Females__c = 0
        );

        if (accMap.containsKey(c.AccountId)) {
            Integer[] v = accMap.get(c.AccountId);
            tmp.No_Of_Males__c = v[0];
            tmp.No_Of_Females__c = v[1];
        }

        accList.add(tmp);

    }


    update accList;


}   

Basically Getting an aggregate grouped by AccountId and Gender using a Count of the Contact Id to count the number of that gender. Then populating a map of AccountId to integer[] the index 0 = males and index 1 = females.

In the end create an account populating the Id and the default 0 values, then grabbing the counts from the Integer map to populate.

1
  • This is definitely a better approach than incrementing count when contact is added (or deleted) as is always more accurate & up to date.
    – crmprogdev
    Commented Mar 18, 2017 at 15:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .