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
mhamberg1mhamberg1 

Apex trigger to update lead owner

We are trying to automatically assign lead ownership based on our database of Zip Codes. Since there are so many zip codes, we can't manually put them in the native assignment rules.

I'm trying to write a trigger to reassign the Lead Owner but this is my first one and I can't seem to get it right. Here's what I have:

Code:
trigger LeadAssignmentTrigger on Lead (before insert) 
{
    List<Lead> leadsToUpdate = new List<Lead>();

    for (Lead lead : Trigger.new)
    {
     
      if (lead.PostalCode != NULL)
      {
          // Find the sales rep for the current zip code
          List<Zip_Code__c> zip = [select Sales_Rep__c from Zip_Code__c 
where Name = :lead.PostalCode limit 1];


// if you found one
if (zip.size() > 0)
{
//assign the lead owner to the zip code owner
lead.Owner = zip.Sales_Rep__c; // This is my problem line

leadsToUpdate.add(lead);

}
}

}

// update the records
try
{
update leadsToUpdate;
}
catch (DmlException dm)
{
leadsToUpdate.addError('There was a problem reassigning the Lead Owner');
}

}

I have bolded the problem line. All I want to do is to assign the User from my Zip Code object (just a list of zip codes and user lookups) to the current lead creation on any given Lead insert.

Can someone please tell me what the correct syntax should be?

Thanks
Best Answer chosen by Admin (Salesforce Developers) 
Vijay RautVijay Raut
Hi,

As your trigger is before insert, you dont need to update / insert record separately.

So there is no need of following lines in your trigger.

      // update the records
try
{
insert leadsToUpdate;
}
catch (DmlException dm)
{

}

Cheers,
V.R.

All Answers

mikefmikef
is Sales_Rep__c a user lookup?

If so then change this line to.
lead.OwnerId = zip.Sales_Rep__c;

But there is a bigger issue, your trigger is not bulked, and will hit query limits if you bulk insert leads of more then 20 records.

Please review this post.

There is some tips to bulking your triggers.
mhamberg1mhamberg1
Yes, Sales_Rep__c is a user lookup.
I changed the line according to your advice, but I still get a compiler error in that statement: "Initial term of field expression must be a concrete SObject: LIST:SOBJECT:Zip_Code__c"

So how do I get around that?

Also, I thought the code was already handling bulk triggers - it only does the insert once at the very end. Is that not how you're supposed to do it? I got that from a different forum post.

Thanks

mikefmikef
You're not in a bulk operation because you are querying in a for loop. If you insert or update leads in mass through the web services API you will hit governor limits.

Please review the bulk post I refer to from before.

To solve the error add Id to your query, that should work.
Vijay RautVijay Raut
Hi,

Your post is not providing details. But what i have assumed that, your custom object is having Sales_Rep__c field which is lookup to User object. If so you need to use following line instead of one used in your code.

lead.OwnerId = zip[0].Sales_Rep__c; // This is my problem line

As when you are retriving Sales Rep information in SOQL, zip is defined as List.

Hope this would help.

Cheers,
V.R.
mhamberg1mhamberg1
Thanks Vijay, that was definitely the right change and it has gotten me further. However, now when I run a test that is supposed to do the real evaluation I get this trigger error - does anyone know what this means or what causes this?

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger LeadAssignmentTrigger caused an unexpected exception, contact your administrator: LeadAssignmentTrigger: execution of BeforeInsert caused by: System.SObjectException: DML statment cannot operate on trigger.new or trigger.old

Code:
trigger LeadAssignmentTrigger on Lead (before insert) 
{
    List<Lead> leadsToUpdate = new List<Lead>();

    for (Lead lead : Trigger.new)
    {     
      if (lead.PostalCode != NULL)
      {
          // Find the sales rep for the current zip code
          List<Zip_Code__c> zip = [select Sales_Rep__c from Zip_Code__c 
                                   where Name = :lead.PostalCode limit 1];
                
          // if you found one
          if (zip.size() > 0) 
          {    
              //assign the lead owner to the zip code owner
              lead.OwnerId = zip[0].Sales_Rep__c; 
          
              leadsToUpdate.add(lead);
          
          }
       } 
          
     }
     
      // update the records
      try 
      {
           insert leadsToUpdate;
      }
      catch (DmlException dm)
      {
            
      }     
}
Vijay RautVijay Raut
Hi,

As your trigger is before insert, you dont need to update / insert record separately.

So there is no need of following lines in your trigger.

      // update the records
try
{
insert leadsToUpdate;
}
catch (DmlException dm)
{

}

Cheers,
V.R.

This was selected as the best answer
mhamberg1mhamberg1
Thanks, that did it. It works great.
mhamberg1mhamberg1
FYI to all. As was pointed out above, this code only works for single instances and runs into the 20-query limit if you try to bulk load it. I'll try to come up with some bulk load code as well.
JohnC5674JohnC5674

mhamberg1, this is exactly what we need.  Do you mind sharing your updated code? We have 14,000 zips that are assigned to 400+ users and its a pain doing this in the native assignment rules.  With what you created, could we have this run on every lead created that has a certain record type and it assign the lead to the owner we specify for the zip used?

 

I would greatly appreciate if you could help me out with this.  I have been looking for something like this for 2 years! do you have an email that I could contact you at?