1

I have a custom text field on Opportunity object by the name 'Opportunity Status' . Now when a Task is Created/Updated then I want my trigger to consider the top most 'Task' field 'Call Result' value to update in the strong text'Opportunity Status' field.

Now the normal behavior of the task record is that the Task with the highest 'Due Date' and then the 'Last Modified Date' is put on the TOP. See the below snip for reference.

enter image description here

What I need:

1) If I consider the above snip then I need value 'zzzzzzz' to update in the 'Opportunity Status' field.

2) If I update the due date of 4th task to '5/15/2016' then it will come on top. Then I want 'status Update 1' value to update on the 'Opportunity Status' field.

3) If I insert new task with due date as '5/16/2016' then I want its value to update in on the 'Opportunity Status' field.

4) Consider if I insert a task with due date as 5/14/2016 , the there already is a task with same date. So I am getting the below exception while inserting.

enter image description here

5) I am also unable to understand how to make my trigger handle bulk records in this situation.

Trigger Code:

Trigger TaskTrigger on Task(After Insert , After Update) 
{
    IF(Trigger.IsAfter)
    {
        IF(Trigger.IsInsert)
        {
            IF(TaskTriggerHelper.isExecuted1) 
            {
               TaskTriggerHelper.isExecuted1 = False;
               TaskTriggerHelper.UpdateOppStatusOnTaskUpdate1(Trigger.New);
            }
        }

        IF(Trigger.IsUpdate)
        {
            IF(TaskTriggerHelper.isExecuted2) 
            {
               TaskTriggerHelper.isExecuted2 = False;
               TaskTriggerHelper.UpdateOppStatusOnTaskUpdate2(Trigger.New);
            }
        }
    }
}

Trigger Class

Public Class TaskTriggerHelper
{
    Public Static Boolean isExecuted1 = True;
    Public Static Void UpdateOppStatusOnTaskUpdate1(List<Task> TaskId)
    {
        Set<ID> OppIds = New Set<Id>();

        For(Task T : TaskID)
        {
            IF(T.WhatId != NULL)
            {
                OppIds.Add(T.WhatId);
            }
        }

        List<Opportunity> OppList = [Select Id,Name,Opportunity_Status__c FROM Opportunity WHERE Id =: OppIds];
        Task MaxTask = [Select Id,ActivityDate FROM Task WHERE WhatId =: OppIds ORDER BY ActivityDate DESC Limit 1];        
        Date MaxDueDate = MaxTask.ActivityDate;
        List<Opportunity> OppToUpdate = New List <Opportunity>();  

        FOR(Task T1 : TaskId)
        {
            IF(T1.ActivityDate == MaxDueDate)
            {
                FOR(Opportunity OL : OppList)
                {
                    Opportunity Opp = New Opportunity();
                    IF(T1.WhatId == OL.Id)
                    {
                        Opp.Id = T1.WhatId;
                        Opp.Opportunity_Status__c = T1.CallDisposition;
                        OppToUpdate.Add(Opp);
                        System.Debug('---OppToUpdate---'+OppToUpdate);
                    }
                }
            }
        }
        Update OppToUpdate;
        TaskTriggerHelper.isExecuted1 = True;
    }

    Public Static Boolean isExecuted2 = True;
    Public Static Void UpdateOppStatusOnTaskUpdate2(List<Task> TaskId)
    {
        Set<ID> OppIds = New Set<Id>();

        For(Task T : TaskID)
        {
            IF(T.WhatId != NULL)
            {
                OppIds.Add(T.WhatId);
            }
        }

        List<Opportunity> OppList = [Select Id,Name,Opportunity_Status__c FROM Opportunity WHERE Id =: OppIds];        
        Task MaxTask = [Select Id,ActivityDate FROM Task WHERE WhatId =: OppIds ORDER BY ActivityDate DESC Limit 1];
        List<Task> TaskList = [Select Id,WhatId,CreatedDate,ActivityDate,CallDisposition FROM Task WHERE WhatId =: OppIds ORDER BY ActivityDate DESC];        
        Date MaxDueDate = MaxTask.ActivityDate;
        List<Opportunity> OppToUpdate = New List <Opportunity>();  

        System.Debug('---MaxDueDate---'+MaxDueDate);

        FOR(Task T1 : TaskList)
        {
            IF(T1.ActivityDate == MaxDueDate)
            {
                FOR(Opportunity OL : OppList)
                {
                    Opportunity Opp = New Opportunity();
                    IF(T1.WhatId == OL.Id)
                    {
                        Opp.Id = T1.WhatId;
                        Opp.Opportunity_Status__c = T1.CallDisposition;
                        OppToUpdate.Add(Opp);
                        System.Debug('---OppToUpdate---'+OppToUpdate);
                    }
                }
            }
        }
        Update OppToUpdate; **//This is line 80**
        TaskTriggerHelper.isExecuted2 = True;
    }
}

Please help me in understanding how to resolve my issue.

Thanks!

  • If there are few tasks for opportunity, you are adding single opportunity few times to the OppToUpdate and that is where does that fail – kurunve May 4 '16 at 12:33
0

I think you can achieve the same results if you collect the opportunity IDs, query them along with the relevant task in a subselect. If I'm not mistaken, this method should work both for after update & insert.

    Set<ID> oppIds = New Set<Id>();

    for(Task t : taskList)
        oppIds.add(t.WhatId);

    List<Opportunity> OppsToUpdate = New List <Opportunity>();  
    List<Opportunity> OppList = [SELECT Name, Opportunity_Status__c, (SELECT CallDisposition FROM Tasks ORDER BY ActivityDate DESC Limit 1) FROM Opportunity WHERE Id IN :OppIDs];

    for(Opportunity opp : OppList) {
        if(!opp.Tasks.isEmpty() && opp.Opportunity_Status__c != opp.Tasks[0].CallDisposition) {
            opp.Opportunity_Status__c = opp.Tasks[0].CallDisposition;
            OppsToUpdate.add(opp);
        }
    }
    update OppsToUpdate;
0

This is how you can bulkify the trigger.

trigger TaskTrigger on Task (after insert, after udpate)
{
   List<Task> tasks = new List<Task>();
   for (Task task : trigger.new)
   {
      //check any conditions needed.
       tasks.add(task);
   }
   TaskTriggerHelper.UpdateOppStatusOnTaskUpdate(tasks);
}
public class TaskTriggerHelper
{
    public static void UpdateOppStatusOnTaskUpdate(List<Task> tasks)
    {
        Set<Id> oppIds = new Set<Id>();
        for (Task task : tasks)
        {
            if (task.WhatId != null)
            {
               oppIds.add(task.WhatId);
            }
        }
        List<Task> tasksToCheck = [select Id, CallDisposition from Task where Id IN :tasks order by LastModifiedDate DESC];
        List<Opportunity> opps = [select Id from Opportunity where Id IN : oppIds];
        for (Opportunity opp : opps)
        {
           for (Task t : tasksToCheck)
           {
               if (opp.Id == t.WhatId)
               {
                  opp.Opportunity_Status__c = t.CallDisposition;
                  break;
               }
           }
        }
        update opps;
    }
}

As tasks are ordered by LastModifiedDate in Descending order the latest task is always on top whether is created or last updated. As soon as you find the right opportunity id from the inner loop set the opportunty status value and break out of the inner loop. The outer loop will then go to the next opportunity.

Hope this helps.

  • I think this will fail because not all Task.whatIds are of sobjectType Opportunity, the [select Id from Opportunity where Id IN : oppIds] will be where this failure occurs. The check any conditions needed will need to locate only Tasks whose whatId is an Opportunity – cropredy May 4 '16 at 15:34
0

You can filter the tasks that are related to the opportunity in the task trigger.

trigger TaskTrigger on Task (after insert, after udpate)
{
   List<Task> tasks = new List<Task>();
   for (Task task : trigger.new)
   {
     Id recId = task.WhatId;
     if (recId.getSObjectType() == Opportunity.SObjectType)
     {
        tasks.add(task);
     }
   }
   //pass the list to helper method
   TaskTriggerHelper.UpdateOppStatusOnTaskUpdate(tasks);
}

This way you are only working with the tasks that are related to opportunities.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.