Find Next Business Day From a Specified Date

Find Next Business Day From a Specified Date

Last Updated on April 7, 2023 by Rakesh Gupta

Big Idea or Enduring Question:

We don’t want to work on Weekends or Holidays – we all get that! If so then, do you think our clients or prospects do?

If you are in doubt then try sending an Email to your prospects to buy a home on a Christmas! Or how about sending a contract renewal Email to your customers on the weekend? Success rate if these actions is not too difficult to estimate, is it?

You get my point.

This blog is a sequel to my previous blog, Skip Scheduled Flow on Weekends and Holidays, where we discussed how to find out if the specified target date occurs within business hours. This article will go one step further and explain how to determine the next business day from the given date by considering business hours and holidays.

Let’s start with a business use case.

Objectives:

In this article, the reader will learn the following:

  • When to use Apex Invocable action with Flow
  • Understand BusinesshHours class and its associated methods
  • Understand @InvocableMethod Annotation
  • How to call an Apex method using Flow to find out next date when business hours are open

Business Use case

Warren Mason is a System Administrator at Gurukul on Cloud (GoC). He created automation to send the automated email notification to the customer after opportunity creation.

The process works like a charm until Warren receives an enhancement request to send email alerts on the company’s working hours. Ouch!! We will help Warren to find out the next business day and store it in a custom field Next_workday__c on the opportunity object.

Automation Champion Approach (I-do):

While this can be solved using various automation tools like Apex Trigger and others, we will use Salesforce Flow and call an Apex method. To call an Apex method, add the Action element to your Salesforce Flow and select an Apex class with a @InvocableMethod Annotation.

In this article, we will use the call BusinessHours database class. Make sure to review it. Use the
nextStartDate method that returns the next date when business hours are open. If the specified target date falls within business hours, this target date is returned. As of Spring’23 release, it is not possible to directly access BusinessHours method from Flow, that’s why we are using the Invocable apex class.

Before discussing the solution, let me show you a diagram of the process at a high level. Please spend a few minutes going through the following Flow diagram to understand it.
Let’s begin building this automation process.

Guided Practice (We-do):

There are 4 steps to solve Warren’s business requirement using After-Save Record-Triggered Flow. We must:

  1. Set Business Hours and Holidays
  2. Create a custom field on the Opportunity object to store Next Workday
  3. Create Apex class and Test class
  4. Salesforce Flow
    1. Define flow properties for record-triggered flow
    2. Add action – call NextStartDate Invocable Apex Class
    3. Add Update Records element to the update the opportunity

Step 1: Setting Up Business Hours and Holidays

  1. Click Setup.
  2. In the Quick Find box, type Business Hours.
  3. Set Business Hours and Holidays, as shown in the following screenshot:

Step 2: Create a Custom Field on the Opportunity Object to Store Next Workday

  1. Click Setup.
  2. In the Object Manager, type Opportunity.
  3. Select Fields & Relationships, then click New.
  4. Select Date/Time as Data Type, then click Next.
  5. Enter Field Label and click the tab key, the Field Name will populate. 
    1. Enter the details:
      1. As a best practice, always input a description and Help Text
      2. Click on the Next button.
  6. Set the Field-level Security for the profiles.  
  7. Add this field to Page Layout.
  8. Click Save.

Step 3: Create an Apex class and Test class

Now, we have to understand a new Apex annotation i.e. @InvocableMethod. This annotation let us use an Apex method as being something that can be called from Flow and Apex. Invocable methods are called with REST API and used to invoke a single Apex method. Invocable methods have dynamic input and output values and support describe calls.

The NextStartDate class contains a single method that is passing the Date/Time to find if the target date is within the given business hours, the target date is returned. The returned time is in the local time zone. Create the following class in your organization.

  1. Click Setup.
  2. In the Quick Find box, type Apex Classes.
  3. Click on the New button.
  4. Copy code from GitHub and paste it into your Apex Class.
  5. Click Save.

public without sharing class NextStartDate {
    @InvocableMethod(label = 'Finds the next date starting from the target date when business hours reopens.' iconName='slds:custom:custom63')
    
    public static List<response> calculateNextStartDate(List<Request> requestList) {
        
        List<response> finalList = new List<response>();
        BusinessHours bh = [SELECT Id FROM BusinessHours WHERE IsDefault=true];
        
        for (Request req: requestList){  
            response resp = new response();
            resp.nextStart=BusinessHours.nextStartDate(bh.id, req.targetDate);
            finalList.add(resp); 
        }
        return finalList;
    }
    
    public class Request{
        @InvocableVariable(label = 'Target Date' required = true)
        public Datetime targetDate;
    }
    
    public class Response
    {
        @InvocableVariable (label='Next Start')
        public Datetime nextStart; 
    }
}

Step 4.1: Define Flow Properties

  1. Click Setup.
  2. In the Quick Find box, type Flows.
  3. Select Flows then click on the New Flow.
  4. Select the Record-Triggered Flow option, click on Create and configure the flow as follows:
    1. Object: Opportunity
    2. Trigger the Flow When: A record is created
    3. Set Entry Criteria
      1. Condition Requirements: None
    4. Optimize the Flow For Action and Related Records
  5. Click Done.

Step 4.2: Adding an Action to Call Invocable Apex Class

  1. On Flow Designer, click on the + icon and select the Action element.
  2. Select the NextStartDate Invocable Apex class.
  3. Enter a name in the Label field- the API Name will auto-populate.
  4. Set Input Values:
    1. Field: Target Date
    2. Value: {!$Record.CreatedDate}
  5. Store Output Values

    1. Field: Next Start
    2. Value: {!$Record.Next_Workday__c}
  6. Click Done.

Step 4.3: Adding an Update Records Element to Update the Opportunity

The next step is to update the opportunity next workday field. We will use the Update Records element. 

  1. On Flow Designer, click on the +icon and select the Update Records element.
  2. Enter a name in the Label field; the API Name will auto-populate.
  3. For How to Find Records to Update and Set Their Values select Use the IDs and all field values from a record or record collection
  4. Select Record(s) to Update
    1. Record or Record Collection: {!$Record}
  5. Click Done.


In the end, Warren’s Flow will look like the following screenshot:


Once everything looks good, perform the steps below:

  1. Click Save.
  2. Enter the Flow Label the API Name will auto-populate.
  3. Click Show Advanced.
  4. API Version for Running the Flow: 57
  5. Interview Label: Next StartDate {!$Flow.CurrentDateTime}
  6. Click Save.

Almost there! Once everything looks good, click the Activate.

Proof of Concept

Formative Assessment:

I want to hear from you!

What is one thing you learned from this post? How do you envision applying this new knowledge in the real world? Feel free to share in the comments below.

Have feedback, suggestions for posts, or need more information about Salesforce online training offered by me? Say hello, and leave a message!

Preferred Timing(required)

3 thoughts on “Find Next Business Day From a Specified Date

  1. I have updated the test class ‘line 27’ with your instruction.
    And I have received following:

    – The error message: ‘System. AssertException: Assertion Failed: Matching Date Time: Expected: 2023-04-09 15:00:00, Actual: 2023-04-10 00:00:00’
    – Stack Trace: (System Code) Class.NextStartDate_Test.calculateNextStartDate: line 27, column 1

    So, I have update the test class line 27 with the following:

    Assert.areEqual(DateTime.newInstance(2023, 4, 10, 9, 00, 00), nextStart, ‘Matching DateTime’);

    Then I have received result ‘Pass’.
    All thanks to inspiration from you.
    Thank you very much.

  2. HI~
    I’m getting a lot of inspiration from you.
    ‘Run Test’ this class is fail.

    The error message: ‘System. AssertException: Assertion Failed: Matching Date Time: Expected: 2023-04-09 21:00:00, Actual: 2023-04-10 00:00:00’

    Maybe it’s a matter of calculating local time.
    Here is South Korea. What should I do?

    1. Update the test class line 21 (You’ve to update the expected date/time) with the following:

      Assert.areEqual(DateTime.newInstance(2023, 4, 10, 00, 00, 00), nextStart, ‘Matching DateTime’);

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.