+ Start a Discussion
John NeilanJohn Neilan 

Trigger Error

Hi Everyone,

I have a custom object (Account_Manager_Handoff__c) with a Mast-Detail relationship to the Opportunity object.  The trigger below is meant to fire when the custom object is created or edited.  In either case, a field on the associated Account (Account_Manager_Handoff_Notes__c) gets updated with some text values from the custom object.  In addition, if another checkbox field (Handoff_Official__c) is marked as TRUE, the Account Owner is supposed to be changed to the person indicated in the Assigned_Account_Manager__c field on the custom object, and the related Opportunity (Opportunity__c) on the custom object is supposed to be cloned.  The trigger saves without errors, but when I try to create a record I get the following error:

MainTriggerAccountManagerHandoff: execution of AfterInsert caused by: System.FinalException: Record is read-only: Class.ClassAccountManagerHandoffNotes.addNotes: line 21, column 1

Does anyone know why I am getting this error and what I need to do to fix it?

Trigger:
 
trigger MainTriggerAccountManagerHandoff on Account_Manager_Handoff__c (after insert,after update) {
    
    IF(trigger.isAfter){
        
        if(trigger.isInsert || trigger.isUpdate){
            
            if(checkAccountManagerHandoffRecursive.runAfterInsertOnce()){
            
                ClassAccountManagerHandoffNotes updater = new ClassAccountManagerHandoffNotes();
                updater.addNotes(Trigger.new);
                
            }                
        }
    }
}

Trigger Class:
public class ClassAccountManagerHandoffNotes {
    
    public void addNotes(List<Account_Manager_Handoff__c> accountManagerHandoffs){
        
        Set<Id> accountsInTrigger = new Set<Id>();
        Map<Id,String> accountMap = new Map<Id,String>();
        Map<Id,Id>accountMap2 = new Map<Id,Id>();
        List<Account> accountsToUpdate = new List<Account>();
        
        FOR(Account_Manager_Handoff__c amh : accountManagerHandoffs){
            IF(amh.AccountLookup__c != NULL){
            
            accountsInTrigger.add(amh.AccountLookup__c);
            String notes = amh.Platform_Experience__c + '\n\n' + amh.Issues_Encountered__c + '\n\n' + amh.Known_Goals__c + '\n\n' + amh.Additional_Notes__c;
            Id owner = amh.Assigned_Account_Manager__c;
            accountMap.put(amh.AccountLookup__c,notes);
            accountMap2.put(amh.AccountLookup__c,owner);


//Clone the Opportunity that is associated with the handoff and all createable fields 
            IF(amh.Handoff_Official__c = TRUE){
                /* query Opportunity and then clone it */
                String soql = RecClone.getCreatableFieldsSOQL('Opportunity','Id =: amh.Opportunity__c.Id');
                    Opportunity opp = (Opportunity)Database.query(soql);
                    Opportunity opp2 = opp.clone(false, true);
                insert opp2;
            }

            }
        }
        
        FOR(Account a : [SELECT Id,Account_Manager_Handoff_Notes__c,OwnerId
                         FROM Account
                         WHERE Id In :accountsInTrigger]){
                             
                            a.Account_Manager_Handoff_Notes__c = accountMap.get(a.Id);

                        FOR(Account_Manager_Handoff__c amh2 : [SELECT Id,Handoff_Official__c
                                                                FROM Account_Manager_Handoff__c
                                                                WHERE Id =: a.Id]){

                            IF(amh2.Handoff_Official__c = TRUE){
                            a.OwnerId = accountMap2.get(a.Id);
                            }
                        }

                        accountsToUpdate.add(a);
                             
                        }
        
        UPDATE accountsToUpdate;        
    }
}

Class for Clone:
//This class is used to clone all the creatable fields on objects for use with Apex cloning.

public with sharing class RecClone{ 
 
    // Returns a dynamic SOQL statement for the whole object, includes only creatable fields since we will be inserting a cloned result of this query
    public static string getCreatableFieldsSOQL(String objectName, String whereClause){
         
        String selects = '';
         
        if (whereClause == null || whereClause == ''){ return null; }
         
        // Get a map of field name and field token
        Map<String, Schema.SObjectField> fMap = Schema.getGlobalDescribe().get(objectName.toLowerCase()).getDescribe().Fields.getMap();
        list<string> selectFields = new list<string>();
         
        if (fMap != null){
            for (Schema.SObjectField ft : fMap.values()){ // loop through all field tokens (ft)
                Schema.DescribeFieldResult fd = ft.getDescribe(); // describe each field (fd)
                if (fd.isCreateable()){ // field is creatable
                    selectFields.add(fd.getName());
                }
            }
        }
        if (!selectFields.isEmpty()){
            for (string s:selectFields){
                selects += s + ',';
            }
            if (selects.endsWith(',')){selects = selects.substring(0,selects.lastIndexOf(','));}
        }
        return 'SELECT ' + selects + ' FROM ' + objectName + ' WHERE ' + whereClause;    
    } 
}

 
Best Answer chosen by John Neilan
Vj@88Vj@88
Try using Conditional operator '=='
IF(amh.Handoff_Official__c == TRUE)

 

All Answers

Vj@88Vj@88
Try using Conditional operator '=='
IF(amh.Handoff_Official__c == TRUE)

 
This was selected as the best answer
John NeilanJohn Neilan
Wow, that would have been a much simpler error message!  That did the trick for getting rid of the error.  Thanks so much!!