Yumi Ibrahimzade from the blog Salesforce Time has written a post explaining how to use flow to add a mass delete button to a list view. Pay special attention to the second solution that avoids performing DML inside a loop by using a custom action that can be found in the collection actions here on UnofficialSF
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Tamar Erlichhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngTamar Erlich2021-08-11 14:31:332021-08-11 14:31:36From Yumi Ibrahimzade: Using Flow to Mass Delete Records from List View
Do you hate food recipe blogs that go on and on about a special story about how they grew up smelling grandma’s cooking and getting frustrated because you just want to get the recipe? Your kids are crying, the garlic and onions are burning, and you finally get to the recipe but it’s covered by an ad on your phone and the browser crashes.
This is not that post. Let’s get right to it!
I recently wrapped up work on a nifty action called ‘FindCommonAndUncommonRecords’ that can compare two like/unlike record collections based on a unique identifier that you specify. It then can provide 4 outputs providing records unique and shared between the two collections based on the identifying fields you provide.
The thoughts and solutions in this post are my own and not that of Salesforce.
Scenario
The action can take a bit of effort to wrap your head around so I created a scenario showing off a hypothetical model involving Accounts and two custom objects, Gas Stations and Gas Station Relationships. An Account can be related to many Gas Stations through the Gas Station Relationships custom object.
Let’s say you build a screen flow that lets the user associate whatever Gas Station they want to the Account (using Datatable or a Lookup component). You will be creating these Gas Station Relationship records to set up that relationship. The catch here is that there are already Gas Stations tied to the account, but you have no way of filtering those out of the datatable/Lookup easily.
The user picks 4 gas stations to associate to Blackbeards Grog Emporium:
Station 17
Station 55
Station 23
Station 3
We then run this new action to get the Gas Stations not tied to the Account, or in other words the records unique to the selected collection by the user.
targetUniqueCollection (Gas_Station__c) – The gas stations unique to the selected gas stations compared to the account’s related gas stations. Returned as Gas Station records.
Station 55
Station 23
Station 3
targetCommonCollection (Gas_Station__c) – The gas stations shared between the account and the selected gas stations. Returned as Gas Station records.
Station 17
sourceUniqueCollection (Gas_Station_Relationship__c) – The gas stations unique to the account compared to the selected gas stations. Returned as Gas Station Relationship records.
Station 45
Station 66
sourceCommonCollection (Gas_Station_Relationship__c) – The gas stations shared between the account and the selected gas stations. Returned as Gas Station Relationship records.
Station 17
From here, you can safely loop over the ‘targetUniqueCollection’ (the unique records selected by the user)to build your junction records without dupes!
Sample Image
This image is a simplified example of two collections being input to the component with four collections being output by the component. The letters represent the value of the designated source or target fields.
Tutorial Video
Inputs
sourceRecordCollection – The first collection you want to compare
Type – Record Collection
sourceUniqueID – The field API name / identifier you want to use to find records in the ‘target’ collection (Case Sensitive)
Type – Text
targetRecordCollection – The the second collection you want to compare
Type – Record Collection
targetUniqueID – The field API name / identifier you want to use to find records in the ‘source’ collection (Case Sensitive)
Type – Text
Outputs
sourceUniqueCollection – The unique records in the source collection when compared against the target collection
Type – Record Collection
sourceCommonCollection – The shared records between the two collections, returned as the specified source Output sObject type.
Type – Record Collection
targetUniqueCollection – The unique records in the target collection when compared against the source collection
Type – Record Collection
targetCommonCollection – The shared records between the two collections, returned as the specified target Output sObject type.
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Adam Whitehttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngAdam White2021-02-03 07:31:072023-11-02 07:30:13Compare & Contrast Two Record Collections with 'FindCommonAndUncommonRecords'
With the advent of System-context screen flows I can’t help but think of the famous phrase ‘With great power comes great responsibility’. When running screen flows in system context, you could inadvertently grant Read or Edit access to a critical system field to the wrong audience. Let’s say you wanted to do some cool stuff like in Jen Lee’s recent post about Community User Management, and you want to ensure the person running the flow has the ‘Manage External User’ permission. Her flow does this check using a custom permission, which is totally fine, this just checks the system permissions directly.
All of that is possible with some straightforward SOQL queries against the Permission Set Assignment object. You may or may not be aware, but the PermissionSet object actually contains Profile permissions as well so it’s a one-stop shop for getting Field and System permissions!
Run an action to check a field permission
The following example will run you through a VERY basic scenario where a Flow presents a screen to update a given field and the flow is running in System context – God mode.
We let the user pick an Account Rating in a basic Flow screen with a picklist radio button
We run the ExecuteSOQL action to check if the running user has ‘Edit’ permission for the Account Rating field.
For older versions of ExecuteSOQL that return an ’empty’ collection we assign the count of the results to a number field
We then do a decision to see if the number of permissions assigned to the user is > 0.
We then either show a screen that says you cant edit it or we move on with updating the field.
Flow Overview
Most of you can probably handle the beginning and end – so I’ll provide some more color on the middle part that does the permission checking.
You’ll want to construct your query using a Plain Text text template variable:
SELECT AssigneeId,PermissionSetId,Permissionset.Name,Permissionset.Profile.Name FROM PermissionSetAssignment WHERE Assignee.Id= ‘{!formulaRunningUserID}’ AND PermissionSetId in (Select ParentId from FieldPermissions where SobjectType = ‘Account’ and Field = ‘Account.Rating’ and PermissionsEdit = true)
*WARNING* If you make any edits to the text template variable, a Flow bug will revert the template back to rich text and it will break the action! Make sure you revert it to Plain Text after every edit.
Next up is to make the ExecuteSOQL action:
Here’s an example result from the action above that returns the permission granted by the System Admin profile when run as myself.
(For older versions of ExecuteSOQL only) You’ll then want to assign the results to a number since older versions of ExecuteSOQL return an empty collection if no results are found. Make sure you set the default value to 0 when making the variable.
Use an ISNULL check if you’re using the latest and greatest.
Create your decision and you’re done!
Checking multiple fields
You could of course extend this to multiple fields in one query by modifying the SOQL query, for example:
SELECT AssigneeId,PermissionSetId,Permissionset.Name,Permissionset.Profile.Name FROM PermissionSetAssignment WHERE Assignee.Id= ‘0051I000000UB4LQAW’ AND PermissionSetId in (Select ParentId from FieldPermissions where SobjectType = ‘Account’ and Field in (‘Account.Rating’,’Account.Type’) and PermissionsEdit = true)
System permission checks
You can also check for specific system permissions! Let’s say you wanted a Flow embedded on the Case layout that manages the Contact’s community user record. The query below could be used to check if the user handling the case has permissions to manage the external user account:
SELECT AssigneeId,PermissionSetId,Permissionset.Name,Permissionset.Profile.Name FROM PermissionSetAssignment WHERE Assignee.Id= ‘{!formulaRunningUserId}’ AND PermissionSetId in (Select Id from PermissionSet where PermissionsManagePartners = true)
https://unofficialsf.com/wp-content/uploads/2020/06/FlowOverview.png497955Adam Whitehttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngAdam White2020-06-09 10:00:592020-06-09 10:19:31Tutorial: Check field and system permissions in screen flows when using System Context using ExecuteSOQL
This action can be used to generate a list of record types for a specific object. This can be useful when you would like to present a record type selector to the user. Can be used as inputs to the QuickChoice by setting Input Mode to “Dual String Collections”. Pass in one output collection for Labels and one for the underlying values
Inputs
Attribute
Type
Description
Object Name
String
API name of the target object example “Task” or “MyObject__c”
ignoreMasterRecordType
Boolean
If “on” then “Master” will not be added to the list of record types
onlyReturnActiveRecordTypes
Boolean
If “on” then only active record types will be added to the list
onlyReturnRecordTypesAvailableToCurrentUser
Boolean
If “on” then only record types available to the current user will be returned
Outputs
Attribute
Type
Description
errors
String
captures details of any error that occurred
recordTypeIds
String
Ids of the records types.
recordTypeNames
String
Names of the record types.
defaultRecordTypeName
String
defaultRecordTypeId
String
Installation
1.1 Unmanaged 5/13/21 – Added outputs for the default Record Type
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Tamar Erlichhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngTamar Erlich2020-01-19 09:13:412021-05-13 15:14:05Get Record Type Info by Object - Flow Action
Narender Singh form ForcePanda wrote a two blog series about using map collections in flows. The second blog makes good use of the new generic sObject support in flows coming in the Spring ’20 release
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Tamar Erlichhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngTamar Erlich2019-12-18 05:51:502019-12-18 06:56:59How to create a Map collection in Flows by Narender Singh
A common need in Flows is to be able to redirect the user to a new record that may have been created in the Flow. This new Lightning Flow Action can be used to redirect the user to the specified record in either View Mode or Edit Mode.
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Eric Smithhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngEric Smith2019-09-19 12:29:112019-09-19 12:38:48Navigate to a Record in View or Edit Mode at the end of a Flow
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Tamar Erlichhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngTamar Erlich2019-05-20 07:52:042019-05-20 07:52:05How to do more with Custom Permissions in Salesforce Lightning Flows by Scott McClung
The other day I built a flow action that generates random numbers. While doing it, I recorded the process, because we don’t have a lot of tutorial material on how you can turn a chunk of useful Apex code into a nice, declarative flow action.
For a general introduction to the invocable action interface, check this out.
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Alex Edelsteinhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngAlex Edelstein2018-10-07 18:33:302019-02-03 02:24:37How to Build a Flow Action with Apex