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
Shahida RobertsonShahida Robertson 

How to Copy Contact Email to Custom Account Field

Hello,
I have created a custom field on the Account object called "Primary Contact Email." I need a trigger that will update this field with the Primary Contact's (lookup on the Account) email. I am not a developer, btw. Right now I have: 

trigger UpdateAccountEmails on Contact (after update) {
    Map<Id, Account> m = new Map<Id, Account>();
    for(Contact c : Trigger.new){
        if (Trigger.oldMap.get(c.Id).Email != c.Email) {
            m.put(c.AccountId, new Account(Id = c.AccountId, Primary_Contact_Email__c = c.Email));
        }
    }
    update m.values();

Can anyone help me? Thanks!
Boss CoffeeBoss Coffee
One thing to take note of is that this functionality (updating a Contact's parent Account field based on an email change) can be done via Process Builder, which is recommended before seeking custom code solutions.

I hope the following code helps in learning Apex and Triggers. Let me know if you have any questions on it!
// Check if the trigger is After and Update
    if(Trigger.isAfter && Trigger.isUpdate) {
        // Create a list for Account Ids
        List<Id> accIds = new List<Id>();
        // Loop through the Contacts from the trigger
        for(Contact c : Trigger.new) {
            // Add each Contact's Parent Account to the list of Account Ids
            accIds.add(c.AccountId);
        }
        
        // Fetch a map holding Accounts that have an Id included in the list of Account Ids we created
        Map<Id,Account> accMap = new Map<Id,Account>([SELECT Id, Primary_Contact_Email__c FROM Account WHERE Id IN :accIds]);
        
        // Create a list for Accounts to update at the end of the method
        List<Account> accountsToUpdate = new List<Account>();
        
        // Create a temporary Account for placeholding during the following for loop
        Account tempAccount;
        // Loop through the Contacts from the trigger again
        for(Contact c : Trigger.new) {
            // Check if the email has changed
            if(Trigger.oldMap.get(c.Id).Email != c.Email) {
                // If the email has changed, fetch the lookup Account for this Contact from the Account map we created and assign to our temporary placeholder Account
                tempAccount = accMap.get(c.AccountId);
                // Update the field for our temporary placeholder Account
                tempAccount.Primary_Contact_Email__c = c.Email;
                // Then add this Account record to the list to be updated
                accountsToUpdate.add(tempAccount);
            }
        }
        
        // If the list of Accounts to be updated has any records in it
        if(accountsToUpdate.size() > 0) {
            // Then update the list of Accounts
            update accountsToUpdate;
        }
    }
Shahida RobertsonShahida Robertson
Thanks so much! The only reason I did not use a process was because I need to update existing accounts without the change. Is that even possible with a trigger or does this act the same way?
Boss CoffeeBoss Coffee
Triggers act in the same way in that they will not act on existing records unless the trigger is fired. In this scenario, even if the trigger is fired, unless the email is changed, then it will not update the Account. Do you need to update all existing Accounts with the Contact email address?
Shahida RobertsonShahida Robertson
Yes, I need to update all Accounts with the Contact email address of the primary contact.
Boss CoffeeBoss Coffee
In that case, I will need a few more details. Does each Account only have one related Contact? I ask because if there are more than one, then I will need to know which Contact's email should be copied to the Account's custom field. Or is there a way to identify which Contact is the Primary Contact?
Shahida RobertsonShahida Robertson
On the contact object there is a checkbox field that udpates to 'True' when the contact (lookup) is entered in the 'Primary contact field.' I've added screenshots just in case I wasn't clear with my wording. Thanks!


User-added imageUser-added image
Boss CoffeeBoss Coffee
Go to Developer Console => Debug dropdown => Open Execute Anonymous Window, then paste the following to fetch all Accounts that have Primary Contact lookup field populated before updating the Primary Contact Email field with the Primary Contact lookup's email.
// Get all Accounts that has Primary Contact lookup field populated
List<Account> accounts = [
    SELECT Id, Primary_Contact__c, Primary_Contact_Email__c, Primary_Contact__r.Email 
    FROM Account
    WHERE Primary_Contact__c != NULL
];

// Loop through each fetched Account to assign the primary Contact's email
for(Account acc : accounts) {
    acc.Primary_Contact_Email__c = acc.Primary_Contact__r.Email;
}

// Update the Accounts
update accounts;
Ajay K DubediAjay K Dubedi
Hi Shahida,

You can use the below code.

I have written a trigger as per your requirement.  

<<<<<----Trigger ---->>>>>
trigger contactTrigger on Contact ( after delete, after insert) {
if(Trigger.isAfter && (Trigger.isinsert || Trigger.isUpdate)){
        PrimaryContactEmail_AccountField.updateContactEmailToAccountField(trigger.new);
    }
}
<<<<<----Apex Class------>>>>>>
public class PrimaryContactEmail_AccountField {

    public static void updateContactEmailToAccountField(List<Contact> contactList){
        
        try{
            Set<Id> accountIds = new Set<Id>();
            List<Account> accountList = new List<Account>();
            if(contactList != NULL){
                for(Contact contactObject : contactList){
                    accountIds.add(contactObject.AccountId);
                }
                accountList = [SELECT Id, Name,Primary_Contact_Email__c     FROM Account WHERE Id IN : accountIds LIMIT 5000];
                for(Account accObject : accountList){
                    if(accObject.Primary_Contact_Email__c == NULL){
                        for(Contact contactObject : contactList){
                            if(contactObject.AccountId == accObject.Id && contactObject.Email != null){
                                accObject.Primary_Contact_Email__c = contactObject.Email;
                            }
                        }
                    }
                }
                if(accountList.size() > 0){
                    Update accountList;
                }
            }
            
        }catch(Exception exp){
            System.debug('Exception Cause-->>'+exp.getMessage()+'Line Number-->>'+exp.getLineNumber());
        }
    }
}
I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks and Regards,
Ajay Dubedi
www.ajaydubedi.com