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
ColaCola 

Test Trigger Not Working: Trigger Updates Account Field Based on Task

I've created a trigger on a task to udpate a custom Account field (In_Touch_Date__c). Although the trigger compiles, it does not seem to be working properly. What I am trying to do is have the Account In_Touch_Date__c field update to the most recent Activity Date of the Account. I have successfully created similar triggers on the Contact and Opportunity levels. 

Here is the current trigger code:

trigger UpdateInTouchAccount on Task (after insert, after update) {
	Set<String> whatIds = new Set<String>();
	
    for (Task t : Trigger.new) {
  		whatIds.add(t.WhatId);
	}
	
   	List<Account> acct = [SELECT Id, In_Touch_Date__c FROM Account WHERE Id =: whatIds];
    
   	Map<String, Task> taskMap = new Map<String, Task>();
	
    for (Task t : Trigger.new){
    	if (!(t.Type.equals('Eloqua Activity'))) {
    		if (t.Status.equals('Completed')) {
    			taskMap.put(t.WhatId, t);
    		}
    	}	
	}
         
    for (Account a : acct) {
  		if (taskMap.containsKey(a.Id)) {
    		a.In_Touch_Date__c = taskMap.get(a.Id).ActivityDate;
  		}
	}
	update acct;
}

 

Best Answer chosen by Cola
ColaCola
Was able to find the solution in this thread: https://developer.salesforce.com/forums/ForumsMain?id=906F0000000AdBxIAK

All Answers

claperclaper
Hi Marc, 

give this a try:
trigger UpdateInTouchAccount on Task (after insert, after update) {
	Set<String> whatIds = new Set<String>();
	

    
   	Map<String, Task> taskMap = new Map<String, Task>();
	
    for (Task t : Trigger.new){
    	if (!(t.Type.equals('Eloqua Activity'))) {
    		if (t.Status.equals('Completed')) {
    			taskMap.put(t.WhatId, t);
    		}
    	}	
	}
    
   List<Account> toUpdate = new List<Account>();
   for(Id accountId : taskMap.KeySet())
   {
          account thisAcc = new Account(id=accountID,
                                                                 In_Touch_Date__c=taskmap.get(accountId).ActivityDate
                                                               );
           toUpdate.add(thisAcc);
   }     
   update toUpdate;

}


ColaCola
Hi, 
When I try your code I get the following error when testing: 
System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, UpdateInTouchAccount: execution of AfterInsert 

Any ideas?
claperclaper
I just tried in my dev org, and changed the custom fields to fields I have in my org:trigger UpdateInTouchAccount on Task (after insert, after update) { Set whatIds = new Set(); Map taskMap = new Map(); for (Task t : Trigger.new){ if (t.subject == 'hey'){ taskMap.put(t.whatid,t); } } List toUpdate = new List(); for(Id accountId : taskMap.KeySet()) { account thisAcc = new Account(id=accountID, Date_Of_New_Account__c=taskmap.get(accountId).ActivityDate ); toUpdate.add(thisAcc); } update toUpdate; } and it work, give that simple code a try and see if it updated correctly. Clara PérezSalesforce Developer
ColaCola

Hi Clara,
I tried the simple code you posted and fixed it to match my custom variables and it didn't give any errors and deployed to the server successfully. But then when I tried to updated an Account Task to have the subject='hey', I received the following error and it would not let me save the Task.

Error Message
Review all error messages below to correct your data.
Apex trigger UpdateInTouchAccount caused an unexpected exception, contact your administrator: UpdateInTouchAccount: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: []: Trigger.UpdateInTouchAccount: line 14, column 1

claperclaper
lets use an if to filter null values out of whatID:

trigger UpdateInTouchAccount on Task (after insert, after update) {
    Set<String> whatIds = new Set<String>();
    

    
    Map<String, Task> taskMap = new Map<String, Task>();
    
    for (Task t : Trigger.new){
        if (t.subject == 'hey'){
                taskMap.put(t.WhatId, t);
            }
    }   
    
    
   List<Account> toUpdate = new List<Account>();
   for(Id accountId : taskMap.KeySet())
   {
          if(accountId != null){
              account thisAcc = new Account(id=accountID,
                                             Date_Of_New_Account__c=taskmap.get(accountId).ActivityDate
                                           );
               toUpdate.add(thisAcc);
           }
   }     
   update toUpdate;

}


Also make sure to have a value in the "Related To" field:

 User-added image

ColaCola

Ah I see. So that would be the issue. All of our Tasks are "Related To" an "Opportunity". So instead, what I'm trying to do just add onto the trigger that we have working for our Opportunities. 

Below is the code for our opportunity trigger: 

 

trigger UpdateOppLastContactDate on Task (after insert, after update) {
	
	Set<String> whatIDs = new Set<String>();
	
    for (Task t : Trigger.new) {
  		whatIDs.add(t.whatID);
	}
	
   	List<Opportunity> opps = [SELECT Id, Last_Contact_Date__c FROM Opportunity WHERE Id =: whatIDs];
   	
   	Map<Id, Account> accts = new Map<Id, Account>();
   	   
   	Map<String, Task> taskMap = new Map<String, Task>();
	
	/* This puts all of the tasks that are not type "Eloqua Activity" and that have 
	*  a status that is "Completed" into a list.
	*/
    for (Task t : Trigger.new){
    	if (!(t.Type.equals('Eloqua Activity'))) {
    		if (t.Status.equals('Completed')) {
    			taskMap.put(t.whatID, t);
    		}
    	}
  		
	}
    
    /*  This takes all the opportunities that have been created or updated and 
    *	updates their contact date to the most recent Activity Date of the
    *	opportunity. 
    */     
    for (Opportunity o : opps) {
  		if (taskMap.containsKey(o.Id)) {
    		o.Last_Contact_Date__c = taskMap.get(o.Id).ActivityDate;
    		Account a = accts.get(o.AccountId);
    		if (a.In_Touch_Date__c != null) {
    			if (taskMap.get(o.Id).ActivityDate.daysBetween(a.In_Touch_Date__c) < 0) {
    				a.In_Touch_Date__c = taskMap.get(o.Id).ActivityDate;
    			}
    		}
  		}
	}
	update opps;
}
The lines I modified to try and make the trigger also update the Account field are: 
Map<Id, Account> accts = new Map<Id, Account>();
and 
Account a = accts.get(o.AccountId);
    	if (a.In_Touch_Date__c != null) {
    			if (taskMap.get(o.Id).ActivityDate.daysBetween(a.In_Touch_Date__c) < 0) {
    				a.In_Touch_Date__c = taskMap.get(o.Id).ActivityDate;
    			}
        }


However, now there seems to be an issue with the a.In_Touch_Date__c. I received the following error when update a Task's Activity Date: 

Apex trigger UpdateOppLastContactDate caused an unexpected exception, contact your administrator: UpdateOppLastContactDate: execution of AfterUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.UpdateOppLastContactDate: line 35, column 1

Let me know if you have any suggestions. Cheers

ColaCola
Was able to find the solution in this thread: https://developer.salesforce.com/forums/ForumsMain?id=906F0000000AdBxIAK
This was selected as the best answer