Home » 2020

Yearly Archives: 2020

Salesforce Spring 21 Release – New Lightning Flow features

Salesforce Winter 21 Release – New Lightning Flow features

This posts summarizes most Winter 21 new features related to Lightning Flow. To test these new features now, you can sign up for a pre-release org here.

1- Trigger a Flow to Run Before a Record is Deleted

In Flow Builder, you can now configure a new record–triggered flow to run before a record is deleted. You no longer need to write Apex code to set this up. This autolaunched flow runs in the background and updates related records when a record is deleted.

2- Debug Autolaunched Flows Directly on the Canvas (Beta)

Now you can debug an autolaunched flow without opening a new browser tab. Just click Debug on Canvas (Beta) in Flow Builder and view the path the flow took during the debug run.

3- Build Multi-Column Screens in Flow Builder (Pilot)

Multi-column layouts have hit Flow Builder! You can use the new Section component to arrange your flow screen components into multiple columns without touching a single line of code. Divide each flow screen into multiple sections, and easily modify the number of columns in each section to create effective, visually appealing layouts. Contact your Account Executive if you’re interested in participating in the pilot.

4- Debug Flow Errors in Sandbox Org as Another User:

Debugging a flow in a sandbox org is now easier than ever with the ability to debug a flow as another user. When you debug a flow as another user, you can catch flow exceptions such as unexpected permission, sharing, and profile configurations before they occur in production orgs.

Note: to enable this feature, go to Setup – Process Automation Settings, otherwise you will receive the below. 

5- Improve the Performance and Precision of Record-Triggered Flows with Entry Criteria

Salesforce added entry criteria to record-triggered flows, giving you more control over your automation. Instead of configuring the flow to run every time a record is created or edited, you can now configure it to run only when condition requirements are met. This optimization can also significantly reduce your record-triggered flows’ impact on your org’s performance, depending on the flow.

6- Create Decision Outcomes that Only Execute When Certain Changes are Made

Now a flow triggered by a record update can take different paths if the record that triggered the flow was edited to meet certain criteria. When you configure a Decision outcome, you can now set that outcome to execute only when the triggering record is updated to meet the condition requirements. This feature allows you to filter out record updates that are unrelated to your flow’s use case, and to avoid reprocessing records that previously triggered the flow.

7- Use Auto-Layout to automatically place and connect elements in flow

The new auto-layout feature makes building flows and aligning elements easier. When auto-layout is enabled on a flow, elements in the canvas are spaced and connected automatically. No more elements positioned slightly out of alignment!

8- Access Related Record Data In Autolaunched Flows With Triggers Using $Record.

We do not need to have a Get Records flow element to retrieve associated record information. You can access the related data via the $Record element.

9- Quickly See the Triggers of Your Flows on the Flows Page in Setup

Now see which trigger your autolaunched flow has with just a glance at the Flows list view in Setup. In the new Trigger column, see if a flow’s trigger is a record, a schedule, or a platform event. For a record-triggered flow, see if it makes before- or after-save updates. You can also discover which trigger an autolaunched flow has by viewing the flow’s detail page.

10- Lightning Flow Run-Time Improvements in API Version 50.0

ISBLANK function returns true for empty string or null values

In flow and process formulas, the ISBLANK function returns true for empty string or null values. In flows and processes that run in API versions earlier than 50.0, the ISBLANK function returns true only when the value is null.

Enforce each flow screen’s Next or Finish control navigation setting

When Next or Finish is deselected in a flow screen’s control navigation settings, the screen no longer displays the Next navigation option to users. For flows that run in API versions earlier than 50.0, the Next or Finish setting isn’t always enforced. Specifically, screens always display the Next option when an element is in the flow after the screen.

Let merge fields support null record variables

Merge fields that reference record variables no longer cause errors when the record variables are null at run time. For flows that run in API versions earlier than 50.0, a merge field such as {!Account.Name} causes an error when the account record variable is null at run time.

Enforce the running user’s data access when a flow uses a merge field

This versioned update enables the Enforce Data Access in Flow Merge Fields release update for flows that run in API version 50.0. After the release update’s auto-activation, the update will be enforced for all flows regardless of their run-time API version. 

Treat invalid references to global variables as errors instead of string values

At run time, an invalid reference to a global variable now results in an error. In flows that run in API versions earlier than 50.0, invalid references to global variables are treated as string values. For example, suppose that a flow screen contains a Display Text component with this typo: Hello {!$User.FirstNaame}! If the flow runs in API version 50.0 or later, an error occurs when the Screen element is executed. If the flow runs in an API version earlier than 50.0, your users see “Hello {!$User.FirstNaame}!” on the screen.


To get the full Winter 21 release notes for Lightning Flow, please visit this link

All about Date and Time in Salesforce

Rule #1 – Every User in Salesforce has a Time Zone which is based on the region and adjusts automatically for DST

Whenever you create a new User in Salesforce, the Time Zone field should be populated as it is required, which means that every User has an associated Time Zone. In other words, no User can be created without a Time Zone! On top of that, the Company has a default Time Zone. 

You can set a User’s Time Zone in the User’s record, and to get your User’s Time Zone, run this in Anonymous Apex:

TimeZone tz = UserInfo.getTimeZone();
System.debug('Time Zone ID: ' +tz.getID());
System.debug('Time Zone Display name: ' +tz.getDisplayName());
// Returns:
// DEBUG|Time Zone ID: America/New_York
// DEBUG|Time Zone Display name: (GMT-05:00) Eastern Standard Time (America/New_York)

And to get the Organization default Time Zone, we use a SOQL query which returns the Time Zone Id, in my case “America/New_York”:

SELECT TimeZoneSidKey 
FROM Organization

Also, as you can see, the Time Zone is displaying a region, and not a difference in hours. So, the difference in hours will change according to the Daylight Saving Time! A Time Zone of “America/New_York” will change from UTC/GMT-04:00 to UTC/GMT-05:00 according to the DST. 

So what? What does this affect DateTime objects in Apex? Let’s visit the second Rule below. 


Rule #2 – DateTime objects are saved in GMT

In Salesforce, every time you instantiate and insert a DateTime object, it gets saved in the database in GMT Time Zone and it is translated to the user’s time zone when reading it. 

There are many ways to instantiate a DateTime object in Salesforce: using the DateTime class with many methods! The most popular method is DateTime.newInstance(year, month, day, hour, minute, second). This method constructs a Datetime from Integer representations of the specified year, month (1=Jan), day, hour, minute, and second in the User’s time zone. My User’s Time Zone is America/New_York, so everytime I instantiate a DateTime object using the newInstance method, I use this Time Zone as my reference, but remember, Salesforce only deals with GMT DateTime! To make it clear, check the below code, and keep in mind my User’s Time Zone. What do you think the debug outcome will be?

DateTime dt = DateTime.newInstance(2020, 01, 20, 15, 0, 0);

I am instantiating a new DateTime object of January 20, 2020, 3 PM. This will be based on my User’s Time Zone because I am using the method newInstance, and will be saved in the database in GMT! Yes, the input is based on the User’s Time Zone, but the actual record is saved in the equivalent GMT time, because GMT is used to save ANY DateTime object! For that, and because the difference between Eastern Time and GMT is 5 hours, the debug outcome is:

DEBUG|2020-01-20 20:00:00

But there are other ways to instantiate a DateTime object. For example, using DateTime.newInstanceGMT will treat the parameters as GMT, and the below 2 objects yield the same retult:

DateTime dtGMT = DateTime.newInstanceGMT(2020, 01, 20, 20, 0, 0);
DateTime dtLocal = DateTime.newInstance(2020, 01, 20, 15, 0, 0);
System.debug('GMT DateTime: ' +dtGMT);
System.debug('Local DateTime: ' +dtLocal);
// Returns:
// DEBUG|GMT DateTime: 2020-01-20 20:00:00
// DEBUG|Local DateTime: 2020-01-20 20:00:00

There is also a way to read the DateTime in any Time Zone that you want using the method DateTime.format. This method can take 2 parameters. The first one is the date format string, and the second is the Time Zone ID. The date format string specifies the format of the returned DateTime string. For more information on the Java simple date format, see Java SimpleDateFormat. The Time Zone Id should be a valid time zone of the Java TimeZone class that correspond to the time zones returned by the TimeZone.getAvailableIDs method in Java.

Datetime GMTDate = Datetime.newInstanceGmt(2011,6,1,12,1,5);
String strConvertedDate = GMTDate.format('MM/dd/yyyy HH:mm:ss', 'America/New_York');
// Date is converted to the new time zone and is adjusted for daylight saving time.
System.assertEquals('06/01/2011 08:01:05', strConvertedDate);


Rule #3 – If possible, try to avoid Datetime field, and use Date field instead

If your use case only requires a Date without a specific Time, do use the Date type instead of the DateTime type, that’s because the Date type does not care about anything related to Timezone. 

For example, let’s instantiate a Date and a DateTime objects:

DateTime dt = DateTime.newInstance(2020, 01, 20, 22, 0, 0);
Date d = Date.newInstance(2020, 01, 20);
System.debug('DateTime: ' +dt);
System.debug('Date: ' +d);
// Returns:
// DEBUG|GMT DateTime: 2020-01-21 03:00:00
// DEBUG|Local DateTime: 2020-01-20 00:00:00



  • Every User has an associated TimeZone
  • DateTime objects are saved in GMT in Salesforce 
  • A User will read a DateTime object depending on his/her TimeZone
  • Try to avoid DateTime if what you need is just a Date 

Scheduling a Salesforce autolaunched Flow

In the Winter ’20 release, Salesforce introduced scheduling autolaunched flows, which made it possible to schedule actioons decalatively within Salesforce. Prior to that, the only way to schedule anything in Salesforce was through Asynchgronous Apex, specificaly by implemeting the Schedulable interface. 

To schedule autolaunched flows, you need to specify the date and time the flow will run as well as its run frequency: once, daily, or weekly. Optionally, you can specify a specific Object with a filter that returns specific records of that Object, where the flow would run against. 

Here’s the session explaining scheduling Salesforce autolaunched flows, with 2 demos ar the end:

  1. Scheduling sending an email using the “Send Email” action
  2. Scheduling mass-updating Account records on a daily basis

These considerations apply to scheduled flows.

  • A scheduled flow starts at the specified time and frequency. You can’t launch a scheduled flow by any other means.
  • The Start Time field value is based on the org’s default time zone.
  • The View All Data permission is required to activate an autolaunched flow that has a trigger.
  • The maximum number of scheduled flow interviews per 24 hours is 250,000 or the number of user licenses in your org multiplied by 200, whichever is greater.

    If you specify an object so the flow runs for a batch of records, set the time, frequency, and record conditions to avoid reaching this limit. You can use debug logs to check how many records a scheduled flow runs on. Track the number of records with the FLOW_START_SCHEDULED_RECORDS event. If your org reaches the limit, Salesforce sends a flow error email.

  • If you delete a scheduled flow from the Scheduled Jobs page in Setup, all future recurrences of that flow are canceled. To enable future runs, deactivate and reactivate the flow.
  • A scheduled flow doesn’t run if it’s scheduled to run once with a date and time that has already passed.
  • The Automated Process user runs scheduled flows.
  • If you need a scheduled flow to invoke Apex code, don’t activate the Require User Access to Apex Classes Invoked by Flow critical update. When that critical update is activated, the scheduled flow fails when it invokes Apex.
  • If you configure an Update Records element to use the ID and all field values from the $Record global variable, enable Filter inaccessible fields from flow requests in your org’s process automation settings. Otherwise, the flow fails because the Update Records element tries to set the values for system fields and other read-only fields.
  • When you define multiple filters, the filter logic usually defaults to AND. However, if multiple filters have the same field selected and use the equals operator, the filters are combined with OR.

    For example, your filters check whether a case’s Type equals Problem (1), Type equals Feature Request (2), and Escalated equals true (3). At run time, the filters are combined to (1 OR 2) AND 3.