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
PROCENTEC TechSupportPROCENTEC TechSupport 

How to track date/time of last activity within a case

Hello,

I know this has been discussed many times, however I cannot find an answer after breaking my skull open with this issue all day and yesterday. I have only been working with SalesForce for a week so forgive me if this is simple to do.

Problem:
Case.LastModifiedDate only reflects the date/time that the actual case was modified, and not the date/time of the last activity within a case.

My goal/solution:
Since Case.LastModifiedDate is a read-only field, I have created a custom field named Case.LastModifiedDateActivity. I want Case.LastModifiedDateActivity (DATETIME datatype) to be automatically updated (via Apex) whenever an employee performs an activity related to a certain case. (When the employee writes an email to a customer, makes a phone call, etc. in regards to a certain case).

Can someone help me implement this function? It is vital for our support team! 
Best Answer chosen by PROCENTEC TechSupport
kevin Carotherskevin Carothers
Hi,

You can try creating a simple trigger on your cases, along the lines of;

trigger CaseChanges on Case (before update) {
    for (Case c :System.Trigger.new) {
        if(c.Activity__c == 'Whatever it is I Care About') {
             c.LastModifiedDateActivity__c = Date.Today(); 
            }
        }
}

Since you're new to Salesforce, I feel I need to mention that you would write this in the sandbox, then write a test class for it, and then deploy both to production.

All Answers

ShashForceShashForce
Hi,

You can try this private appexchange package: https://appexchange.salesforce.com/listingDetail?listingId=a0N300000016cUoEAI

However, it will only do it for call logs. For email message, you can use a workflow rule on "Email Message".

Thanks,
Shashank
kevin Carotherskevin Carothers
Hi,

You can try creating a simple trigger on your cases, along the lines of;

trigger CaseChanges on Case (before update) {
    for (Case c :System.Trigger.new) {
        if(c.Activity__c == 'Whatever it is I Care About') {
             c.LastModifiedDateActivity__c = Date.Today(); 
            }
        }
}

Since you're new to Salesforce, I feel I need to mention that you would write this in the sandbox, then write a test class for it, and then deploy both to production.

This was selected as the best answer
PROCENTEC TechSupportPROCENTEC TechSupport
Thank you Shashank and Kevin.

Shashank - I have tried the touch up trigger script already, before posting this thread. As an Apex noobie, that script is too complex for me to integrate since I don't understand it that well. I was looking for something similar to Kevin's response, however that too won't fully work here.

Kevin - Your trigger script is exactly what I was getting at, unfortunately I don't think I can implement it since c.Activity__c does not exist for me. Here some pseudo code to represent what I need:

trigger TaskChanges on Task (after update) {
    for (Task t :System.Trigger.new) {
            parentCase.LastModifiedDateActivity__c = Date.Today();
        }
}

Since all activities in the internal ActivityHistory object (email, phone calls, etc.) will be handled in the same way, an if clause for the type of activity is not necessary. All activities should update the parent case's LastModifiedDateActivity__c field with the Today() / Now() functions so that we can track the newest activity within a case.

How can I modify the above pseudo code to actually identify the parent case and update it's LastModifiedDateActivity__c field? Also, you mentioned I should create a test class and debug it within an SF sandbox. Is the class necessary for this to function or was that just meant for test purposes? I am trying to find the smallest, easiest and most efficient solution for this issue since this will be my first piece of Apex code and overly complex scripts/solutions will dilute my understanding of what the code is actually doing.
PROCENTEC TechSupportPROCENTEC TechSupport
Perhaps this offers a bit of an improvement to the above pseudo code, since creating the t alias to represent that current task seems excessive:

trigger TaskChanges on Task (after update) {
            parentCase.LastModifiedDateActivity__c = Date.Today();
}
kevin Carotherskevin Carothers
Oh - I forgot to mention -- in that last block of code I posted, if a child case is also a parent of another child, and both are being ipdated (like in a bulk load) it will throw an error.  So there should also be a before insert trigger that makes sure that case doesn't happen. - or, I guess you could just insert a throw-catch  to catch any error that pops up.
kevin Carotherskevin Carothers
Well, the parameters have changed a little.....   
Going up and modifying the parent of a Case is a little difficult because it's polymorphic -- it can be either a Case, a Contact, or Activity.   So I don't think you can use a nested query to get to the value;  If anyone knows a better way to to this - please post it - as it's kind of a hack.  I think this code will allow you to do what you want;  But it  is untested -

It only tests for modified child cases that have a parent -- I think that's your use case....

trigger CaseChanges on Case (before update) {
    Map<Id, Id> pid = new Map<Id, Id>();
    Map<Id, Case> childMap = new Map<Id, Case>();
    List<Case> modifiedParentedCases = new List<Case>();
    
    for (Case c :System.Trigger.new) {  // build list of Case IDs
        if(c.ParentId != null)   {
           pid.put(c.Id, c.ParentId); 
           }          
        }
    
    List<Case> parentedCases = new List<Case>([Select Id, LastModifiedDate__c From Case Where Id in :pid.values()]);
    for(Id i :pid.keySet()) {           // map children with their parent Cases
        Id theParent = pid.get(i);
        for(Case p :parentedCases) {
            if(p.Id == theParent)  {
                childMap.put(i, p);
                }
            }
        }
                   
    for (Id i :pid.keySet()) {    // Build map  of parent cases that are affected
        if(Trigger.Newmap.get(i).Activity__c == 'Whatever it is I Care About') {
             Case c = childMap.get(i);
             c.LastModifiedDate__c = Date.Today();
             modifiedParentedCases.add(c);
             }
        }
    update modifiedParentedCases;   
}
Oh - I forgot to mention -- if a child case is also a parent of another child, and both are being ipdated (like in a bulk load) it will throw an error.  So there should also be a before insert trigger that makes sure that case doesn't happen. - or, I guess you could just insert a throw-catch  to catch any error that pops up.



Liam Smith 33Liam Smith 33
Hi PROCENTEC TechSupport,
I have the exact same need to have a date/time field update with the latest activity on a case. Except I have little experience with APEX triggers or classses. 
I was hoping you could share the code you ended up going with and perhaps a tip or two on creating the trigger/class?
It would be very much appreciated. 
Regards, 
Liam