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
JN22JN22 

Account Field to Opportunity Records

Hello,

I have a trigger (below) that is meant to take the value from a custom field on the Account object and copy it to a custom field on related Opportunities that are not closed won or closed lost, but only when the value in the Account field changes.  The trigger saves without any errors, but the value does not write over to the Opportunity.  Can anyone help me figure out why the value is not pulling through?  Thanks,


trigger UpdateConsultant on Account (after update){
       
List<Account> acct = new List<Account>();

FOR(Account a : Trigger.new){

// Query Opportunity records realted to Account that is being created/edited
    List<Opportunity> opps = [SELECT AccountId, IsWon, IsClosed, Consultant_Partner__c, Consultant_Type__c
                              FROM Opportunity
                              WHERE AccountId IN: Trigger.newMap.keySet()];
       
        // Iterating through all the Opportunity records and updating them as per the conditions
        for(Opportunity opps2 :opps){

            // Update Consultant Partner field on Opportunity if Opp is Open and Consultant field changes at Account level
            IF(opps2.IsWon == FALSE && opps2.IsClosed == FALSE && opps2.Consultant_Type__c == 'Primary Consultant' && trigger.NewMap.get(opps2.AccountId).Consultant_Partner_Primary__c != trigger.OldMap.get(opps2.AccountId).Consultant_Partner_Primary__c){
                opps2.Consultant_Partner__c = a.Consultant_Partner_Primary__c;
            }
           
            ELSE IF(opps2.IsWon == FALSE && opps2.IsClosed == FALSE && opps2.Consultant_Type__c == 'Secondary Consultant' && trigger.NewMap.get(opps2.AccountId).Consultant_Partner_Secondary__c != trigger.OldMap.get(opps2.AccountId).Consultant_Partner_Secondary__c){
                opps2.Consultant_Partner__c = a.Consultant_Partner_Secondary__c;
            }
        }
       
        // Update all realted Opportunity records
//        IF(opps.size() > 0)
            update opps;
}
}
Best Answer chosen by JN22
willardwillard
To tell you the truth - I think your code should work as is based on how I understand how a list of sobjects work, but I'd improve this code with two tweaks:
  1. Only update those opps that need to be updated and
  2. Bulkify your trigger
Like so.  My comments are prepended with XXX:
<pre>
trigger UpdateConsultant on Account (after update){

    List<Account> acct = new List<Account>();

    // XXX: add oppsToUpdate list
    Opportunity[] oppsToUpdate = new List<Opportunity>();
    FOR(Account a : Trigger.new){

        // Query Opportunity records realted to Account that is being created/edited
        List<Opportunity> opps = [SELECT AccountId, IsWon, IsClosed, Consultant_Partner__c, Consultant_Type__c
        FROM Opportunity
        WHERE AccountId IN: Trigger.newMap.keySet()];

        // Iterating through all the Opportunity records and updating them as per the conditions
        for(Opportunity opps2 :opps){

            // Update Consultant Partner field on Opportunity if Opp is Open and Consultant field changes at Account level
            IF(opps2.IsWon == FALSE && opps2.IsClosed == FALSE && opps2.Consultant_Type__c == 'Primary Consultant' && trigger.NewMap.get(opps2.AccountId).Consultant_Partner_Primary__c != trigger.OldMap.get(opps2.AccountId).Consultant_Partner_Primary__c){
                opps2.Consultant_Partner__c = a.Consultant_Partner_Primary__c;
                oppsToUpdate.add(opps2); // XXX: add to list if there is a change
            }

            ELSE IF(opps2.IsWon == FALSE && opps2.IsClosed == FALSE && opps2.Consultant_Type__c == 'Secondary Consultant' && trigger.NewMap.get(opps2.AccountId).Consultant_Partner_Secondary__c != trigger.OldMap.get(opps2.AccountId).Consultant_Partner_Secondary__c){
                opps2.Consultant_Partner__c = a.Consultant_Partner_Secondary__c;
                oppsToUpdate.add(opps2); // XXX: add to list if there is a change
            }
        }

        // XXX: Move this outside of the account loop to make it bulk-safe
        // update opps; 
    }
    update oppsToUpdate; // XXX: do update here instead to make bulk-safe
}
</pre>

All Answers

willardwillard
To tell you the truth - I think your code should work as is based on how I understand how a list of sobjects work, but I'd improve this code with two tweaks:
  1. Only update those opps that need to be updated and
  2. Bulkify your trigger
Like so.  My comments are prepended with XXX:
<pre>
trigger UpdateConsultant on Account (after update){

    List<Account> acct = new List<Account>();

    // XXX: add oppsToUpdate list
    Opportunity[] oppsToUpdate = new List<Opportunity>();
    FOR(Account a : Trigger.new){

        // Query Opportunity records realted to Account that is being created/edited
        List<Opportunity> opps = [SELECT AccountId, IsWon, IsClosed, Consultant_Partner__c, Consultant_Type__c
        FROM Opportunity
        WHERE AccountId IN: Trigger.newMap.keySet()];

        // Iterating through all the Opportunity records and updating them as per the conditions
        for(Opportunity opps2 :opps){

            // Update Consultant Partner field on Opportunity if Opp is Open and Consultant field changes at Account level
            IF(opps2.IsWon == FALSE && opps2.IsClosed == FALSE && opps2.Consultant_Type__c == 'Primary Consultant' && trigger.NewMap.get(opps2.AccountId).Consultant_Partner_Primary__c != trigger.OldMap.get(opps2.AccountId).Consultant_Partner_Primary__c){
                opps2.Consultant_Partner__c = a.Consultant_Partner_Primary__c;
                oppsToUpdate.add(opps2); // XXX: add to list if there is a change
            }

            ELSE IF(opps2.IsWon == FALSE && opps2.IsClosed == FALSE && opps2.Consultant_Type__c == 'Secondary Consultant' && trigger.NewMap.get(opps2.AccountId).Consultant_Partner_Secondary__c != trigger.OldMap.get(opps2.AccountId).Consultant_Partner_Secondary__c){
                opps2.Consultant_Partner__c = a.Consultant_Partner_Secondary__c;
                oppsToUpdate.add(opps2); // XXX: add to list if there is a change
            }
        }

        // XXX: Move this outside of the account loop to make it bulk-safe
        // update opps; 
    }
    update oppsToUpdate; // XXX: do update here instead to make bulk-safe
}
</pre>
This was selected as the best answer
willardwillard
The above code should also update the opportunities that don't seem to be updating if you update the opps directly within the list returned from the SOQL query.
JN22JN22
Hi Willard,

Thanks so much for the feedback.  Unfortunately, it still is not working.  My fields "Consultant_Partner__c" and "Consultant_Partner_Primary__c" are lookup fields to Account records. Is there perhaps a different format that I need to use to populate them?  I'm stumped. Thanks.
JN22JN22
Nevermind.  I had a line commented our that was preventing anything from being written.  The code below works like a charm!  Thanks for all your assistance!!!

trigger UpdateConsultant on Account (after update){
       
    List<Account> acct = new List<Account>();

    Opportunity[] oppsToUpdate = new List<Opportunity>();  

    FOR(Account a : Trigger.new){

    // Query Opportunity records realted to Account that is being created/edited
    List<Opportunity> opps = [SELECT AccountId, IsWon, IsClosed, Consultant_Partner__c, Consultant_Type__c
                              FROM Opportunity
                              WHERE AccountId IN: Trigger.newMap.keySet()];
       
        // Iterating through all the Opportunity records and updating them as per the conditions
        for(Opportunity opps2 :opps){

            // Update Consultant Partner field on Opportunity if Opp is Open and Consultant field changes at Account level
            IF(opps2.IsWon == FALSE && opps2.IsClosed == FALSE && opps2.Consultant_Type__c == 'Primary Consultant' && trigger.NewMap.get(opps2.AccountId).Consultant_Partner_Primary__c != trigger.OldMap.get(opps2.AccountId).Consultant_Partner_Primary__c){
                opps2.Consultant_Partner__c = a.Consultant_Partner_Primary__c;
                oppsToUpdate.add(opps2);
            }
           
            ELSE IF(opps2.IsWon == FALSE && opps2.IsClosed == FALSE && opps2.Consultant_Type__c == 'Secondary Consultant' && trigger.NewMap.get(opps2.AccountId).Consultant_Partner_Secondary__c != trigger.OldMap.get(opps2.AccountId).Consultant_Partner_Secondary__c){
                opps2.Consultant_Partner__c = a.Consultant_Partner_Secondary__c;
                oppsToUpdate.add(opps2);
            }
        }
       
        // Update all realted Opportunity records
        //IF(opps.size() > 0)
        //   update opps;
    }
    update oppsToUpdate;
}