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
Mike SimmenMike Simmen 

Trigger to Update Account from Task when whatID is null

Hello all,

I have been working on writing an apex trigger to update an account date field when a task that meets certain criteria is entered.  The code works great when you have a whatID.  The problem though is when you use email to salesforce, the emails are only attached to the whoID and leaves the whatID null.  I need to find a way to modify my code to look at the whoID and determine what account it is associated with and then update that account.  I need some help.  Take a look and let me know your thoughts.  Thanks.

trigger updateAccountEngagement on Task (before insert, before update) {
    
    List<Id> accountIds=new List<Id>();
    for(Task t:trigger.new){
        if(t.Status=='Completed'){
            if(t.whatId != null && (String.valueOf(t.whatId).startsWith('001')==TRUE || String.valueOf(t.whatId).startsWith('006')==TRUE) && (String.valueOf(t.subject).startsWith('Email: Re:')==TRUE || String.valueOf(t.subject).startsWith('Email: Fw:')==TRUE || t.Engagement__c==TRUE)){//check if the task is associated with an account
                accountIds.add(t.whatId);
            }//if 2
        }//if 1
    }//for
    List<Account> accountsToUpdate=[SELECT Id, Last_Engagement_Date__c FROM Account WHERE Id IN :accountIds];
    For (account a:accountsToUpdate){
        a.Last_Engagement_Date__c=date.today();
    }//for
    
    try{
        update accountsToUpdate;
    }catch(DMLException e){
        system.debug('Accounts were not all properly updated.  Error: '+e);
    }
}//trigger
Best Answer chosen by Mike Simmen
Mike SimmenMike Simmen
I was able to fix this issue.  Here is my code for anyone else that might have this issue.
trigger updateAccountEngagement on Task (after insert, after update) 
{
    List<Id> Triggerids=new List<Id>();
   
     System.debug('in Trigger 1');
    for(Task t:trigger.new)
    {
       Triggerids.add(t.id);
    }
    classupdateAccountEngagement.Triggerhelper(Triggerids);
}
public class classupdateAccountEngagement {

    @future
    public static void Triggerhelper(List<id> TaskId){
        List<Id> accountIds=new List<Id>();
    List<Id> ContactIds=new List<Id>();
    List<Account> UpdateAccounts = new List<Account>();
        List<Task> Tasks = [select Whoid, WhatId, Engagement__c, Subject, status from task where id IN :TaskId];
        
        for(Task t:Tasks)
    {
        System.debug('task who id and whatid'+ t.whoid + '  ' + t.whatid);
        if(t.Status=='Completed')
        {
            system.debug('inside loop of task completed');
            if(t.whatId != null && (String.valueOf(t.whatId).startsWith('001')==TRUE || String.valueOf(t.whatId).startsWith('006')==TRUE) && t.Engagement__c==TRUE)
            {
                //check if the task is associated with an account
                accountIds.add(t.whatId);
            }
        }
        {
            if ((t.whoId != null && String.valueOf(t.whoId).startsWith('003')==TRUE) && ((String.valueOf(t.subject).startsWith('Email: Re:')==TRUE || String.valueOf(t.subject).startsWith('Email: Fw:')==TRUE ) || t.Engagement__c==TRUE))
            {
                //check if the task is associated with a contact
                ContactIds.add(t.whoid);
            }
        }
    }
    if( accountIds.size() > 0)
    {
        List<Account> accountsToUpdate=[SELECT Id, Last_Engagement_Date__c FROM Account WHERE Id IN :accountIds];
        For (account a:accountsToUpdate)
        {
        a.Last_Engagement_Date__c=date.today();
        
        UpdateAccounts.add(a);
        }
        
        
        
    }
    if(ContactIds.size() > 0)
    {
        System.debug('Testing inside tge loop'+ContactIds );
        List<Contact> listContact = [select id,accountid from contact where id in :ContactIds ];
        Set<id> accId = new Set<ID>();
        for(Contact cont : listContact)
        {
            if(cont.accountid != null)
            {
                accId.add(cont.accountid);
            }   
        }   

        if( accId.size() > 0)
    {
        List<Account> accountsToUpdate=[SELECT Id, Last_Engagement_Date__c FROM Account WHERE Id IN :accId];
        For (account a:accountsToUpdate)
        {
        a.Last_Engagement_Date__c=date.today();
        
        UpdateAccounts.add(a);
        }
        
        }       
    }
    
    try
        {
            update UpdateAccounts;
        }catch(DMLException e){
            system.debug('Accounts were not all properly updated.  Error: '+e);
        }
    
    }

}


 

All Answers

ThousifAli99ThousifAli99
Hi Mike,

Since you are performing DML on account object inside a task trigger, i would suggest you update the trigger context to  'after insert,after update'. 
Mike SimmenMike Simmen
Thanks Amit,

The code works great when you are logging activity manually from the contact level.  However whenever you try to use email to salesforce, the trigger does not fire and does not update the Last_Engagement_Date__c field at the account.  That is the ultimate goal.  Is this possible?
Amit Chaudhary 8Amit Chaudhary 8
Please try below code:-
trigger updateAccountEngagement on Task (After insert, After update) 
{
    List<Id> accountIds=new List<Id>();
    List<Id> ContactIds=new List<Id>();
    for(Task t:trigger.new)
	{
        if(t.Status=='Completed')
		{
            if(t.whatId != null && (String.valueOf(t.whatId).startsWith('001')==TRUE || String.valueOf(t.whatId).startsWith('006')==TRUE) && (String.valueOf(t.subject).startsWith('Email: Re:')==TRUE || String.valueOf(t.subject).startsWith('Email: Fw:')==TRUE || t.Engagement__c==TRUE))
			{
				//check if the task is associated with an account
                accountIds.add(t.whatId);
            }
        }
		
		if ( (t.whoId != null && t.whatid == null) && (String.valueOf(t.whatId).startsWith('003')==TRUE) )
		{
			ContactIds.add(t.whoid);
		}
		
    }
	if( accountIds.size() > 0)
	{
		List<Account> accountsToUpdate=[SELECT Id, Last_Engagement_Date__c FROM Account WHERE Id IN :accountIds];
		For (account a:accountsToUpdate)
		{
			a.Last_Engagement_Date__c=date.today();
		}
		
		try
		{
			update accountsToUpdate;
		}catch(DMLException e){
			system.debug('Accounts were not all properly updated.  Error: '+e);
		}
	}
	if(ContactIds.size() > 0)
	{
		List<Contact> listContact = [select id,accountid from contact where id in :ContactIds ];
		Set<id> accId = new Set<ID>();
		for(Contact cont : listContact)
		{
			if(cont.accountid != null)
			{
				accId.add(cont.accountid);
			}	
		}	

		if(accId.size() > 0)
		{
			List<Account> accToUpdate=[SELECT Id, Last_Engagement_Date__c FROM Account WHERE Id IN :accId];

			For (account a : accToUpdate)
			{
				a.Last_Engagement_Date__c=date.today();
			}
			try
			{
				update accToUpdate;
			}catch(DMLException e){
				system.debug('Accounts were not all properly updated.  Error: '+e);
			}
		}		
	}
}

I hope this should help you
 
Mike SimmenMike Simmen
I receive this error now....Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger updateAccountEngagement caused an unexpected exception, contact your administrator: updateAccountEngagement: execution of AfterUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.updateAccountEngagement: line 16, column 1
Mike SimmenMike Simmen
I fixed the error.  Still does not work with Email to Salesforce.  I might have to figure out another way.  Maybe do a trigger on task for contact and then do another trigger to update from the contact object to the account object.  It works great though when you use email to salesforce to log the email and then go into the contact and edit the task and resave.  This fires the trigger without issues.
Mike SimmenMike Simmen
I was able to fix this issue.  Here is my code for anyone else that might have this issue.
trigger updateAccountEngagement on Task (after insert, after update) 
{
    List<Id> Triggerids=new List<Id>();
   
     System.debug('in Trigger 1');
    for(Task t:trigger.new)
    {
       Triggerids.add(t.id);
    }
    classupdateAccountEngagement.Triggerhelper(Triggerids);
}
public class classupdateAccountEngagement {

    @future
    public static void Triggerhelper(List<id> TaskId){
        List<Id> accountIds=new List<Id>();
    List<Id> ContactIds=new List<Id>();
    List<Account> UpdateAccounts = new List<Account>();
        List<Task> Tasks = [select Whoid, WhatId, Engagement__c, Subject, status from task where id IN :TaskId];
        
        for(Task t:Tasks)
    {
        System.debug('task who id and whatid'+ t.whoid + '  ' + t.whatid);
        if(t.Status=='Completed')
        {
            system.debug('inside loop of task completed');
            if(t.whatId != null && (String.valueOf(t.whatId).startsWith('001')==TRUE || String.valueOf(t.whatId).startsWith('006')==TRUE) && t.Engagement__c==TRUE)
            {
                //check if the task is associated with an account
                accountIds.add(t.whatId);
            }
        }
        {
            if ((t.whoId != null && String.valueOf(t.whoId).startsWith('003')==TRUE) && ((String.valueOf(t.subject).startsWith('Email: Re:')==TRUE || String.valueOf(t.subject).startsWith('Email: Fw:')==TRUE ) || t.Engagement__c==TRUE))
            {
                //check if the task is associated with a contact
                ContactIds.add(t.whoid);
            }
        }
    }
    if( accountIds.size() > 0)
    {
        List<Account> accountsToUpdate=[SELECT Id, Last_Engagement_Date__c FROM Account WHERE Id IN :accountIds];
        For (account a:accountsToUpdate)
        {
        a.Last_Engagement_Date__c=date.today();
        
        UpdateAccounts.add(a);
        }
        
        
        
    }
    if(ContactIds.size() > 0)
    {
        System.debug('Testing inside tge loop'+ContactIds );
        List<Contact> listContact = [select id,accountid from contact where id in :ContactIds ];
        Set<id> accId = new Set<ID>();
        for(Contact cont : listContact)
        {
            if(cont.accountid != null)
            {
                accId.add(cont.accountid);
            }   
        }   

        if( accId.size() > 0)
    {
        List<Account> accountsToUpdate=[SELECT Id, Last_Engagement_Date__c FROM Account WHERE Id IN :accId];
        For (account a:accountsToUpdate)
        {
        a.Last_Engagement_Date__c=date.today();
        
        UpdateAccounts.add(a);
        }
        
        }       
    }
    
    try
        {
            update UpdateAccounts;
        }catch(DMLException e){
            system.debug('Accounts were not all properly updated.  Error: '+e);
        }
    
    }

}


 
This was selected as the best answer