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
ItsJustCode2ItsJustCode2 

Having trouble updating a lead owner based on status update.... Please help. Kudos given

The following is the code snippet of what I'm trying to do.  However the update portion seems to be off somehow?  What am I doing wrong?  I want the trigger to be ready for bulk please let me know if you have any ideas?  Thanks ahead of time.
trigger AssignLastModified on Lead (after update)  
{

    List<Id> LeadList = new List<Id>();

    for (Lead l : Trigger.new) 
    { 
       Lead oldLead = Trigger.oldMap.get(l.ID); 
       if (l.Status != oldLead.Status && (oldLead.Status == 'Prospect' || oldLead.Status == 'Contact Attempted') 
       && l.Status != 'Prospect' && l.Status != 'Contact Attempted') 
       {   
           l.OwnerId = l.LastModifiedById;
           LeadList.add(l.id);      
       } 
    }

    Update LeadList;




 
Best Answer chosen by ItsJustCode2
Abhishek BansalAbhishek Bansal
Hi Steve,

You do not required to again update a recod in before update if you are doing changes on the same record.
So as per your requirement, I have modified the code.
Please find it below :
trigger AssignLastModified on Lead (before update)  
{
    for (Lead newLead : Trigger.new) { 
       Lead oldLead = Trigger.oldMap.get(newLead.ID); 
       if(newLead.Status != oldLead.Status && (oldLead.Status == 'Prospect' || oldLead.Status == 'Contact Attempted')
    		   && newLead.Status != 'Prospect' && newLead.Status != 'Contact Attempted' ){
    	   newLead.OwnerId = newLead.LastModifiedById;
       }
    }
}

Let me know if you need more help.

Regards,
Abhishek

All Answers

Alba RivasAlba Rivas
Hi Steve

FIrst of all, you are performing an update operation inside a trigger. This is not recommended, as you could enter into a loop, the lead is updated, it arrives to the trigger, then you update it again, and thus it arrives to the trigger again ... and so on.

Then, if you want to modify the leads that are being updated, you should do it in the berfore part, as in the after part they are already updated in database. Thus, in after part you can only validate what happened. Then, if you change the Trigger.new objects in the before part (modifiying OwnerId in your case), you don't need to call "update LeadList" in the end, as the update will be done after you have modify the Trigger.new records.

It's a good practice to validate the updated record in the after part, to avoid possible modifications that a 3rd party could do to your object through another trigger.

Best regards


 
Jayson Faderanga 14Jayson Faderanga 14
Hi Steve,

please check this snippet :D

trigger AssignLastModified on Lead (before update)  {

//this will bulkify your trigger
List<Lead> leadtoUpdate = new List<Lead>();

for(Lead ld : trigger.new) {
Lead oldLead = trigger.oldMap.get(ld.Id);
if(ld.status != oldLead.status && (oldLead.Status == 'Prospect' || oldLead.status == 'Contact Attempted') && ld.Status != 'Prospect' && oldLead.Status != 'Contact Attempted') {

ld.OwnerId = ld.LastModifiedById;

leadtoUpdate.add(ld);
  }
 }
update leadtoUpdate;
}
 
Abhishek BansalAbhishek Bansal
Hi Steve,

You do not required to again update a recod in before update if you are doing changes on the same record.
So as per your requirement, I have modified the code.
Please find it below :
trigger AssignLastModified on Lead (before update)  
{
    for (Lead newLead : Trigger.new) { 
       Lead oldLead = Trigger.oldMap.get(newLead.ID); 
       if(newLead.Status != oldLead.Status && (oldLead.Status == 'Prospect' || oldLead.Status == 'Contact Attempted')
    		   && newLead.Status != 'Prospect' && newLead.Status != 'Contact Attempted' ){
    	   newLead.OwnerId = newLead.LastModifiedById;
       }
    }
}

Let me know if you need more help.

Regards,
Abhishek
This was selected as the best answer
ItsJustCode2ItsJustCode2
Alba, no recursion possible when you take a closer look at the filter criteria.  Sorry.

Jayson, Thanks but I think this one has to go to Abhishek Bansal.  It processes in bulk and doesn't need an update statement.

Thank you all.
Steve Laycock
Abhishek BansalAbhishek Bansal
Hi Steve,

I checked and found that LastModifiedById is only available in after trigger.
As a result we have to again update our list.
So please change the code as mentioned below :

trigger AssignLastModified on Lead (afetr update)  
{
    List<Lead> updateLeadList = new List<Lead>();
    for (Lead newLead : Trigger.new) {
       Lead oldLead = Trigger.oldMap.get(newLead.ID);
       if(newLead.Status != oldLead.Status && (oldLead.Status == 'Prospect' || oldLead.Status == 'Contact Attempted')
               && newLead.Status != 'Prospect' && newLead.Status != 'Contact Attempted' ){
           newLead.OwnerId = newLead.LastModifiedById;
           updateLeadList.add(newLead);
       }
    }
    if(updateList.size() > 0){
        update updateLeadList
    }
}

It will not be called recursively since the updateLeadList will be empty in second update.

Regards,
Abhishek
ItsJustCode2ItsJustCode2
As it turns out the after updates kept blowing up due to record locking.  Returning 'current record is read-only trigger' errors.

While I changed my approach on the before update.  Instead of trying to assign the LastModifiedById I went with UserInfo.getUserId(); .

Like this and it works great with mass updates.
 
trigger AssignLastModified on Lead (before update) 

    {

        for (Lead newLead : Trigger.new) {

           Lead oldLead = Trigger.oldMap.get(newLead.ID);

           if(newLead.Status != oldLead.Status && (oldLead.Status == 'Prospect' || oldLead.Status == 'Contact Attempted')
                   && newLead.Status != 'Prospect' && newLead.Status != 'Contact Attempted' ){

               newLead.OwnerId = UserInfo.getUserId();

           }

        }

    }
Please let me know what you think?

Thank you,
Steve Laycock
 
Abhishek BansalAbhishek Bansal
You have come up with a very clever alternate.
This will work absolutely fine with your requirement.
Great Work :)

Abhishek
Alba RivasAlba Rivas
Hi Steve

For sure performing updates of your object in your object's trigger is dangerous, regardless if your specific condition doesn't allowed recursion.

The solution I was proposing to you was your best answer chosen solution: using a before update trigger and remove the extra update operation. I think it's much better explaining what you have to do than doing it for you. 

So please, the next time rethink before disliking an answer in which people has invested some time to help you. 

Regards