+ Start a Discussion
StaciStaci 

time in a status

I currently have a trigger that accumulates time spent in each of our status/substatus combos.  The time accumulates when the status/substatus is changed to the next status/substatus, but until that is changed, the time spent isn't actually current.  Is there a way to update this trigger so that when I say refresh the browser it will update the time for the current status/substatus instead of waiting till the status/substatus changes?

Here's a snippet of the code
trigger CaseStatusChangeTrigger on Case (before insert, before update) {
    DateTime currentTime = DateTime.now();

    for (Case c: trigger.new) {
        try { // Catch any exceptions that occur on a particular Case, for display to the user
            if (c.Current_Status_Start_Time__c == null) {
                // The ticket isn't already tracking time.
                // This either means it's new (trigger.isInsert case below),
                // or that it's a legacy ticket that existed before this trigger rolled out.
                // In either case, the time tracking fields need to be initialized;
                // set them all to decimal zero values.
                c.New_Hours__c = 0.0;
                c.Open_with_Dealer_Hours__c = 0.0;
                c.Open_with_Support_Advocates_Hours__c = 0.0;
                c.Open_with_Product_Specialists_Hours__c = 0.0;
                c.Awaiting_Customer_Response_Hours__c = 0.0;
                c.Awaiting_3rd_Party_Hours__c = 0.0;
                c.Pending_RCA_Hours__c = 0.0;
                c.Pending_CPI_Hours__c = 0.0;
                c.Pending_NPI_Hours__c = 0.0;
                c.Accumulated_Duration_Pending_Change__c = 0.0;
                //c.Pending_Evaluation_Hours__c = 0.0;
                c.Other_Status_Substatus_Hours__c = 0.0;
                c.Awaiting_Access_to_Machine_Hours__c = 0.0;
                c.Accumulated_Dur_Await_Tech_Avail_Hours__c = 0.0;//Added by Staci on 3/26/20 #00006009
                c.Open_with_CPI_Hours__c = 0.0;
                c.Pending_Customer_Validation_Hours__c = 0.0;
                c.Pending_Dealer_Validation_Hours__c = 0.0;
                c.Awaiting_Change_hours__c = 0.0;
                c.Pending_T3_hours__c = 0.0;
                c.RCA_Open_with_Customer_hours__c = 0.0;
                c.RCA_Open_with_Dealer_hours__c = 0.0;
                c.RCA_Open_with_PS_hours__c = 0.0;
                c.RCA_Open_with_SA_hours__c = 0.0;
                c.Pending_Reoccurrence_hours__c = 0.0;
                c.Accumulated_Duration_Open_with_Cat_Supp__c =0.0; //Added by Ramesh on 16-Jan2017 #00005171
                c.Accumulated_Duration_RCA_Open_w_CS__c=0.0;//Added by Ramesh on 16-Jan2017 #00005171
                c.Accumulated_Duration_CER_Release__c=0.0;//added by Staci 4/11/2017 ENT 2873
                c.Accumulated_Duration_CER_Prioritization__c=0.0;//added by Staci 4/11/2017 ENT 2873
                c.Accumulated_Duration_CER_Evaluation__c=0.0;//added by Staci 4/11/2017 ENT 2873
                c.Accumulated_Duration_CER_Cust_Funding__c=0.0;//added by Staci 4/11/2017 ENT 2873
                c.Accumulated_Duration_CER_Cancellation__c=0.0;//added by Staci 4/11/2017 ENT 2873
              //  c.Accumulated_Duration_Reviewed_hours__c = 0.0;
              //  c.Accumulated_Duration_Init_Review_hours__c = 0.0;
              //  c.Accumulated_Duration_Dev_in_Prog_hours__c = 0.0;
              //  c.Accumulated_Duration_Clarification_Hours__c = 0.0;
              //  c.Accumulated_Duration_User_Acc_Test_hours__c = 0.0;
              //  c.Accumulated_Duration_Funded_hours__c = 0.0;
            }
            if (trigger.isInsert) {
                // New case creation, just start the clock on the initial New status
                c.Current_Status_Start_Time__c = currentTime;
            }
            else {
                Case oldCase = trigger.oldMap.get(c.Id);
                if (oldCase == null) {          
                    // Internal error - Can't find the old case to log the time
                    // This "should never happen" (famous last words)
                    // Log the error if debugging
                    System.debug('Error in trigger CaseStatusChangeTrigger:  Can\'t find oldCase ' + c.Id + ' in map');
                    // Also show the error to the user
                    c.addError('Internal error in Apex trigger CaseStatusChangeTrigger:  Can\'t find old Case for status/substatus comparison.  Please contact a GIS Salesforce Administrator to report this error.');
                }
                else {
                    // Normal Case update, log the time to the appropriate Status and Substatus combination
                    // First save the new and old Status and Substatus values for comparison
                    String newStatus = c.Status;
                    String oldStatus = oldCase.Status;
                    String newSubstatus = c.Substatus__c;
                    String oldSubstatus = oldCase.Substatus__c;
                    Decimal currentStatusStartTime;
                    // Also calculate the elapsed hours in Status and Substatus for the Case
                    Decimal elapsedSeconds;
                    if (c.Current_Status_Start_Time__c == null) {
                        currentStatusStartTime = c.Incident_Start__c.getTime();
                    }
                    else {
                        currentStatusStartTime = c.Current_Status_Start_Time__c.getTime();
                    }
                    if (currentStatusStartTime == null) {
                        c.addError('Internal error in Apex trigger CaseStatusChangeTrigger:  No Incident Start Time recorded for legacy Case');
                        elapsedSeconds = 0.000000;
                    }
                    else {
                        elapsedSeconds = currentTime.getTime() - currentStatusStartTime;
                    }
                    Decimal elapsedHours = elapsedSeconds / (60 * 60 * 1000);
            
                    // If the Status and Substatus are both unchanged, do nothing
                    // Otherwise (either Status, Substatus or both have changed),
                    // log time if in a loggable Status and Substatus combination
                    if (c.Status != oldCase.Status || c.Substatus__c != oldCase.Substatus__c) {
                        // Status or Substatus has changed, log time into the appropriate variables
                        // First close out the current (old) Status and Substatus combination
                        // by logging time into the appropriate bucket for that combination
                        if (oldCase.Status == 'New') {
                            // New Status:  Regardless of Substatus, log time into the New bucket
                            if(c.New_Hours__c != Null) {
                              c.New_Hours__c += elapsedHours;
                            }
                            else {
                                c.New_Hours__c = 0.0;
                                c.New_Hours__c += elapsedHours;
                            }
                        }
                        else if (oldCase.Status == 'In Progress') {
                            // In Progress Status:  5 trackable Substatuses with buckets for time
                            if (oldCase.Substatus__c == 'Open with Dealer') {
                                // Log into the "Open with Dealer Hours" bucket
                                if(c.Open_with_Dealer_Hours__c != Null) {
                                  c.Open_with_Dealer_Hours__c += elapsedHours;
                                }
                                else {
                                    c.Open_with_Dealer_Hours__c = 0.0;
                                    c.Open_with_Dealer_Hours__c += elapsedHours;
                                }
                            }
                            else if (oldCase.Substatus__c == 'Open with Support Advocates') {
                                // Log into the "Open with Support Advocates" bucket
                                if(c.Open_with_Support_Advocates_Hours__c != Null) {
                                  c.Open_with_Support_Advocates_Hours__c += elapsedHours;
                                }
                                else {
                                    c.Open_with_Support_Advocates_Hours__c = 0.0;
                                    c.Open_with_Support_Advocates_Hours__c += elapsedHours;
                                }
                            }

--------LOTS OF DUPLICATED CODE FOR EACH STATUS/SUBSTATUS----------
catch (Exception e) {
            // General exception in the trigger
            // This "should never happen" (famous last words)
            // Show the exception message to the user
            // Log the error if debugging
            System.debug('Exception in trigger CaseStatusChangeTrigger: ' + e.getMessage() + ' for Case "' + c.CaseNumber + '" (ID = ' + c.Id + ')');
            // Also show the error to the user
            c.addError('Internal error in trigger CaseStatusChangeTrigger: ' + e.getMessage() + ' for Case "' + c.CaseNumber + '" (ID = ' + c.Id + ')');
        }
    }
}

 
ANUTEJANUTEJ (Salesforce Developers) 
Hi Staci,

As the triggers run only when  an update or delete or insert is done to a record I don't think this would be possible with a record but you can certainly develop a lightning component that can listen to the refresh event and reload the data with the latest difference in time.

I hope this helps and incase if this comes handy can you please choose this as best answer so that it can be used by others in the future.

Regards,
Anutej
StaciStaci
Hi @ANUTEJ  We are still on classic so I'm assuming we can't use your suggestion?