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
Chinna99Chinna99 

Error on Opportunity Trigger After insert on Owner Update from Account - Help needed..

HI.. I need quick help ....

Error Message :

Review all error messages below to correct your data.
Apex trigger OpportunityTrigger caused an unexpected exception, contact your administrator: OpportunityTrigger: execution of AfterInsert caused by: System.FinalException: Record is read-only: Class.OpportunityTriggerHandler.OnBeforeInsert: line 47, column 1


Apex trigger :
trigger OpportunityTrigger on Opportunity (After Insert,After update) {

OpportunityTriggerHandler.onAfterInsertUpdate(trigger.newmap,trigger.oldmap);
OpportunityTriggerHandler.onBeforeInsert(trigger.new);
}

Apex class :
public with sharing class OpportunityTriggerHandler {

    public OpportunityTriggerHandler(){
    
    }
    
    public static void onAfterInsertUpdate(map<ID,Opportunity> newmap,map<ID,Opportunity> oldmap)
    {
        set<ID> accIDs = new set<ID>();
        for(Opportunity oppObj : newmap.values()){
            if(oppObj.AccountID != null){
                accIDs.add(oppObj.AccountID);
            }
        }
        map<ID,Account> accountMap = new map<ID,Account>([SELECT ID,OwnerID FROM Account WHERE ID IN: accIDs]);
        map<ID,String> oppTeam = new map<ID,String>();
        map<ID,String> oppTeamRole = new map<ID,String>(); 
                  
       for(Opportunity oppObj2 : newmap.values()){
            if(oppObj2.AccountID != null && accountMap.containsKey(oppObj2.AccountID) && accountMap.get(oppObj2.AccountID).OwnerID != oppObj2.OwnerID){
                    oppTeam.put(accountMap.get(oppObj2.AccountID).OwnerID,oppObj2.ID);
                    oppTeamRole.put(oppObj2.ID,'Account Manager'); 
            }
        }                   
        addAccountTeamMember.addOpportunityTeamMembers(oppTeam,oppTeamRole); 
                  
    }
    
       
    public static void OnBeforeInsert(List<Opportunity> newRecords){
     set<ID> accIDs = new set<ID>();
     set<ID> conIDs = new set<ID>();     
        for(Opportunity oppObj : newRecords){
            if(oppObj.AccountID != null){
                accIDs.add(oppObj.AccountID);
            }
            if(oppObj.Primary_Contact__c != null){
                conIDs.add(oppObj.Primary_Contact__c);
            }                                    
        }
        map<ID,Account> accountMap = new map<ID,Account>([SELECT ID,OwnerID FROM Account WHERE ID IN: accIDs]);
        map<ID,Contact> contactMap = new map<ID,Contact>([SELECT ID,OwnerID FROM Contact WHERE ID IN: conIDs]);

        for(Opportunity oppObj2 : newRecords)
        {
            if(oppObj2.AccountID != null && accountMap.containsKey(oppObj2.AccountID) && accountMap.get(oppObj2.AccountID).OwnerID != null){
                oppObj2.OwnerID = accountMap.get(oppObj2.AccountID).OwnerID;
            }
            // add field in both query and here
            if(oppObj2.Primary_Contact__c != null && contactMap.containsKey(oppObj2.Primary_Contact__c)){
                //oppObj2.Expense_Planning__c = contactMap .get(oppObj2.Primary_Contact__c).Expense_Planning__c;
            }
                          
                        
            
        }        
    }
 
Rohit Sharma 66Rohit Sharma 66
In your OnBeforeInsert method at line 47 u r updating the original object field in trigger.new which is not allowed for After insert and after update trigger. See following document:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables_considerations.htm

Also, please add the following condition in your trigger:
If(tigger.isBefore && trigger.isInsert)
If(tigger.isAfter && trigger.isInsert)

Else your both methods will run on each condition whether u insert or update the record.

Please let me know if this helps.