+ Start a Discussion
Ramon AustriaRamon Austria 

Apex Trigger to auto-update standard Account lookup field from custom Contact lookup field (on Opportunity object)

Hello everyone,

I'm configuring Salesforce for a non-profit and I'm using Salesforce enterprise with the Non-Profit Starter Pack. We're linking our opportunities object to both contacts and accounts/households and we want our users to be able to, when filling up the opportunity form, select the contact that made the donation from a custom contact lookup field (Contact_Name__c) and upon creating the record the standard Account lookup field will be filled up with this contact's account/household name automatically. This way our users won't have to manually fill in both the contact and account fields for every opportunity record they wish to create.

This is the current trigger iteration I'm using:

trigger UpdateRegistrationHousehold on Opportunity (before insert, before update) 
{   
    for (Opportunity a:trigger.new)
    {
        if(a.recordtypeID == '012o0000000NnqM')   
        {a.Account.Name = a.Contact_Name__r.Account.Name;}
    }    
}

We want to implement this functionality only on a particular opportunity record type.

This particular code structure has worked for me when updating other fields prior to this, but for this specific issue it's been yielding errors and driving me nuts. I've been tweaking this bit of code a bit and depending on my tweaks, 1 of two things seems to happen: either the Account field remains unpopulated, or the form doesn't save and I get this error: Error:Apex trigger UpdateRegistrationHousehold caused an unexpected exception, contact your administrator: UpdateRegistrationHousehold: execution of BeforeUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.UpdateRegistrationHousehold: line 6, column 1

I have limited coding knowledge so I'm looking forward to hearing from you guys and learning more in the process! Cheers! :)



 
Best Answer chosen by Ramon Austria
gokul bharatigokul bharati
Hi Ramon,

Please find the code which will help you in acheiving your requirement.

trigger CreateOpportunitywithouAccount on Opportunity (before insert,before update) {
Set<Id> ContactId=new Set<Id>();
Map<Id,Id> ContactIdAccountID=new Map<Id,Id>();
    for(Opportunity a:Trigger.New){
     ContactID.add(a.Contact__c);
    }
    for(Contact c:[select id,AccountId from Contact where id in:ContactID]){
    ContactIdAccountID.put(c.id,c.AccountId);
    }
    for(Opportunity a:Trigger.New){
        if(ContactIdAccountID.keySet().contains(a.contact__c)){
           a.AccountId=ContactIdAccountID.get(a.contact__c);
        }
    }
}

All Answers

Sagar PareekSagar Pareek
Try using after insert and after update events in place of before insert and before update.
Ramon AustriaRamon Austria
Hi Sagar,

Thanks for the quick response! I tried what you did, but it's still not working. This is the error message that pops up when I try to create an opportunity now:

Apex trigger UpdateRegistrationHousehold caused an unexpected exception, contact your administrator: UpdateRegistrationHousehold: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.UpdateRegistrationHousehold: line 6, column 1
Sagar PareekSagar Pareek
Got it ! 

The problem is that you are iterating over the Trigger.new that is new copy of the record. As the record is not committed to database when the trigger fires which is making it to show null exception error. You need to first query the related contact then take the account and assign it to the opportunity's account .
Ramon AustriaRamon Austria
Hi Sagar,

Great! If it's not too much of an inconvenience, could you show me a sample bit of code for how to do exactly that (query the related contact then take the account and assign it to the opportunity's account)? I'm still learning my way around Apex and coding in general so I would appreciate the help. 

Thanks again!
gokul bharatigokul bharati
Hi Ramon,

Please find the code which will help you in acheiving your requirement.

trigger CreateOpportunitywithouAccount on Opportunity (before insert,before update) {
Set<Id> ContactId=new Set<Id>();
Map<Id,Id> ContactIdAccountID=new Map<Id,Id>();
    for(Opportunity a:Trigger.New){
     ContactID.add(a.Contact__c);
    }
    for(Contact c:[select id,AccountId from Contact where id in:ContactID]){
    ContactIdAccountID.put(c.id,c.AccountId);
    }
    for(Opportunity a:Trigger.New){
        if(ContactIdAccountID.keySet().contains(a.contact__c)){
           a.AccountId=ContactIdAccountID.get(a.contact__c);
        }
    }
}
This was selected as the best answer
Ramon AustriaRamon Austria
Hi Gokul,

Thanks! That did the trick! :) Thanks to you and Sagar for the help, i really appreciate it. Cheers! :)
Tanvi KakkarTanvi Kakkar
hi 
I am new to  Apex triggers , Can you plz explain the logic behind why do u need to Query and how to Query the records . Even I did not understand : 
(query the related contact then take the account and assign it to the opportunity's account)?

I also have a requirement like : when contact is saved account and opportunity are automatically updated . 
Please Help . ?
suvarna Reddysuvarna Reddy
Account custom lookup filed(user) is updated automatically child opportunity updated
suvarna Reddysuvarna Reddy
trigger UpdateChildWithParent on Account (after insert,after update) {
    if(trigger.isInsert || trigger.isUpdate){
        List<Account> listAccount = new List<Account>();
        Set<Id> UpdatedAccountIds = new Set<Id>(); 
        for(Account acc : Trigger.new) {   
            UpdatedAccountIds.add(acc.RecordTypeId);
        }
        System.debug('UpdatedAccountIds'+UpdatedAccountIds);
        Map<ID, Account> mapAccounts = new Map<ID, Account>([SELECT Id, Status__c,name
                                                             FROM Account 
                                                             WHERE Id IN :UpdatedAccountIds]); 
        Map<Id, RecordType> recordTypeMap = new Map<Id, RecordType>([SELECT DeveloperName 
                                                                     FROM RecordType 
                                                                     WHERE Id IN :UpdatedAccountIds]);
        System.debug('recordTypeMap'+recordTypeMap);       
        for(Account accList: Trigger.new) {
            RecordType optyRecordType = recordTypeMap.get(accList.RecordTypeId);       
            if(optyRecordType != null) {            
                if(optyRecordType.DeveloperName == 'Brand') {   
                    listAccount.add(accList);
                } else  if(optyRecordType.DeveloperName  == 'Merch Owner') {
                    listAccount.add(accList);
                }
            }
        }    
        for(Account accObj:Trigger.new){
            UpdatedAccountIds.add(accObj.ParentId);        
            System.debug('Id>>>>>>>'+accObj.Id);
            System.debug('ParentId>>>>>>>'+accObj.ParentId);
            System.debug('Chid Account Name>>>>>>>'+accObj.Name);   
        }               
       List<Account> UpdateAcc = [SELECT ID,Name,Status__c,AccountManager__c 
                                   FROM Account 
                                    WHERE Id IN: UpdatedAccountIds];
       System.debug('>>>UpdateAcc>>>>'+UpdateAcc);
        List<Account> listAccount1=new List<Account>();
        for(Account accObj1:UpdateAcc){
            for(Account accObj2:listAccount){
                    //accObj1.Status__c=accObj2.Status__c;
                accObj1.AccountManager__c=accObj2.AccountManager__c;
                listAccount1.add(accObj1);
            }
        }  
        update listAccount1;    
        System.debug('>>>listAccount1>>>>'+listAccount1);
        
        Map<ID, Account> mapAccount = new Map<ID, Account>([SELECT Id, AccountManager__c 
                                                            FROM Account 
                                                            WHERE Id IN :UpdatedAccountIds]);
        System.debug('>>>mapAccount>>'+mapAccount);
        List<Opportunity> oppLst=new List<Opportunity>([SELECT Id, AccountManager__c 
                                                        FROM Opportunity 
                                                        WHERE Id IN :UpdatedAccountIds]);
        System.debug('>>>oppLst>>'+oppLst);
        List<Account> lstAccToUpdate = new List<Account>();
        System.debug('>>lstAccToUpdate>>>'+lstAccToUpdate);
        For(Opportunity opp : oppLst)  {
            System.debug('>>>opp>>'+opp);
            Account acc = mapAccount.get(opp.AccountId);
            System.debug('>>>acc>>'+acc);
           // acc.Status__c=opp.Status__c;    
            acc.AccountManager__c = opp.AccountManager__c;
            lstAccToUpdate.add(acc);          
        }
        update lstAccToUpdate;
          System.debug('>lstAccToUpdate>>>>'+lstAccToUpdate);
        
        Map<Id, Account> mapUpdatedAccounts = new Map<Id,Account>();
        For(Account acc : lstAccToUpdate){
            mapUpdatedAccounts.put(acc.Id,acc);
            System.debug('mapUpdatedAccounts'+mapUpdatedAccounts);
        }
    }
}