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:
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:
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?