Create a Task Assigned to Lead Owner of a New Web Lead

I recently got a request from a client to write a trigger that creates a task when a lead is created from Web-to-Lead (Lead Source = “Web”). The Task should have Due Date = Today, WhoId is the Lead.Id, and Status = New.

I thought that was a simple trigger.  I originally designed the trigger to be an after insert trigger on the Lead object, which checked for LeadSource = ‘Web’ and created new Task like this:

   Task t = new Task();
   t.WhoId = l.Id;
   t.Subject = 'Web Lead';
   t.OwnerId = l.OwnerId
   t.ActivityDate = date.today();

 

Then I added the new Task (t) to lstNewTasks and insert.

Simple, right? No, no, no!  Not until the Lead Assignment rule was implemented. Here is the scenario:

  • In Lead Settings, the default lead owner is “Jack Bauer”
  • Lead Assignment rule has State = MA, assign to “Sydney Bristow”

A new lead came in from the website with State = MA.  Who would be the Task Owner?  Sydney, of course.  But the actual Task Owner was Jack Bauer.  Why?

According to Salesforce’s Triggers and Order of Execution, on the server, Salesforce executes all after triggers before assignment rules.  Wow, I didn’t expect that.

What should I do to assign the Task Owner to the same Owner as the Lead?  I thought it would be nice to have a Task Assignment Rule for this particular case.  Then I began my search for some good ideas from fellow developers and I found this blog article Opportunity Assignment Rules in Salesforce.com via Apex & Imagination.  MJ Kahn introduced to me the way to convert Lead Assignment Rules to Opportunity Assignment Rules, so I thought “Why not?  I can use this same tactic with my Task Assignment Rules, too.”  My approach is a little bit easier than MJ’s Opportunity Assignment Rules and here are the steps:

  1. Add a checkbox field called “From WebLead” in Activity Custom Field
  2. Tweak the Lead Trigger to not set the Task Owner Id and set From WebLead = true.
  3. Write an Apex trigger that fires when a Task is created.  The trigger will:
    •  Query for the default Lead Assignment rule.
    •  Check if the Task is from web lead (From WebLead = true) and WhoId starts with ’00Q’.
    •   Set Database Savepoint.
    •   Insert a new Lead that has all the important fields equal to the same values in the Lead that the Task was created from, except FirstName is the Lead’s Id.  (Oh.  You might not want to copy the Lead’s email from the web lead, since some people like to put an invalid email address and that would cause the Web to Lead to fail to insert the original lead to the database.)  Apply the default Lead Assignment Rule to the new Lead.
    •  Determine which user the default Lead Assignment Rule assigned to the new Lead and the Task.From Weblead is true, then change the Task to be owned by that user.
    • Roll back the database to the state it was in when you set the Savepoint, so we don’t save the new Lead.
    •  Allow the creation of the Task to continue. The Task will be created and we now have Task Owner equals to the Lead Owner based on the default Lead Assignment Rule!

Let’s see the Task trigger below.

trigger Task on Task (before insert) {
          if (Trigger.isBefore && Trigger.isInsert) {
                      AssignmentRule rule = [select id from AssignmentRule where SObjectType = 'Lead' and Active = true limit 1];
                      Database.DmlOptions dmo = new Database.DmlOptions();
                      dmo.assignmentRuleHeader.assignmentRuleId = rule.id;
                      Set<Id> setLeadIds            = new Set<Id>();
                      Map<Id, Lead> mapWebLeads     = new Map<Id, Lead>();
                      Map<Id, Lead> mapLeadsbyWhoId = new Map<Id, Lead>();
                      for (Task t : Trigger.new) {
                                 String whoId;
                                 whoId = t.WhoId;
                                 if (t.WhoId == null) continue;
                                 if (whoId.contains('00Q')) setLeadIds.add(t.WhoId);
                      }
                      // Get the current information from the Lead that we create a task for
                      mapWebLeads = new Map<Id, Lead>([select LastName, OwnerId, Email, Company, LeadSource, Country, State,
                                            Status, AZ_Auctioneer_ID__c
                                            from   Lead
                                            where  Id IN:setLeadIds ]);
                      if (!mapWebLeads.isEmpty()) {
                                 for (Task t : Trigger.new) {
                                            String whoId;
                                            whoId = t.WhoId;
                                 if (whoId.contains('00Q') && t.From_WebLead__c==true) {
                                         Lead newLead = new Lead();
                                         newLead.OwnerId    = mapWebLeads.get(t.WhoId).OwnerId;
                                         newLead.LastName   = mapWebLeads.get(t.WhoId).LastName;
                                         newLead.FirstName  = t.WhoId;
                                         newLead.Company    = mapWebLeads.get(t.WhoId).Company;
                                         newLead.LeadSource = mapWebLeads.get(t.WhoId).LeadSource;
                                         // flag the Lead to be assigned by our Assignment Rule
                                         newLead.setOptions(dmo);
                                         mapLeadsbyWhoId.put(t.WhoId, newLead);
                                            }
                                 }
                      }
          Savepoint sp = Database.setSavepoint();
          // Insert the newLeads (and trigger the reassignment)
          insert mapLeadsbyWhoId.values();
          // Create a map of Leads, indexed by their Ids in the FirstName
          Map<Id, Lead> mapLeadsByWhoIdNew = new Map<Id, Lead>();
          for (Lead ld : [select id, FirstName, Email, OwnerId from Lead where id in :mapLeadsbyWhoId.values()]) {
                      mapLeadsByWhoIdNew.put((Id)ld.FirstName, ld);
          }
                      // Rollback database so the temp newLeads are not saved to real database
                      Database.rollback(sp);
                      // mapLeadsByWhoIdNew should now contain all of the Leads in Trigger.new
                      for (Task t : Trigger.new) {
                                 String whoId;
                                 whoId = t.WhoId;
                                 if (t.WhoId == null) continue;
                                 if (whoId.contains('00Q') && t.From_WebLead__c==true) {
                                            // Reassign the Task
                                            t.OwnerId = mapLeadsByWhoIdNew.get(t.WhoId).OwnerId;
                                 }
                      }
          }
}

 

Have you reassigned a Task based on Lead Assignment rule before?  What approach did you use?