Monday, April 25, 2022

How to pass record Id(s) to Screen Flow

When users run flow, the best experience is to automatically grab the context instead of asking the user to enter some input. The most common place to start a Screen Flow is probably the record detail page, but how do we pass the current record information to the flow? All we need is a text input variable called recordId (Case Sensitive) in that flow.


With this, you can simply use the standard flow quick action to invoke the flow, and that current recordId will be passed into the flow.


Alternatively, you can define an input variable with any name, for example, input.

And define a URL custom button to invoke the flow (/flow/FlowName), to which you can attach the variable at the end of the URL using ?input={!object.Id}

For example, a button on the Account detail page passing the record Id to the input variable of flow named AccountName will look like this.



Depending on the use case we usually need an action to get the corresponding record from the Id.


The biggest difference between quick action and URL button is that the former will run in a modal, and the latter runs in full screen.

Similarly, we can actually pass selected record Ids to a list button.


The text input collection variable must be ids (Case Sensitive). Then you can create a list button calling the flow, like the previous example (/flow/FlowName), and you don't need to specify this variable, it's automatic. However, you may want to attach the return URL parameter to control where the user goes after the flow is finished, such as ?retURL=001/o which will redirect to the account list view page.


More examples are listed in the documentation 

https://help.salesforce.com/s/articleView?id=sf.flow_distribute_internal_url_retURL.htm&type=5

The challenge for these flows designed for multiple records will be how to manipulate them, depending on the use case, a loop may do the job, but sometimes you may need an Apex action to process them more efficiently.

Sunday, April 24, 2022

Making Flows More Flexible with Record Choice Set

Salesforce Flow is a great tool to automate business processes, and the best part is it can combine the MVC all together in one go. So we can build a flow with screens to interact with users and add the logic to handle the data. However, changes are inevitable for all kinds of processes, which leads to the question of how to make flows easy to maintain and adapt to changes.

For example, a client wants to collect some diet preferences when users launch the flow. It will be a list of options to pick from. However, the business changes the options frequently, and based on the chosen option, users need to see different following screens like different dishes. The most straightforward way is to build everything into the flow itself, or maybe pull the options from a picklist field or custom metadata types (CMDT). But with more questions involved, this pattern may get difficult to handle.

Let me explain with some pictures.

For example, I have a form with 3 questions. Question No.1 has 2 options A and B. If the user picks A, then the next one will be Question No.2. Option B leads to Question No.3.


You can easily put the logic into flow at this scale, and there is not much difference with the new pattern. However, imagine you have more questions like this:


You can still do it in the flow directly, but it is getting messy, and harder, especially for maintenance. And what about you have 15 questions, or more? You may end up with something like this:


It might look something cool to show off, but definitely not something nice to maintain, at least not for me. So what alternative can I have?


Solution

http://unofficialsf.com/scaling-to-thousands-of-screens-with-lightning-flow/

Inspired by the great article above, I recently figured out a new way to design flows. All it requires is to save the logic into 2 custom objects or CMDT (it usually requires admin to modify and does not support Rich Text) as records.

I named them Question Node (questions) and Question Node Outcome (answers).

Both of them need a Label field to hold the text of the question/answer. I used rich text type, so I can have more flexibility to control the format.

The Question Node needs to have a type picklist field, to distinguish if it's a choice question or some other types like number or date.

The Queston Node Outcome has two lookup fields to Queston Node, and they are the key for this pattern. I named them Parent Node and Target Node.

In this pattern, Each question is a Queston Node record, and each answer is a Question Node Outcome record. For the 3 question example above, I need 3 records of Question Node for each question. For Question No.1, there are 2 Queston Node Outcome records representing A and B. Both have Question No.1 as Parent Node, but Question No.2 and No.3 as Target Node respectively.


With the new pattern, no matter you have 3 questions or 300, the flow remains the same like this:


All the complexity is handled in those records because each Node Question Outcome has a target Question Node. When user runs the above flow, an initial Question Node record is passed as an input, and then the flow dynamically "Get" the next question based on the user's interaction. And the magic comes from the Record Choice Set resource in the flow.


In the above example, the Quesiion No.1 is the curNode, and this element will get Option A and B as choices. Depending on the user's choice, the next Node will be set as Question No.2 or No.3.

Remember I mentioned the type field on the question? It provides the criteria for the flow to identify the corresponding data to proceed. So other than choices, we can potentially collect number, date, and text answers as well. And that's why I have some decision nodes to check types in the above flow.

But how to capture the data collected in the flow? That's those assignment elements for. I have a text variable to be edited in the assignment, so each question-answer pair will be added to it as a new line. And it will generate a large string like this at the end:

Question1 Answer1

Queston2 Answer2

QuestionN AnswerN

Based on the use case, you may need to create or update records using the above information, but that needs some Apex involved to parse the data.


Limitations

The biggest limitation is that you can only place one question using Record Choice Set on each screen. Otherwise, the variable related to the record will only hold the last choice you picked.

It is hard to allow multi-select, but it is possible with Apex because you need to parse the selected answer and reverse it back to a collection variable.


Variety

This pattern can be used by combining the normal way to build flow. You can use just one object to hold those parameters that change frequently, and still build the logic into flow. So you can easily have the DML features or bypass the limitation of one question on each screen.


This article only shows the core implementation of this pattern. I have some ideas to enhance it, like adding field names into those choices, so potentially I build a JSON string at the end, which is easier to create and update records of any object. Anyway, the sky is the limit. 

Thursday, April 21, 2022

Open Process Builder as Flow

 

We all know that Salesforce will sunset workflow and process builder (PB) in the near future, and for workflow migration to flow, there's an official tool that will be GA next release. There might be something similar coming to PB eventually but for the moment I think we still need a decent amount of effort to "rebuild" them into Flow.

I recently got a task to rebuild a quite big PB (with quite a few decisions). Since it's saved as Flow in the metadata, I wondered if it's possible to edit it as a Flow. After some experiments, I figured out a hack to do this.

First, run a SOQL using Tooling API, in order to get the PB's Id.

SOQL:

SELECT  VersionNumber,  Definition.DeveloperName, Status,  id from flow where Definition.DeveloperName = 'Process_Name'

Then you can see a list of all the versions of that PB with corresponding Ids. Grab the one you want to rebuild (usually the latest version or active version), which looks like

'301xxxxxxxxxxxxxxx'

Finally, click any Flow in your Flow list to open its editor, and you'll see an url like

https://yourdomain.lightning.force.com/builder_platform_interaction/flowBuilder.app?flowId=301xxxxxxxxxxxxxxx

Simply replace the Id, and voila, the PB is opened in flow builder.

The layout may be ugly and messy when you open it, but you can easily get a good-looking version by changing the UI from Freedom to Auto-Layout.

Freedom



Auto-Layout



But it's not perfect yet, we still have a bunch of work to make it a record-triggered flow, starting with Save As button on the top right corner.


You will see an error immediately because Salesforce doesn't know what object it is.



It's easy to fix by selecting the same object of PB in the Start element.


You also need to change the trigger to match the original PB.

The next thing is to add an element to assign the record to the myVariable of PB after the Start element.



Depending on the elements in PB, you may still see some warning messages on the top right corner telling you some formula does not work, which requires your attention. Maybe some other performance issues, but you should be able to activate the Flow now.



Until now you have a quick and dirty Flow of the old PB. This should give you a better starting point for the rebuilding process. To properly migrate the PB, it's better to look through the logic and refactor it into Flow, and that's why I say this is a hack that should be only used with your own discretion.







Tips for Salesforce Certified Strategy Designer Exam

A little late to the party, but I just passed the latest Strategy Designer exam. Since it's a really new one (about one week old), there...