+ Start a Discussion
Carrie Nunemaker 10Carrie Nunemaker 10 

Create a trigger to sum a custom field on the contact and display on the account

I am completely new to Apex and could really use some help with what seems to be a simple task.  I have a formula on the contact, Persona_True__c, that returns a 1 if the custom field "persona" is populated and a 0 if it is blank.

I would like to have a roll-up summary that sums this field at the account level in a field called Related_Personas__c.  

Because we can't roll-up from contact to account I'm reading that this type of action needs to be a trigger, but I don't even know where to start.  Does anyone have any thoughts or expertise they can share to help me out? 
Best Answer chosen by Carrie Nunemaker 10
Anthony McDougaldAnthony McDougald
Good Evening Carrie,
Hope that your day is off to an amazing start. We've constructed a trigger to your specifications. Please test and report back if anything. Hope this helps and may God bless you abundantly.
trigger ContactSumTrigger on Contact (after delete, after insert, after undelete, after update) {

Contact[] cons;
    if (Trigger.isDelete){ 
    cons = Trigger.old;
    }
    else{
    cons = Trigger.new;
    }
Set<ID> acctIds = new Set<ID>();
for (Contact con : cons) {
   acctIds.add(con.AccountId);
}

Map<ID, Contact> contactsForAccounts = new Map<ID, Contact>([SELECT Id, AccountId, Persona_True__c FROM Contact WHERE AccountId IN :acctIds]);

Map<ID, Account> acctsToUpdate = new Map<ID, Account>([SELECT Id, Related_Personas__c FROM Account WHERE Id IN :acctIds]);

for (Account acct : acctsToUpdate.values()) {
Set<Id> conIds = new Set<Id>();
Decimal totalValue = 0;
for (Contact con : contactsForAccounts.values()) {
    if (con.AccountId == acct.Id && con.Persona_True__c != NULL) {
        totalValue += con.Persona_True__c; 
    }
}
acct.Related_Personas__c = totalValue;
}
if(acctsToUpdate.values().size() > 0) {
    update acctsToUpdate.values();
}
}


Best Regards,
Anthony McDougald

All Answers

Anthony McDougaldAnthony McDougald
Good Evening Carrie,
Hope that your day is off to an amazing start. We've constructed a trigger to your specifications. Please test and report back if anything. Hope this helps and may God bless you abundantly.
trigger ContactSumTrigger on Contact (after delete, after insert, after undelete, after update) {

Contact[] cons;
    if (Trigger.isDelete){ 
    cons = Trigger.old;
    }
    else{
    cons = Trigger.new;
    }
Set<ID> acctIds = new Set<ID>();
for (Contact con : cons) {
   acctIds.add(con.AccountId);
}

Map<ID, Contact> contactsForAccounts = new Map<ID, Contact>([SELECT Id, AccountId, Persona_True__c FROM Contact WHERE AccountId IN :acctIds]);

Map<ID, Account> acctsToUpdate = new Map<ID, Account>([SELECT Id, Related_Personas__c FROM Account WHERE Id IN :acctIds]);

for (Account acct : acctsToUpdate.values()) {
Set<Id> conIds = new Set<Id>();
Decimal totalValue = 0;
for (Contact con : contactsForAccounts.values()) {
    if (con.AccountId == acct.Id && con.Persona_True__c != NULL) {
        totalValue += con.Persona_True__c; 
    }
}
acct.Related_Personas__c = totalValue;
}
if(acctsToUpdate.values().size() > 0) {
    update acctsToUpdate.values();
}
}


Best Regards,
Anthony McDougald
This was selected as the best answer
Maharajan CMaharajan C
Hi Carie,

Please wirte the below trigger in Contact Object. This trigger will cover all your scenario's:

Use any one of the below Trigger:

Trigger 1:   Based on Formula Field  ==> Persona_True__c we are  calculating the Related Persona's in Account

trigger ContactTrigger on Contact (after insert, after update, after delete, after undelete) {
     
    Set<Id> accountIds = new Set<Id>();
    Map<Id,Decimal> mapChildTotalAmount = new Map<Id,Decimal>();
    List<Account> accounttoUpdate = new List<Account>();
     
    if(trigger.isInsert || trigger.isUpdate || trigger.isUndelete){
        for(Contact con:trigger.new){
            if(con.AccountId != null){
                accountIds.add(con.AccountId);
            }
        }
    }
     
    if(trigger.isUpdate || trigger.isDelete){
        for(Contact con:trigger.old){
            if(con.AccountId != null){
                accountIds.add(con.AccountId);
            }
        }
    }
     
    if(!accountIds.isEmpty()){
        
        for(AggregateResult agg: [Select AccountId accId, SUM(Persona_True__c) from Contact where AccountId IN : accountIds group by AccountId ]){
            mapChildTotalAmount.put((Id)agg.get('accId'),(Decimal)agg.get('expr0'));
        }
        
        for( Account acc : [Select Id, Related_Personas__c from Account where Id IN :accountIds])
        {
            Decimal totalPersona = mapChildTotalAmount.get(acc.Id);
            acc.Related_Personas__c = totalPersona ;
            accounttoUpdate.add(acc);
        }
    }
    
    if(!accounttoUpdate.IsEmpty())
        {
            update accounttoUpdate;
        }
}



========================   OR  =======================


Trigger 2 : Without using the Formula Field. So no need to create the Formula Field. we can use the below trigger directly with the help of persona__c custom field to calculate the related persona's in Account.

trigger ContactTrigger on Contact (after insert, after update, after delete, after undelete) {
     
    Set<Id> accountIds = new Set<Id>();
    Map<Id,Decimal> mapChildTotalAmount = new Map<Id,Decimal>();
    List<Account> accounttoUpdate = new List<Account>();
     
    if(trigger.isInsert || trigger.isUpdate || trigger.isUndelete){
        for(Contact con:trigger.new){
            if(con.AccountId != null){
                accountIds.add(con.AccountId);
            }
        }
    }
     
    if(trigger.isUpdate || trigger.isDelete){
        for(Contact con:trigger.old){
            if(con.AccountId != null){
                accountIds.add(con.AccountId);
            }
        }
    }
     
    if(!accountIds.isEmpty()){
        
        for(AggregateResult agg: [Select AccountId accId, Count(Id) from Contact where AccountId IN : accountIds AND persona__c!=null group by AccountId ]){
            mapChildTotalAmount.put((Id)agg.get('accId'),(Decimal)agg.get('expr0'));
        }
        
        for( Account acc : [Select Id, Related_Personas__c from Account where Id IN :accountIds])
        {
            Decimal totalPersona = mapChildTotalAmount.get(acc.Id);
            acc.Related_Personas__c = totalPersona ;
            accounttoUpdate.add(acc);
        }
    }
    
    if(!accounttoUpdate.IsEmpty())
        {
            update accounttoUpdate;
        }
}
 
 

Thanks,
Maharajan.C
Carrie Nunemaker 10Carrie Nunemaker 10
This worked perfectly!! Thank you both! 
Carrie Nunemaker 10Carrie Nunemaker 10
@Anthony McDougald - do you happen to have a test class that could get me past the code coverage error?
Anthony McDougaldAnthony McDougald
Good Morning Carrie,
Hope that your day is off to an amazing start. Below is a test class that you can use to get code coverage. Please test and feel free to report back if you have any questions or problems. Hope this helps and may God bless you abundantly.
@isTest
public class ContactSumTriggerTest {
    testmethod static void sumFields(){
        Account a = new Account(
        Name ='testAccount'
        );
        insert a;
        Contact c = new Contact(
        FirstName = 'test',
        LastName = 'contact',
        AccountId = a.Id,
        Persona_True__c= 0 
        );
        insert c;
        
        test.startTest();
        System.debug('Persona initial value is: ' + c.Persona_True__c);
        c.Persona_True__c = 1;
        update c;
        System.debug('Persona new value is: ' + c.Persona_True__c);
        System.debug('Account\'s Persona value is: ' + 
                     [SELECT Id, Related_Personas__c FROM Account WHERE Id IN :a.Id]);
        test.stopTest();
        
    }
    
}
Best Regards,
Anthony McDougald
 
Carrie Nunemaker 10Carrie Nunemaker 10
Thank you, thank you! 100% coverage.  I really appreciate the help. I've decided it's time to learn this side of the system after this experience. lol
Marco GasserMarco Gasser
We have a direct provider of fresh cut bank instrument for lease/sale, such as BG,SBLC, MTN, Bank Bonds,specifically for lease. If you are a potential Investor or Principle looking to raise capital, we will be happy to answer any questions that you have about this opportunity and to provide you with all the details regarding this services.

Regards
 
Marco Gasser

AA Group Financial Consulting AG

Email: MarcoGasser@Consultant.com

Email: marcoga@naver.com
Mister LeeMister Lee
Thanks For Posting. Thats what actually i need (https://wofcheatsanswer.com)
manpreet Singh 193manpreet Singh 193
Teji Infotech is an awarded Digital marketing company in Patiala (https://tejiinfotech.com) We are able to build attractive websites that help in boosting sales and conversations. we Are also institute in Patiala who provides Digital marketing course in Patiala (https://tejiinfotech.com/digital-marketing-course-in-patiala)
Noah MillerNoah Miller
Thank you so much for sharing this valuable information. You can also check out my blog. (https://thereviewhawk.com/)
Luke StocksLuke Stocks
This worked perfectly!! Thank you both! Buy Puppies Online (https://onebarkplaza.com)
Luke StocksLuke Stocks
Thank you so much for sharing this valuable information. Cat Collars (https://www.zacalcatcollars.co.uk/)