Last week, I deployed the following Apex Trigger & Class in order to update a custom field called "Open Tasks" on both the Lead & Contact Record. It pulls in the number of open tasks related to that lead/contact.
Here is the trigger:
trigger UpdateLeadOpenTasks on Task (after delete, after insert, after undelete,
after update) {
// Declare the variables
public set<Id> LeadIDs = new Set<Id>();
public list<Lead> LeadsToUpdate = new List<Lead>();
public set<Id> ContactIDs = new Set<Id>();
public list<Contact> ContactsToUpdate = new List<Contact>();
// Build the list of Leads and Contacts to update
if(Trigger.isInsert || Trigger.isUnDelete || Trigger.isUpdate){
for(Task t: Trigger.new){
if(string.valueOf(t.WhoId).startsWith('00Q'))
LeadIDs.add(t.WhoId);
if(string.valueOf(t.WhoId).startsWith('003'))
ContactIDs.add(t.WhoId);
}
}
if(Trigger.isDelete || Trigger.isUpdate){
for(Task t: Trigger.old){
if(string.valueOf(t.WhoId).startsWith('00Q'))
LeadIDs.add(t.WhoId);
if(string.valueOf(t.WhoId).startsWith('003'))
ContactIDs.add(t.WhoId);
}
}
// Update the Leads
if(LeadIDs.size()>0){
for(Lead l: [Select l.Id, l.Open_Tasks__c,
(Select Id From Tasks where IsClosed = False)
From Lead l where Id in :LeadIDs])
LeadsToUpdate.add(new Lead(Id=l.Id, Open_Tasks__c = l.Tasks.size()));
update LeadsToUpdate;
}
// Update the Contacts
if(ContactIDs.size()>0){
for(Contact c: [Select c.Id, c.Open_Tasks__c,
(Select Id From Tasks where IsClosed = False)
From Contact c where Id in :ContactIDs])
ContactsToUpdate.add(new Contact(Id=c.Id, Open_Tasks__c = c.Tasks.size()));
update ContactsToUpdate;
}
}
}
Here is the class:
@isTest
private class OpenTask {
static testMethod void LeadTest(){
// Create a Lead
Lead newLead = new Lead(LastName='Test', Company='ABC', Status='Targeted');
insert newLead;
// Create a Task
Task newTask = new Task(Subject='Open Task', Status='Not Started', WhoId=newLead.Id);
test.startTest();
insert newTask;
test.stopTest();
// Verify that the # Open Tasks is correct
newLead = [select Open_Tasks__c from Lead where Id=:newLead.Id ];
System.assertEquals(1,newLead.Open_Tasks__c);
}
static testMethod void ContactTest(){
// Create a Contact
Contact newContact = new Contact(LastName='Test');
insert newContact;
// Create a Task
Task newTask = new Task(Subject='Open Task', Status='Not Started', WhoId=newContact.Id);
test.startTest();
insert newTask;
test.stopTest();
// Verify that the # Open Tasks is correct
newContact = [select Open_Tasks__c from Contact where Id=:newContact.Id];
System.assertEquals(1,newContact.Open_Tasks__c);
}
static testMethod void CompletedTest(){
// Create a Lead
Lead newLead = new Lead(LastName='Test', Company='ABC', Status='Targeted');
insert newLead;
// Create a Completed Task
Task newTask = new Task(Subject='Open Task', Status='Completed', WhoId=newLead.Id);
test.startTest();
insert newTask;
test.stopTest();
// Verify that the # Open Tasks is empty
newLead = [select Open_Tasks__c from Lead where Id=:newLead.Id ];
System.assertEquals(0,newLead.Open_Tasks__c);
}
static testMethod void BatchTest(){
// Create 100 Leads
List<Lead> newLeads = new List<Lead>();
for (Integer i = 0; i < 200; i++) {
newLeads.add(new Lead(LastName='Test '+i, Company='ABC', Status='Targeted'));
}
insert newLeads;
// Create a task for each one
List<Task> newTasks = new List<Task>();
for(Lead l : newLeads){
newTasks.add(new Task(Subject='Open Task', Status='Completed', WhoId=l.Id));
}
// Insert the tasks
test.startTest();
insert newTasks;
test.stopTest();
// We could verify that the Open Tasks fields were updated correctly,
// but this is just testing the governor limits so it's not necessary
}
}
The issue that I'm currently running into concerns the "Email to Salesforce" functionality. I am receiving the following error message:
"Apex script unhandled trigger exception by user/organization:UpdateLeadOpenTasks: execution of AfterInsert
caused by: System.NullPointerException: Attempt to de-reference a null object
Trigger.UpdateLeadOpenTasks: line 14, column 1"
The message is Undeliverable. Any advice would be greatly appreciated. Thanks,
Attribution to: ddean.au
Possible Suggestion/Solution #1
Thanks to @sfdcfx, Here's my updated trigger:
trigger UpdateLeadOpenTasks on Task (after delete, after insert, after undelete,
after update) {
// Declare the variables
public set<Id> LeadIDs = new Set<Id>();
public list<Lead> LeadsToUpdate = new List<Lead>();
public set<Id> ContactIDs = new Set<Id>();
public list<Contact> ContactsToUpdate = new List<Contact>();
// Build the list of Leads and Contacts to update
if(Trigger.isInsert || Trigger.isUnDelete || Trigger.isUpdate){
for(Task t: Trigger.new){
if(t.WhoId != NULL){
if(string.valueOf(t.WhoId).startsWith('00Q'))
LeadIDs.add(t.WhoId);
if(string.valueOf(t.WhoId).startsWith('003'))
ContactIDs.add(t.WhoId);
}
}
}
if(Trigger.isDelete || Trigger.isUpdate){
for(Task t: Trigger.old){
if(t.WhoId != NULL){
if(string.valueOf(t.WhoId).startsWith('00Q'))
LeadIDs.add(t.WhoId);
if(string.valueOf(t.WhoId).startsWith('003'))
ContactIDs.add(t.WhoId);
}
}
}
// Update the Leads
if(LeadIDs.size()>0){
for(Lead l: [Select l.Id, l.Open_Tasks__c,
(Select Id From Tasks where IsClosed = False)
From Lead l where Id in :LeadIDs])
LeadsToUpdate.add(new Lead(Id=l.Id, Open_Tasks__c = l.Tasks.size()));
update LeadsToUpdate;
}
// Update the Contacts
if(ContactIDs.size()>0){
for(Contact c: [Select c.Id, c.Open_Tasks__c,
(Select Id From Tasks where IsClosed = False)
From Contact c where Id in :ContactIDs])
ContactsToUpdate.add(new Contact(Id=c.Id, Open_Tasks__c = c.Tasks.size()));
update ContactsToUpdate;
}
}
Attribution to: ddean.au
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/34381