Date: Fri, 29 Mar 2024 13:23:33 +0000 (UTC) Message-ID: <2083264663.7.1711718613660@75311961dcc9> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_6_633000220.1711718613659" ------=_Part_6_633000220.1711718613659 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
Other Pages on Flow Triggers
IN PROGRESS= - TO BE UPDATED FOR WINTER '22
Before-Save Flows - much rejoicing was had wh= en the Spring =E2=80=9820 release notes first came out=E2=80=A6 but are the= y all they are cracked up to be=E2=80=A6 let=E2=80=99s investigate. But fir= st, have you seen a Before-Save Flow demo video (apart from mine) that does= anything more than updating one or two fields=E2=80=A6 let=E2=80=99s get r= eal here, in the real world we need do to soooo much more.
After-Save Flows were also released in Summer '20. Winter 21 release had=
a few new features but were still not enough to move Process Builders to F=
lows. In=20
Spring =E2=80=9821 Winter '22 I think we are finally there! I wi=
ll update this post with tips and tricks as I migrate all my complex calcul=
ations to Flow from Process builder. (Let=E2=80=99s start with Percentage Fields in Flows weirdness).
Display Validation Rules correctly. Geezus. Who ever thought the current= way Flows fail with a validation rule is acceptable? Still not good in= Winter '22.
Be easily able to update data for duplicate management without having to= write a trigger. Yep!
More clarification or less confusion over the whole =E2=80=9COne Process= Builder per Object=E2=80=9D rule and =E2=80=9Cdon=E2=80=99t mix Flow, Proc= ess Builder, Workflows and Triggers=E2=80=9D rule. I don=E2=80=99t necessar= ily subscribe to these rule, but that needs a whole other post (Flows - Question Everything) and what I learn her= e might change my thoughts. (disclaimer: I don=E2=80=99t work in large ente= rprise orgs, so I=E2=80=99m only talking about small to medium sized orgs w= ith small to medium sized complexities). This is going to be way more valid= for After-Save Flows also. There is some documentation on this topic n= ow in the Architect Decision Guides, and I have started writing about this = in Flow Triggers Naming and Grou= ping .
Maybe getting away from DLRS=E2=80=A6 I love DLRS and now that it has be= en taken on by Salesforce Commons, it live son. And sometimes it=E2=80=99s = flaky and sometimes it causes issues (again this probably needs a whole oth= er post). I=E2=80=99m still going to use DLRS.
The =E2=80=9CAlways=E2=80=9D updates - the fields that are like formulas= but the formula is > 5000 character compile size so it needs to be an u= pdate. This is the whole basis for my Multiple ways to run Flows for multiple records talk at Ja= pan Dreamin. Now, the caveat to this is building formulas in Flows SUCKS! e= ven worse than building formulas in Process Builder! This is NOT addres= sed yet as at Winter '22. However Salesforce Enhanced= Formula Editor can now be used in a limited way in Flows.
Make it easy to do a criteria like =E2=80=9CIf all of these fields are n= ot entered then don=E2=80=99t allow the stage to be changed=E2=80=9D. When = you can=E2=80=99t fit all of your criteria into a formula this becomes a pa= in to manage because you have to manage both setting the validation field A= ND clearing the validation field when the record is subsequently edited to = NOT match the validation. I need to do another post on this - currently= working on something.
After Update queries (obvs)
Chatter Posts, Notifications and Email Alerts
Platform Events
Subflows!!! (Not Possible with After-Save Flows!)
Workflows on Long Text or Rich Text Areas (see below)
Creating new related records or updating related records
Invocable Actions
Things I will still only use Workflow for=E2=80=A6
Time-based Workflow
The implementation of time based updates in Flows is terrible. If it h=
as less features and is less reliable and is less customisation than existi=
ng functionality why would I use it? It is just bad.
Email Alerts, if there are a lot of emails being automated
Who=E2=80=99s stupid idea was it to have seemingly orphaned email alerts= because you can=E2=80=99t see that they are used in Process Builders? And = it=E2=80=99s not even in the Where is it Used functionality.
Email Alerts can now use Lightning Email Templates in Spring '21 but= they are still orphaned in the UI!
Where a complex formula is used more than once
Nope, Invocable Process Builders are just a waste of time, and see above= re formulas in Flows=E2=80=A6 I sometimes just want to stick with what I k= now works. (May be less of an issue with the ability to run Apex in Flows, = and the release of the Automation Components).
Long Text and Rich Text Fields
You STILL cannot build record triggered flows that are triggered based o= n the contents of a long text or rich text field. Eg I have a field named I= nstructions and another field named InstructionsExcerpt that is used to val= idate if Instructions is filled in. InstructionsExcerpt is updated every ti= me the Instructions is Edited and IF it is not null. This will stay as a wo= rkflow. You need to have an after-save flow that is triggered ALWAYS, then = include a decision in that Flow. I=E2=80=99m not sure it=E2=80=99s worth it= unless you have another Always After Save Flow.
Foiled again! Dammit!
Just because
Why would I rebuild anything that is already fully functioning in Workfl= ows=E2=80=A6 (nice to see this reiterated by Jen Lee in the Architect blog post)
A small sidebar=E2=80=A6
I have a client with very complex currency calculations that of course a= re more than the 5000 compile size limit. We had a major structural change = to the object so it was best to create a new object to refactor the databas= e (to more closely mirror the external system we are integrating with). Thi= s was just 12 months ago so Process Builders are well entrenched and are de= finitely the way things are =E2=80=9Cmeant=E2=80=9D to be done.
All the formulas were basically the same. So this is a great opportunity= to move everything to the recommended way of doing things right=E2=80=A6= p>
Well, what a nightmare. The record was so slow to save (no delay in savi= ng the same formulas in workflow rules) that I had to severely restrict whe= n the fields were updated, which has caused issues with people not believin= g the data they see=E2=80=A6 very understandable.
So now I have to either rebuild everything in flow triggers, or get righ= t to it and code all these highly complex formulas (that do change based on= government legislation changes for example. And yes, we did just have a hu= ge change in government legislation due to Covid).
So we have a process that needs to update some values, create some recor= ds, notify another user, add a chatter post to the record and send an email= . So we are going to have the updates in the Before-Save Flows then have th= e rest of the bits in After-Save Flows=E2=80=A6 Isn=E2=80=99t this breaking= the rules? Well maybe not, since Before-Save flows have their own place in= the Order Of Execution before everything so it=E2=80=99s almost like we ar= e removing the load of those updates from the Process Builders=E2=80=A6 but= is it still going to be slow because of all the other things? The updates = would not be a heavy load on the whole transaction in that scenario. (But w= e can now use Asynchronous After-Save Flows so this may be a good option he= re).
Think of the classic scenario why they told us that Process Builders wer= e sooo much better than Workflow Rules - where you have different field val= ues based on different criteria. So I have exactly this scenario. I have 6 = fields that can be different values based on one field that has 7 different= options - basically it's a picklist with a list of presets and you choose = that and it goes and sets all these other fields with the right values that= make an external system function. Am I going to have to do all those combi= nations in one formula in Flow? No, decisions in Before Save Flow shoul= d do the trick now.
Does =E2=80=9CWhere is this Used=E2=80=9D work for Assignment Elements i= n Flow? (I don=E2=80=99t think so).
Are Flow Triggers bulkified? I don=E2=80=99t see how they are when they = run once for every single record. Check the Architect Decision Guides o= n this=E2=80=A6
My first foray into Before-Save Flows was in a pre-release scratch org w= here I made a quick video about changing from a= regular flow to a Before-Save Flow.
Over the next few releases I tried again, but just had to give up. I am = now starting fresh in Spring '21.
You can=E2=80=99t Debug EVERYTHING in Record triggered Flows!!!!
You can=E2=80=99t select an Email in the Flow Debugger (why is it a sele= ction box rather than a text box).
Add an Assignment element named Error as the last element in the flow. M= ake an error happen in this Assignment item (eg set RecordID to a blank val= ue) and turn on the Debug Log. This saved me big time!
The full value of a record is in the Debug Log=E2=80=A6 now this would b= e the same if you added all field value variables but it is a bit of an eye= opener and makes you definitely think about the data security of your debu= g logs - especially if you are using things like the De= bugging in SFDX options.
Wow. Having to select the $Record with a mouse (I can=E2=80=99t find a k= eyboard shortcut to quickly expand it and start typing the field name), is = such a PITA.
Of course this is an issue with ALL flows, and is one of the things that= makes me hate flows, and makes me hate building formulas in flows,
You can=E2=80=99t use CMDT in Formulas=E2=80=A6
So there is a work-around but it requires completely rethinking your= CMDT - ensure the CMDT has enough fields to be able to select the right re= cord with a Get Records that returns only one record. Then you can get the = fields from that CMDT record.
Example
Case({!ThisRecord.MyFieldHourOrDay__c},
"H",$CustomMetadata.MyMD__mdt.Scenario1HourID.ExID__c, "D",$CustomMetadata.=
MyMD__mdt.Scenario2DayID.ExID__c,
0),
It=E2=80=99s OK if you=E2=80=99ve got one of these, you can do that in a= formula, but when you have 15 combinations to look through to choose the r= ight MDT record, the formula gets too big.
Before-Save Flows don=E2=80=99t trigger on Deletion (I had not gotten to= the point of considering this yet, but one commenter raised this as an iss= ue). After-Save Flows do though.
When setting defaults in Before-Save Flows don=E2=80=99t do what I did a= nd overwrite what users have already entered. Ensure you do something like:=
IF(ISBL= ANK(TEXT({!$Record.YourField__c})),"Default Value,TEXT({!$Record.YourField_= _c}))
You can now set defaults for record Owners and Currency ISO Codes??? May= be? (I need to check this). You can=E2=80=99t set these in Quick Actions (But you may be able to set these = through the new URL Hacks also).
You can use Before-Save Flows to set values for Duplicate Rules - such a= good use of these Before-Save Flows!
You CAN use Formulas in record triggered flows, just be aware of the Got= chas! See Formulas in Flow Triggers
=The new thing of being able to see Flows (and Process Builder) in Time-B= ased Workflow is a complete game-changer. No need to use Workflow for Time = dependant actions anymore. Though why it took this long for Process Builder= to be in there, I will never understand.
HOWEVER, you can NOT search on Object. So ensure the Name of the Flow ha= s the Object in it. See Flow Triggers= Naming and Grouping for naming suggestions.
Naming Convention: See Flow Trigge= rs Naming and Grouping for tips on Naming your Flows
Ensure you don=E2=80=99t accidentally assign a value that will ALWAYS se= t the value to that and will never allow the value to be set to anything el= se. Eg as shown in the Release Demo Video for Before-Save= Flows!
Create a Checkbox on your record (eg Disable Auto Update for Before-Save Flows), default False=E2=80=A6 Set this as the first Cond= ition in your Flow=E2=80=A6 just in case you need a way to opt out. (or use= CMDT or Custom Settings. See Monica=E2=80=99s best= practice video).
Are there fields that always should be entered? If so, put these into a = Before-Save Flow for Create only, rather than running this each time it=E2= =80=99s updated (except if it changes of course - this is more for default = values).
You can maybe turn off field required-ness on create for some fields tha= t you can now set through these flows. (or event better, requiredness may b= e able to be set through Dynamic Forms= and Dynamic Actions)
If you are doing a Before Create and Before Update in the same Flow then= ensure you use a Decision Element before you do a Get Records on a related= Object, so your flow does not fail when that lookup field is not filled in= (or when the value is cleared in an Update).
Decide what happens after the record gets to a certain status - eg Close= d Won Opp, or Closed Case. Do these flows run then?
Duplicate the Final Assignment Element, stick a Decision before it for t= he Status / Stage and only set those values that MUST be changed after that= Status / Stage.
Or use a Lock Record Flow Action on a regular = Flow to lock the record (hmm, if Before-Save runs before even Before trigge= rs, does the regular record lock feature even prevent Before-Save updates f= rom happening? And how does Lock Record work if Flows are run in System Con= text - all this needs to be tested, do not take my word for it).
Turn a Before-Save Flow conditionally into a Before Update or Before Cre= ate by checking for the existence of the $Record.Id. Rather than maintainin= g two flows=E2=80=A6 maybe=E2=80=A6 check if it slows things down.
Check your formulas for what happens when there is a null value. The res= ulting field will be Null. Do you want it to be null or 0.
My Scenario
For the Contract Fee I have a Percentage Field and a Base Rate. If the P= ercentage Field is not filled in I want the Contract Fee to be null. But If= I enter a 0% Percentage then I DO want the Contract Fee to say $0.
In formulas this is as simple as checking the Treat Blank Fields as Blan= k box (or otherwise), but you have to handle it yourself in Flows.
Note: The Architect Decision Guides say DO NOT use After-Save Flows for = single record field updates=E2=80=A6 this is not practical at all.
When one of the fields has a value set that is based on a formula contai= ning a field that is set by DLRS or Trigger. After Save Flows happen after = Triggers.
You CAN NOT use formulas that include values from any other field set by= the Before-Save record. Think of the field as being null always and every = time you edit the record this field value is going to be set again. Not= e, I need to check this now that I=E2=80=99ve worked out you CAN use formul= as in Before-Save flows. Oh wow, it looks= like it works!!! See Formulas in= Flow Triggers for more details on this=E2=80=A6
In my scenario above. I enter the Base Rate - it is never set in my Assi= gnments in my Flow. I always set my Contract Fee based on the Percentage an= d the Base Rate.
But what if I have another formula that I want to calculate Contract Tot= al that is added as the Base Rate plus the Contract Fee.
If the formula for fContractFee is $Record.BaseRate__c * $Record.Percent= age__c
The formula for fContractTotal can not be fContractFee + $Record.BaseRat= e__c
It would have to be ($Record.BaseRate__c * $Record.Percentage__c) + $Rec= ord.BaseRate__c
(I=E2=80=99ve excluded all the null checks for clarity).
Then I have another formula that spells out the Contract Total in words = to display on the Contract documents. So I would have to put the full formu= la calculation for every part of the formula that requires any part of the = value. (For example see all these stupid formulas just for adding the dollar signs). Nope.
That=E2=80=99s all fine for simple formulas but for complex formulas tha= t is a need to go into After-Save Flows.
You use $Record_Prior to find the prior value of a field.
But you could come into strife - test it really well.
Think of the differences between setting a default and what the user int= ended to set.
My Scenario
On my Contract I have a field for the Signatory. The Default Signatory i= s set as a field on the Account. If I am creating a new Contract I always w= ant the Default. But if they change the Signatory away from the Default, th= en I do NOT want this Before-Save Flow to override their choice.
If the Contract is Activated, and the Default Signatory changes on the A= ccount, and I happen to update any field on a Contract after that, then I d= o NOT want the Signatory to change to the new Default Signatory from the Ac= count, I want it to always remain as the Signatory it was set as.
So, why not do this in a Before-Save Flow only for Create=E2=80=A6 yep t= hat is fine. But what if my Account changes before the Contract is Activate= d (eg the Contract needs to be for the Parent Account which is the National= Office, rather than the Branch Office. If I change the Account, I ALWAYS w= ant to set the Default Signatory again.
So this is probably where I would revert to doing a Before-Save Flow on = Create, then an regular Process Builder on Is Changed=E2=80=A6 it gets too = hard in a Before-Save Flow on Create and Update.
Not sure if any of these are valid=E2=80=A6 just trying to work through = them.
Decide what needs to go into Before-Save and After-Save and what needs t= o absolutely stay in Process Builder. See Below as to what needs to stay in= Process Builder.
Deactivate all your Process Builders, Workflow Rules, (triggers if neede= d) first, so you can see what is being set by this Flow only.
Decide on ALL the Decision elements you need and add them to your canvas=
Ensure you always do a decision to check for Blank Values IF the field i= s not required on Create.
Add a decision element for checking if $Record.Id is blank.
If there are only a few fields that need to be updated based on a Status=
, then do formulas instead of a decision element. Eg If two fields should o=
nly be updated if the Status is Draft and their values should remain the sa=
me in all other circumstances then build a formula like IF({!fIsDraft=
} =3D true, {!Account.MyField__c}, {!$Record.MyField__c})
.
Save regularly so you know if the formulas or $Record assignments are in= correct (why oh why oh why can=E2=80=99t it evaluate formulas as you click = OK, or have another button to evaluate the formula?).
Add your final Assignment at the bottom of the Canvas and don=E2=80=99t = tie it up to the rest until you have finished everything else.
The Final Assignment should only assign $Record elements, not other Vari= ables.
Create Formulas with the exact name of the API name of the field that is= to be updated with a f in front eg fContractFee (No, I do NOT have undersc= ores in my API names).
Think about your STOP criteria. These Assignments should only assign Var= iables, never Assigning $Record
Build all your formulas before you start adding them to your Assignment.=
Copy your Formulas over from Process Builder into a text editor and repl= ace the syntax in bulk.
Eg replace =E2=80=9C[Account].=E2=80=9D with =E2=80=9C{!$Record.=E2=80= =9D and
As you build your formulas, remove them from a copy of your Process Buil= der.
You can Delete. With great power comes great responsibility though!
<= /li>Conditional Chatter Posts!!!! Way more easier than Process Builder!
<= /li>Submit for Approval!
No Sub Flows
Runs even if nothing changes on the record (does triggers do this?)
<= /li>When to use Created or Created and Updated as separate Flows?
Without Subflows it=E2=80=99s difficult.
How will they work bulkified when the flow only runs on one record at a = time.
Are we still only meant to do one Flow per Object? As per above question= s.
How do all the new Flows Permissions affect all this?
No Sub Flows
No Bulkification
Can have flows with different permissions levels
Objects with different record types may be used for very different thing= s. Maybe have the first decision element being a STOP decision.
Pause or Wait in Flow - yes there is definitely valid reasons to use thi= s in headless flows - eg using the 0 minutes wait trick to do things in ano= ther transaction.
Workaround may be to use Invocable Apex or the new Asynchronous Flow Pat= h
Where I call a Flow - eg assigning a Topic to a record, I have that in a= generic Flow - I would have to make that an Invocable Apex instead.
More to be added here!