1

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,

3
  • Can you verify that line 14 in your trigger is if(string.valueOf(t.WhoId).startsWith('00Q')) I'm not seeing how that would give you a null reference error. May 5, 2014 at 18:44
  • That is correct, that is line 14.
    – ddean.au
    May 5, 2014 at 18:45
  • 3
    You should make sure Whoid isn't null.
    – sfdcfox
    May 5, 2014 at 19:09

1 Answer 1

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;
}


}
2
  • Probably ought to check your Deleted and Updated Tasks for null WhoIDs as well. May 5, 2014 at 19:28
  • @ThomasTaylor - You're exactly right. I corrected it on there as well. Thanks!
    – ddean.au
    May 5, 2014 at 19:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .