Skip to content

Instantly share code, notes, and snippets.

@douglascayers
Last active April 1, 2019 00:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save douglascayers/f72962c84314f78fac989a3abc8d77b9 to your computer and use it in GitHub Desktop.
Save douglascayers/f72962c84314f78fac989a3abc8d77b9 to your computer and use it in GitHub Desktop.
Simple batchable to compute the number of hours a case was open, taking into consideration BusinessHours. Can be scheduled to run hourly.
public class CaseOpenBizHoursBatchable implements Database.Batchable<SObject>, Database.Stateful {
private ID businessHoursId { get; set; }
public CaseOpenBizHoursBatchable( ID businessHoursId ) {
this.businessHoursId = businessHoursId;
}
public Database.QueryLocator start( Database.BatchableContext context ) {
// Idea behind this query is to get all open cases or
// cases that were closed yesterday or today. We consider records closed
// yesterday or today to ensure the scheduled job doesn't miss updating a case
// that may have closed in between job runs, particularly between job runs that
// span 11pm yesterday through midnight into next day.
// Understandably, this precaution also means any cases closed yesterday or today
// continously get queried until we move beyond that window.
return Database.getQueryLocator([
SELECT
id, createdDate, closedDate, Case_Open_Hours__c
FROM
Case
WHERE
isClosed = false
OR
closedDate = LAST_N_DAYS:1
ORDER BY
accountId
]);
}
public void execute( Database.BatchableContext context, List<Case> cases ) {
List<Case> casesToUpdate = new List<Case>();
for ( Case cs : cases ) {
DateTime now = DateTime.now();
DateTime startDate = cs.createdDate;
DateTime endDate = ( cs.closedDate == null ? now : cs.closedDate );
// compute difference between the two dates taking into consideration
// working hours, weekends, holidays, etc. of the BusinessHours record
Long milliseconds = BusinessHours.diff( this.businessHoursId, startDate, endDate );
// convert milliseconds into hours
Long hours = ( milliseconds / 1000 / 60 / 60 );
// don't unecessarily update a case if no new information here
if ( cs.Case_Open_Hours__c != hours ) {
// use a new case sobject variable so that precisely only
// the fields we want to set are populated
casesToUpdate.add( new Case(
id = cs.id,
Case_Open_Hours__c = hours
));
}
}
if ( casesToUpdate.size() > 0 ) {
// optimistically update as many of the cases as possible
// by not rolling back all cases if one fails to update
Database.DMLOptions dmo = new Database.DMLOptions();
dmo.OptAllOrNone = false;
// consider iterating save results to identify failed records
// and notifying someone
List<Database.SaveResult> saveResults = Database.update( casesToUpdate, dmo );
}
}
public void finish( Database.BatchableContext context ) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment