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
msmithey13msmithey13 

Please help with trigger and class.

I need to trigger a email from a task and, since I cannot do that, I need to trigger the email another way.  My thought is to set up a trigger that will populate a custom field in the Account that I can then trigger the email by.  Unfortunately I don't understand code and cannot create the trigger.  Can anyone help me with creating a trigger that will populate this field and then the test class?

Scenario:  Task:  Subject = ISA Call Complete and Survey Sent = True.  From this I need to trigger the WS Survey Complete field in the Account to True.  I can then set  up the workflow rule to trigger my email when the account field goes true.

I appreciate the assist so thanks in advance.

Best Answer chosen by Admin (Salesforce Developers) 
souvik9086souvik9086

Test Class

 

@isTest
private class testClass_Trigger{
private static TestMethod void JWGetAssociations(){
Account acct1 = new Account(name='TestAccount1');
insert acct1;
Task t = new Task();
t.Subject = 'ISA Call Complete';
t.SurveySent__c = True;
t.WhatId = acct1.Id;
t.Status = 'Not started';
t.Priority = 'Normal';
insert t;
}


}

 

If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.

Thanks

All Answers

souvik9086souvik9086

Try this

 

trigger PopulateContactOnTask on Task(after insert,after update){
List<Id> lstid = new List<Id>();
List<Account> accListToBeUpdated = new List<Account>();
for(task t : Trigger.new){
if(t.WhatId.startsWith('001') != NULL){
lstid.add(t.WhatId);
}
}
Map<id,account> aMap = new Map<id,account>([Select Id,WSSurveyComplete__c from Account where id in :lstid]);
for(task t : Trigger.new){
if(aMap.get(t.WhatId) != NULL && t.WhatId.startsWith('001') != NULL && t.Subject == 'ISA Call Complete' && t.SurveySent__c == True){
Account acc = new Account(Id = aMap.get(t.WhatId));
acc.WSSurveyComplete__c = TRUE;
accListToBeUpdated.add(acc);
}
}
if(accListToBeUpdated.size()>0){
UPDATE accListToBeUpdated;
}
}

 

If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.

Thanks

msmithey13msmithey13

Souvik,

Thanks for the quick reply.  We have an error: Method does not exist or incorrect signature: [Id].startsWith(String) at line 5 column 4.

 

5.  if(t.WhatId.startsWith('001') != NULL){

 

Again, I appreciate your help.

 

 

souvik9086souvik9086

Change it like this

 

trigger PopulateContactOnTask on Task(after insert,after update){
List<Id> lstid = new List<Id>();
List<Account> accListToBeUpdated = new List<Account>();
for(task t : Trigger.new){
if(String.valueOf(t.WhatId).startsWith('001') != NULL){
lstid.add(t.WhatId);
}
}
Map<id,account> aMap = new Map<id,account>([Select Id,WSSurveyComplete__c from Account where id in :lstid]);
for(task t : Trigger.new){
if(aMap.get(t.WhatId) != NULL && String.valueOf(t.WhatId).startsWith('001') != NULL && t.Subject == 'ISA Call Complete' && t.SurveySent__c == True){
Account acc = new Account(Id = aMap.get(t.WhatId));
acc.WSSurveyComplete__c = TRUE;
accListToBeUpdated.add(acc);
}
}
if(accListToBeUpdated.size()>0){
UPDATE accListToBeUpdated;
}
}

 

If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.

Thanks

 

msmithey13msmithey13

New error:  Invalid initial expression type for field Account.Id, expecting: Id at line 12 column 32

 

12.  Account acc = new Account(Id = aMap.get(t.WhatId));

souvik9086souvik9086

Aha little missout :)

 

Account acc = new Account(Id = aMap.get(t.WhatId).Id);

 

 

msmithey13msmithey13

Souvik,

This trigger seems to work perfectly!  Thanks a bundle!!  Will this required an Apex Class for test coverage or can I move this to production?

msmithey13msmithey13

It appears that I will need a test class for this trigger.  Any chance you can help with that as well?

souvik9086souvik9086

Test Class

 

@isTest
private class testClass_Trigger{
private static TestMethod void JWGetAssociations(){
Account acct1 = new Account(name='TestAccount1');
insert acct1;
Task t = new Task();
t.Subject = 'ISA Call Complete';
t.SurveySent__c = True;
t.WhatId = acct1.Id;
t.Status = 'Not started';
t.Priority = 'Normal';
insert t;
}


}

 

If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.

Thanks

This was selected as the best answer
msmithey13msmithey13

Thank you Souvik!!  I appreciate your help big time!

msmithey13msmithey13

Souvik,

This worked great in the Sandbox test and moved to production without incident.  Later though, I received this email from ApexApplication:

 

Apex script unhandled trigger exception by user/organization: 00560000001eQr1/00D60000000KGaJ

 

PopulateContactOnTask: execution of AfterInsert

 

caused by: System.NullPointerException: Attempt to de-reference a null object

 

Trigger.PopulateContactOnTask: line 5, column 1

 

Is this something I should worry about?

souvik9086souvik9086

Is this running fine in Production?

If not then some difference in the dataset in sandbox and production. Lets change the trigger a little.

 

trigger PopulateContactOnTask on Task(after insert,after update){
List<Id> lstid = new List<Id>();
List<Account> accListToBeUpdated = new List<Account>();
for(task t : Trigger.new){
if(t.WhatId != NULL && String.valueOf(t.WhatId).startsWith('001') != NULL){
lstid.add(t.WhatId);
}
}
Map<id,account> aMap = new Map<id,account>([Select Id,WSSurveyComplete__c from Account where id in :lstid]);
for(task t : Trigger.new){
if(t.WhatId != NULL && aMap.get(t.WhatId) != NULL && String.valueOf(t.WhatId).startsWith('001') != NULL && t.Subject == 'ISA Call Complete' && t.SurveySent__c == True){
Account acc = new Account(Id = aMap.get(t.WhatId));
acc.WSSurveyComplete__c = TRUE;
accListToBeUpdated.add(acc);
}
}
if(accListToBeUpdated.size()>0){
UPDATE accListToBeUpdated;
}
}

 

If the post helps you please throw KUDOS.

Thanks

msmithey13msmithey13

I tested in production and it did exactly what I expected and the same as the sandbox.  Should I still do the trigger update?

souvik9086souvik9086

If it works fine then no need. :)

 

Thanks

msmithey13msmithey13

Very well.  I will keep a copy of the updated trigger for use IF it becomes necessary.  Thanks again!!

 

KaityKaity

Hi Souvik,

I have tried to write the trigger in the below ways;  

 

Can you please pick where am I going wrong:

 

trigger UpdateAccountField on Task (before Insert, before Update) {
  Map<String,Task> map_task = new Map<String,Task>(); 
  List<Account> accountToBeUpdated = new List<Account>(); 
   for(Task ts : Trigger.new){
   if(ts.subject =='IS A Call Complete' && ts.Survey_Sent__c == True){
    map_task.put(ts.Id, ts); 
     }
  }
   accountToBeUpdated = [SELECT Id, Name, WS_Survey_Complete__c From Account where Id IN: map_task.keySet()];
     for(Account a: accountToBeUpdated ){
   //  a.WS_Survey_Complete__c = map_task.get(a.Id).Survey_Sent__c;
     a.WS_Survey_Complete__c =true;
     }
     if(!accountToBeUpdated.IsEmpty()){
        update accountToBeUpdated;
     }
}

souvik9086souvik9086

You have to make it after insert to get the task id which you using in the for loop.

 

If the post helps you, please throw KUDOS.

Thanks

KaityKaity

Souvik....

I change the event to 'after insert' and 'after update'. But still not working.

My concept about map:

When there are two objects and we are using map, then we use the map on that object from where er are manipulating data. And here, Task is such an object.

 

 

trigger UpdateAccountField on Task (after Insert, after Update) {
  Map<String,Task> map_task = new Map<String,Task>(); 
  List<Account> accountToBeUpdated = new List<Account>(); 
   for(Task ts : Trigger.new){
   if(ts.subject =='IS A Call Complete' && ts.Survey_Sent__c == True){
    map_task.put(ts.Id, ts); 
     }
  }
   accountToBeUpdated = [SELECT Id, Name, WS_Survey_Complete__c From Account where Id IN: map_task.keySet()];
     for(Account a: accountToBeUpdated ){
     a.WS_Survey_Complete__c = map_task.get(a.Id).Survey_Sent__c;
    // a.WS_Survey_Complete__c =true;
     }
     if(!accountToBeUpdated.IsEmpty()){
        update accountToBeUpdated;
     }
}

souvik9086souvik9086

If the trigger is firing in Task object and you want account to be updated then you keep the accoyntid and account in map instead of task and then in teh loop of task get that accountid from the whatid of the task.

 

If the post is helpful please throw KUDOS.

Thanks