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
Darko VukasovicDarko Vukasovic 

Error Message: CreatingTask: execution of AfterInsert caused by: System.FinalException: Record is read-only Trigger.CreatingTask: line 28, column 1

Hi All,

I am just starting to learn to code and I have a small question regarding the code I wrote below. 
My goal is to first calculate the number of fields which are not null(there are 6 fields I am interested in as you can see in the list) and then show that number in the custom Key_Fields_Populated__c  field.
Once I have the Key_Fields_Populated__c filled out with correct number I would also like to create a new Task and link that Task to the Lead.

For some reason when I try to create Lead I get the following message: CreatingTask: execution of AfterInsert caused by: System.FinalException: Record is read-only Trigger.CreatingTask: line 21, column 1
I

Line 21 is this line in the code below
myLead.Key_Fields_Populated__c = NonEmptyFields.size();

Here is my code:

trigger Homework5 on Lead (after insert) {
    
    for (Lead myLead:Trigger.new){

        List<String> NameOfFields = New List<String>();
        NameOfFields.add('FirstName');
        NameOfFields.add('LastName');
        NameOfFields.add('Email');
        NameOfFields.add('Phone');
        NameOfFields.add('Website');
        NameOfFields.add('Title');
        
        List<String> NonEmptyFields = new List<String>();
               
        for(Integer i=0;i<NameOfFields.size();i++){
            if(myLead.get(NameOfFields.get(i)) !=null){
               NonEmptyFields.add(NameOfFields.get(i));
           
            }
        }
      myLead.Key_Fields_Populated__c = NonEmptyFields.size();
        
       Task myTask = new Task();
       myTask.whoId = myLead.Id;
       myTask.Status = 'Not Started';
       insert myTask;
         
    } 
           
}

Thanks in advance.

Darko
Abdul KhatriAbdul Khatri
Hi Darko,

Since you are using after insert and update the lead field info in the same context on which the lead trigger is running, therefore system is complaining that the current lead is in the process of getting insert so that record is unavailable. One way to handle is to run a SOQL Query on the leads so that the records get available to you for making updates. 

Also task creation is not following best practice since you are calling insert in the loop.

I think this is the approach I would suggest to take to update the lead field on before update and create task on after update 
 
trigger Homework5 on Lead (before insert, after insert) {

    switch on Trigger.operationType {
         
        when BEFORE_INSERT {
            for (Lead myLead:Trigger.new)
            {    
                List<String> NameOfFields = New List<String>();
                NameOfFields.add('FirstName');
                NameOfFields.add('LastName');
                NameOfFields.add('Email');
                NameOfFields.add('Phone');
                NameOfFields.add('Website');
                NameOfFields.add('Title');
                
                List<String> NonEmptyFields = new List<String>();
                
                for(Integer i=0;i<NameOfFields.size();i++){
                    if(myLead.get(NameOfFields.get(i)) !=null){
                        NonEmptyFields.add(NameOfFields.get(i));
                        
                    }
                }
                
                myLead.Key_Fields_Populated__c = NonEmptyFields.size();            
            }         
        }  
        when AFTER_INSERT 
        {
            List<Tast> taskToInsertList = new List<Task>();
            for (Lead myLead:Trigger.new){       
                Task myTask = new Task();
                myTask.whoId = myLead.Id;
                myTask.Status = 'Not Started';
				taskToInsertList.add(myTask);
            }
            insert taskToInsertList;
        } 
    }
}

Let  me know if this helps.

Thanks
AnkaiahAnkaiah (Salesforce Developers) 
Hi Darko,

Instead of creating new field, you can handle it trigger itself. If all 6 fields are not empty then you can create a task.
 
trigger Homework5 on Lead (after insert) {

List<Tast> taskToInsertList = new List<Task>();
            for (Lead myLead:Trigger.new){
if(myLead.FirstName !=Null && myLead.LastName !=Null && myLead.Email !=Null && myLead.Phone !=Null && myLead.Website !=Null && myLead.Title!=Null){       
                Task myTask = new Task();
                myTask.whoId = myLead.Id;
                myTask.Status = 'Not Started';
				taskToInsertList.add(myTask);
               }
            }
            insert taskToInsertList;
}

If this helps, Please mark it as best answer.

Thanks!!
 
Darko VukasovicDarko Vukasovic
Hi Abdul,

Thank you very much for your answer. I have some additional questions. 

1) Is it possible to write this code without using SOQL Query since this is the area which I haven't covered yet(but I am planning to start learning it soon)?

2) If at least 3 key fields are populated I would like to create a new Task for each key field populated. So if 3 Key fields are populated I would like to create 3 new Tasks as well.
The name of each Task should be: Verify the <<key field name>> field
Do you know how I can do that since the API name for the Name field for Task is WhoId, and they Key Fields in Lead Object are Strings.

Thanks.

Best Regards,

Darko

Abdul KhatriAbdul Khatri
Hi Darko,

I didn't understand the below part. Can you explain with one example how you want task to look like.
User-added image

Thanks
 
Abdul KhatriAbdul Khatri
Hi Darko,

Please try the below code and see if it fulfills your expectation.
 
trigger Homework5 on Lead (before insert, after insert) {

    switch on Trigger.operationType {
         
        when BEFORE_INSERT {
            for (Lead myLead:Trigger.new)
            {    
                List<String> NameOfFields = New List<String>();
                NameOfFields.add('FirstName');
                NameOfFields.add('LastName');
                NameOfFields.add('Email');
                NameOfFields.add('Phone');
                NameOfFields.add('Website');
                NameOfFields.add('Title');
                
                List<String> NonEmptyFields = new List<String>();
                
                for(Integer i=0;i<NameOfFields.size();i++){
                    if(myLead.get(NameOfFields.get(i)) !=null){
                        NonEmptyFields.add(NameOfFields.get(i));
                        
                    }
                }
                
                myLead.Key_Fields_Populated__c = NonEmptyFields.size();            
            }         
        }  
        when AFTER_INSERT 
        {
            Map<Id, List<String>> leadMap = new Map<Id, List<String>>();
            for (Lead myLead:Trigger.new)
            {  
                
                
                List<String> NameOfFields = New List<String>();
                NameOfFields.add('FirstName');
                NameOfFields.add('LastName');
                NameOfFields.add('Email');
                NameOfFields.add('Phone');
                NameOfFields.add('Website');
                NameOfFields.add('Title');
                              
                List<String> tempList = new List<String>();
                for(Integer i=0;i<NameOfFields.size();i++)
                {
                    if(myLead.get(NameOfFields.get(i)) !=null){
                        
                        tempList.add(NameOfFields.get(i));
                        if(leadMap.containsKey(myLead.Id))
                        {
							tempList = leadMap.get(myLead.Id);
                            tempList.add(NameOfFields.get(i));
                        }
                        
                        leadMap.put(myLead.Id, tempList);                       
                    }
                }
                          
            }            
            
            List<Task> taskToInsertList = new List<Task>();
            for (Lead myLead:Trigger.new)
            {       
                
                if(leadMap.get(myLead.Id) == null) continue;
                
                if(leadMap.get(myLead.Id).size() <= 2) continue;
                
                for(String fieldNames : leadMap.get(myLead.Id)){
                	Task myTask = new Task();
                	myTask.whoId = myLead.Id;
                	myTask.Status = 'Not Started';                    
					taskToInsertList.add(myTask);
                }
            }
            insert taskToInsertList;
        } 
    }
}