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 

Update Opportunity with Lookup Field Value from Account

Hello,

I think I'm trying to do something pretty simple, but I am getting an error.  My trigger below is meant to fire when an Opportunity is updated.  All it's supposed to do is pull the value from 1 of 2 custom fields (Consultant_Partner_Primary__c and Consultant_Partner_Secondary__c) at the associated Account based on the value the user enters in a picklist field (Consultant_Type__c) on the Opportunity.  When I try to update an Opportunity, I get the following error:

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger UpdateConsultOpp caused an unexpected exception, contact your administrator: UpdateConsultOpp: execution of AfterUpdate caused by: System.FinalException: Record is read-only: Trigger.UpdateConsultOpp: line 7, column 1



Can anyone help why I am getting this error?  Thanks,


trigger UpdateConsultOpp on Opportunity (after Insert, after Update) {

    // Update Consultant Partner field with value from Account
    FOR(Opportunity o : Trigger.New){
       
        IF(o.Consultant_Type__c == 'Primary Consultant'){
            o.Consultant_Partner__c = o.Account.Consultant_Partner_Primary__c;
        }
       
        ELSE IF(o.Consultant_Type__c == 'Secondary Consultant'){
            o.Consultant_Partner__c = o.Account.Consultant_Partner_Secondary__c;
        }

}

}


Best Answer chosen by JN22
JN22JN22
For anyone interested, I got my trigger to work with the code below:

trigger UpdateConsultOpp on Opportunity (before insert, before update) {  
    Set<ID> setOppIds = new Set<ID>();
    for(Opportunity opp:Trigger.new){
        setOppIds.add(opp.Id);
    }
    Map<ID, Opportunity> mapAcc = new Map<ID, Opportunity>([Select Id, Account.Consultant_Partner_Primary__c, Account.Consultant_Partner_Secondary__c, Consultant_Type__c
                                                            FROM Opportunity
                                                            WHERE Id in:setOppIds]);
    if(mapAcc.size()>0){
        for(Opportunity opp:Trigger.New){
            IF(mapAcc.containsKey(opp.Id) && opp.Consultant_Type__c == 'Primary Consultant'){
                opp.Consultant_Partner__c = mapAcc.get(opp.Id).Account.Consultant_Partner_Primary__c;
            }
            ELSE IF(mapAcc.containsKey(opp.Id) && opp.Consultant_Type__c == 'Secondary Consultant'){
                opp.Consultant_Partner__c = mapAcc.get(opp.Id).Account.Consultant_Partner_Secondary__c;
            }
        }
    }
}

All Answers

Florian HoehnFlorian Hoehn
Hi JN22,

You want to update the opportunity that has been inserted or updated so you need to do this 'before insert' and 'before update'.

In the 'after insert/update' event you cannot change the actual opportunity itself.

This should solve your issue.

Florian
JN22JN22
Hi Florian,

Thanks.  That gets rid of the error, but nothing gets updated.  Any idea why nothing is happening?  Thanks.
Florian HoehnFlorian Hoehn
Other than that the code does look ok to me. Debug and I am sure you will find out that some value is not exacty as you expect it.
JN22JN22
I ran some debug statements and it appears as though I am getting a value of null from the variable o.Account.Consultant_Partner_Primary__c.  This is a value I'm trying to pull from a custom lookup field on the Account associated with the Opportunity being edited.  Any thought?
Florian HoehnFlorian Hoehn
Ah, this is probably not automatically selected via the trigger. In the trigger.new lists and maps not all fields are being selected especially not if it is a field on another record.

So you would have to select these fields specifically (tip: think bulk) - Does that make sense?

I don't have an exact picture if a formula field is possible but definitely have a look into it if you didn't do that already.
JN22JN22
For anyone interested, I got my trigger to work with the code below:

trigger UpdateConsultOpp on Opportunity (before insert, before update) {  
    Set<ID> setOppIds = new Set<ID>();
    for(Opportunity opp:Trigger.new){
        setOppIds.add(opp.Id);
    }
    Map<ID, Opportunity> mapAcc = new Map<ID, Opportunity>([Select Id, Account.Consultant_Partner_Primary__c, Account.Consultant_Partner_Secondary__c, Consultant_Type__c
                                                            FROM Opportunity
                                                            WHERE Id in:setOppIds]);
    if(mapAcc.size()>0){
        for(Opportunity opp:Trigger.New){
            IF(mapAcc.containsKey(opp.Id) && opp.Consultant_Type__c == 'Primary Consultant'){
                opp.Consultant_Partner__c = mapAcc.get(opp.Id).Account.Consultant_Partner_Primary__c;
            }
            ELSE IF(mapAcc.containsKey(opp.Id) && opp.Consultant_Type__c == 'Secondary Consultant'){
                opp.Consultant_Partner__c = mapAcc.get(opp.Id).Account.Consultant_Partner_Secondary__c;
            }
        }
    }
}
This was selected as the best answer