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
uma52551.3972270309784705E12uma52551.3972270309784705E12 

Apex Trigger to Insert Task record and send Email Notification

Hi All,

Can any one guide me how to write a trigger on Account that has to create a task record (Only one record) and then send an email notification to the person who is in assgined to field. I wrote an after update trigger but it is creating multiple task records when ever i am editing account page for any reason.
Thanks!
Best Answer chosen by uma52551.3972270309784705E12
Anupam RastogiAnupam Rastogi
Hi Uma,

If that is the case then you can check if a Task is already existing for the Account. Only when there is no pre-existing Task, the code should create a new Task for that Account on update. Here is the modified inner IF loop that you can use to replace the current IF loop.
 
if((trigger.isUpdate) && bulkProdMap.containsKey(acc.Id))
    {
        List<Task> eTask = [select Id from Task where WhatId = :acc.Id];
        
        if(eTask.size() == 0)
        {
            task t1 = new task ();
            t1.RecordTypeId = rtList1[0].Id;
            t1.ActivityDate = Date.today()+2;
            t1.Status = 'Not Started';
            t1.Description = 'New Contract----------------. Please make personal contact with the agent';
            t1.Subject = 'New Contracted Follow Up';
            t1.OwnerId = acc.ownerId;
            t1.WhatId = acc.Id;
            t1.Priority = 'High';
            taskToInsert.add(t1);
        }        
    }

Additionally, I have coupld of questions here.

1. When does the Task gets 'Completed'?
2. And should a new Task be created for the Account if the Status of all existing Tasks for that Account are with Status = Completed?

If the answer to the second question above is 'Yes', then you can include a condition for checking the Status of existing tasks as well like shown below - 
 
if((trigger.isUpdate) && bulkProdMap.containsKey(acc.Id))
    {
        List<Task> eTask = [select Id from Task where WhatId = :acc.Id and Status = 'Completed'];
        
        if(eTask.size() == 0)
        {
            task t1 = new task ();
            t1.RecordTypeId = rtList1[0].Id;
            t1.ActivityDate = Date.today()+2;
            t1.Status = 'Not Started';
            t1.Description = 'New Contract----------------. Please make personal contact with the agent';
            t1.Subject = 'New Contracted Follow Up';
            t1.OwnerId = acc.ownerId;
            t1.WhatId = acc.Id;
            t1.Priority = 'High';
            taskToInsert.add(t1);
        }        
    }

Thanks
AR

If the reply was useful and helped solve the problem, please mark it as best answer.
 

All Answers

sandeep sankhlasandeep sankhla

Hi Uma,

Can you share your code here so I can correct if is there anything wrong ?

Thanks,

Sandeep

Anupam RastogiAnupam Rastogi
Hi Uma,

You need to keep this 'creation of task' code under some condition within the Trigger. Or else every time the event on which you have placed this Trigger occurs, the task is going to get created.

For example, keep the trigger to execute only when a new Account is created.

Thanks
AR
sandeep sankhlasandeep sankhla
Hi Uma,

I agree with Anupam,
It basicalluy depends on your need..if every time whenever you are updating the account that time also you want to update any field on task then you can have it on after update only and in trigger you will check if is there any task already created for account then you will update that..else you will create the task..

so it would be good if you can provide your exact req so we can guide on that..

Thanks,
Sandeep
uma52551.3972270309784705E12uma52551.3972270309784705E12
Here is my code please let me know what I am doing wrong!
trigger TaskInsertTriggerOnAccount on Account (before update) {
    List <RecordType> rtList = [SELECT Id from RecordType where SobjectType='Account' and Name = 'BB' Limit 1];
    List <task> taskToInsert = new List <task> ();
     Set<Id> accountIds = new Set<Id>();

    for(Account acc:Trigger.New){
    if(acc.Agent_Id__c!=NULL&&acc.Contracting_Completed_Date__c==date.Today()&&acc.Contracting_Complete__c==True&&acc.RecordTypeId==rtList[0].Id&&acc.status__c=='Active'){
     accountIds.add(acc.Id);
      }
    }
    
    Map<Id,Bulk_Product__c> bulkProdMap = new Map<Id,Bulk_Product__c>();
    List<Bulk_Product__c> bulkProdList = [Select Id,Bulk_Code__c,Bulk_acc__c from Bulk_Product__c Where Bulk_acc__c IN :accountIds and Bulk_Code__c = 'CCM' Limit 1];
    for(Bulk_Product__c bk:bulkProdList ){
     if(ag.Bulk_Code__c!=NULL){
      bulkProdMap.put(bk.Bulk_acc__c,bk);
      }
     }
    List<RecordType> rtList1=[Select Id from RecordType where SobjectType = 'Task' and Name = 'BB Tasks' Limit 1];  
   List<Account>  accList = [select id,ownerId,Name,Agent_Id__c,Status__c,RecordtypeId from Account Where Id IN:accountIds and RecordTypeId=:rtList[0].Id Limit 1]; 
     for(Account acc:accList){
     if((trigger.isUpdate)&&bulkProdMap.containsKey(acc.Id)){
     task t1 = new task ();
     t1.RecordTypeId = rtList1[0].Id;
     t1.ActivityDate = Date.today()+2;
     t1.Status = 'Not Started';
     t1.Description = 'New Contract----------------. Please make personal contact with the agent';
     t1.Subject = 'New Contracted Follow Up';
     t1.OwnerId = acc.ownerId;
     t1.WhatId = acc.Id;
     t1.Priority = 'High';
     taskToInsert.add(t1);
    
     }
     
  if(taskToInsert.Size()>0){
       insert taskToInsert;
       }
 
    }      
 }
uma52551.3972270309784705E12uma52551.3972270309784705E12
Sorry in the above trigger it is after update. so please let me know what was my mistake
sandeep sankhlasandeep sankhla
Hi Uma,

you can simply fire this trigger on After Insert instead of after Update..with this it will only create a task once not always whenevr account is updated.....

P.S. If my answer helps you to solve your problem please mark it as best answer. It will help other to find best answer.

Thanks,
Sandeep
Salesforce Certified Developer 
Anupam RastogiAnupam Rastogi
Hi Uma,

Few considerations about the code that you have written - 

1. Whenever you are about the create a new record in some other object (like in your case it is Task) from a trigger based on a different object (like Account), always go for an 'after insert' event. The reason is, suppose for some reason the before insert/update event fails and errors out after the trigger execution is complete, your code would have already created the record in the other entity.

2. There is no need to use Trigger Context variables in case your trigger is based on only one event.

So to solve your problem for now, change the event of the trigger from 'before update' to 'after insert'. So the task is created only when a new Account is created. Also remove the if statement that checks for isUpdate.

I hope this explains a bit about the problem and solves it.

Thanks
AR

If the reply was useful and helped solve the problem, please mark it as best answer.
uma52551.3972270309784705E12uma52551.3972270309784705E12
Hi Anupam,

My trigger has to work as an update only. Because of few conditions and dependancy's on the bulk product object trigger should work for only update operation. And this update should insert task only once. If that perticular task is inserted then we have to track that and later when ever account is updated the trigger souldn't create another task. Please guide me!

Thanks,
Anupam RastogiAnupam Rastogi
Hi Uma,

If that is the case then you can check if a Task is already existing for the Account. Only when there is no pre-existing Task, the code should create a new Task for that Account on update. Here is the modified inner IF loop that you can use to replace the current IF loop.
 
if((trigger.isUpdate) && bulkProdMap.containsKey(acc.Id))
    {
        List<Task> eTask = [select Id from Task where WhatId = :acc.Id];
        
        if(eTask.size() == 0)
        {
            task t1 = new task ();
            t1.RecordTypeId = rtList1[0].Id;
            t1.ActivityDate = Date.today()+2;
            t1.Status = 'Not Started';
            t1.Description = 'New Contract----------------. Please make personal contact with the agent';
            t1.Subject = 'New Contracted Follow Up';
            t1.OwnerId = acc.ownerId;
            t1.WhatId = acc.Id;
            t1.Priority = 'High';
            taskToInsert.add(t1);
        }        
    }

Additionally, I have coupld of questions here.

1. When does the Task gets 'Completed'?
2. And should a new Task be created for the Account if the Status of all existing Tasks for that Account are with Status = Completed?

If the answer to the second question above is 'Yes', then you can include a condition for checking the Status of existing tasks as well like shown below - 
 
if((trigger.isUpdate) && bulkProdMap.containsKey(acc.Id))
    {
        List<Task> eTask = [select Id from Task where WhatId = :acc.Id and Status = 'Completed'];
        
        if(eTask.size() == 0)
        {
            task t1 = new task ();
            t1.RecordTypeId = rtList1[0].Id;
            t1.ActivityDate = Date.today()+2;
            t1.Status = 'Not Started';
            t1.Description = 'New Contract----------------. Please make personal contact with the agent';
            t1.Subject = 'New Contracted Follow Up';
            t1.OwnerId = acc.ownerId;
            t1.WhatId = acc.Id;
            t1.Priority = 'High';
            taskToInsert.add(t1);
        }        
    }

Thanks
AR

If the reply was useful and helped solve the problem, please mark it as best answer.
 
This was selected as the best answer
uma52551.3972270309784705E12uma52551.3972270309784705E12
Hi AR,

Thanks For your code. I am still having few issues with the above code. As per your suggestion "if a Task is already existing for the Account. Only when there is no pre-existing Task, the code should create a new Task for that Account on update" But if there is already a task created by another trigger/workflow/Manually in that account then this trigger won't work. This trigger will always check for Zero tasks condition which is not correct in all situations. And comming to task status : in my case task should be in 'not started' state. I think we have to do it in other way to track the task. Thanks!
Anupam RastogiAnupam Rastogi

Hi Uma,

The scenario you have mentioned in absolutely possible. And to handle it as well, the best way is to use a custom field at the Task (Activity) level. Whenever a task is created from the UI, default this field value to something like 'UI', else when creating a task using this specific Trigger, default it to something like 'TaskInsertTriggerOnAccount'.

Now in the code do the following - 
 
if((trigger.isUpdate) && bulkProdMap.containsKey(acc.Id))
    {
        //--- Here Record_Source__c is the new Custom Field at the Task (Activity) Object
        List<Task> eTask = [select Id from Task where WhatId = :acc.Id and Record_Source__c = 'TaskInsertTriggerOnAccount'];
        
        if(eTask.size() == 0)
        {
            task t1 = new task ();
            t1.RecordTypeId = rtList1[0].Id;
            t1.ActivityDate = Date.today()+2;
            t1.Status = 'Not Started';
            t1.Description = 'New Contract----------------. Please make personal contact with the agent';
            t1.Subject = 'New Contracted Follow Up';
            t1.OwnerId = acc.ownerId;
            t1.WhatId = acc.Id;
            t1.Priority = 'High';
            taskToInsert.add(t1);
        }        
    }

You can use something similar to this for the new Custom Field - 
Field Name: Record Source
Type: Text
Length: 100
Default Value: 'UI'
Visible To: Only Admin for reporting purposes

This way you will always be able to identify exactly whether a Task has been created for the Account earlier or not by this Trigger.

I think this should definitely resolve your problem.

Thanks
AR

If the reply was useful and helped solve the problem, please mark it as best answer.
uma52551.3972270309784705E12uma52551.3972270309784705E12
Hi AR,

Thank you so much my problem solved with out adding custom variable. Thank you once again. I have taken the idea of querying task object and adding task size to the if condition.
 
Anupam RastogiAnupam Rastogi
Great!

But Task can be created for other reasons as well, isnt it? So how have you used the size to check whether you should create a new task or not?
uma52551.3972270309784705E12uma52551.3972270309784705E12

Hi Anupam,

Yes you are right. Task can be created for mutliple reasons but here I am filtering the tasks by the subject equals to 'New Contracted Follow Up' so if there is any task exists with this subject then don't insert task else insert task. I mean I am taking tasks size with the above filter if this size()==0 then insert the task else don't insert. Please let me know if this is not correct in the long run!