Here’s an example of a flow I created to automatically create multiple children records based on the data entered on the parent.
The Example
We track the deliverables of some of our products. We have two levels, a “Summary” of what they’ve been contracted and a “Contracted Deliverable” which gives the details of the status of each quantity. The challenge each Summary could have up to 8 child records created. The Initial data entry is done by folks who are not specialist on delivery. They’re simply helping with the data entry. This is great for those who are going to be modifying the data going forward, but it means very tedious work for those who are just getting the sets of records created.
Worse the children record start by just mimicking the data entered at the Summary level. So instead having them tediously click “Save & New” Seven times, I created some Code to go create the records.
Why Apex
I could create the records within Flow using the Record Create element. There is a limitation to this. First I would complicate the flow by having to have series of decisions to look at the value of Quantity field and determine if a record needs to be created. It would also require me to modify the flow each time I have to add a new quantity field. Who the heck needs that?
Apex allows me to use Dynamic Apex. I’m able to loop through the fields on the object. In this situation I loop through all the fields that start with “Quantity” and create children records. So “Quantity Banners” will have a child record associated to “Banners.” This allows me to write my code once. When I add my next field, I don’t have to update anything as long as I follow my Naming convention. So “Quantity Awesome” will automatically get children records created associated to “Awesome.”
I could skip flow all together and use a trigger. The challenge is I cannot assume that when the record is first created or updated that the user is ready for the children records to be created. I could add a “create records” check box field and filter my trigger logic, but that seems so inelegant. Plus, it’ll add an extra field that only gets needed that one time and no one else but the code cares about.
Enter Flow!
To embedded Apex within Flow we require a global class. The Code is pretty straight forward. This global class is there to handle the input and output variables to and from the flow and to pass information to my working class. I put all the code with Dynamic Apex and record creation in a separate class, but that’s a different post.
Here’s the code that get’s embedded in the flow.
global class Deliverable_Flow_Util implements Process.Plugin{ global Process.PluginResult invoke(Process.PluginRequest prRequest) { //Get Values from Flow string SummaryID = (string)prRequest.inputParameters.get('SummaryID'); //Get the ID of the Summary Record that will be the parent //Create map for return Map<String,Object> mapResult = new Map<String,Object>(); //Deliverable_Creation_Class.CreateDeliverables(SummaryId); Deliverable_Creation_Class DCC = new Deliverable_Creation_Class(); //Instance of the class that does the work DCC.CreateDeliverables(SummaryId); //method that does all the work system.debug('FlowUtil Success: ' +DCC.IsSuccess); system.debug('FlowUtil eMSG: ' + DCC.eMSg); //debug of status system.debug('FlowUtil RecordCount: ' + DCC.RecordCount); //Debug of num records created mapResult.put('IsSuccess',DCC.IsSuccess); //Set Parameter in map mapResult.put('eMSG', DCC.eMSG); //Set Parameter in map mapresult.put('RecordCount',DCC.RecordCount); //Set Parameter in map return new Process.PluginResult(mapResult); } global Process.PluginDescribeResult describe() { Process.PluginDescribeResult pdrResult = new Process.PluginDescribeResult(); pdrResult.Name = 'DeliverablesCreation'; //Flow name pdrResult.Tag = 'APEX Helpers'; //Category in Flow Explorer //InputParams pdrResult.inputParameters = new List<Process.PluginDescribeResult.InputParameter> { new Process.PluginDescribeResult.inputParameter('SummaryID',Process.PluginDescribeResult.ParameterType.ID, true) }; //Output Parms - Puts out the output parameters that return to the flow pdrResult.outputParameters = new List<Process.PluginDescribeResult.OutputParameter> { new Process.PluginDescribeResult.OutputParameter('IsSuccess', Process.PluginDescribeResult.ParameterType.BOOLEAN), new Process.PluginDescribeResult.OutputParameter('eMSG', Process.PluginDescribeResult.ParameterType.STRING), new Process.PluginDescribeResult.OutputParameter('RecordCount', Process.PluginDescribeResult.ParameterType.INTEGER) }; return pdrResult; } }
The Flow Itself
The flow is very simple. We start with a confirmation screen. Clicking next calls our Apex Method. The user will then be presented with either a Fault, a Success, or an Error screen. The fault occurs when the Apex method fails completely. Our Success screen well provide a success message followed by the number of records that was created. The error message appears when only some of the records were created.
The Completion
The end result is a very cool data completion process. A user creates the summary, confirms the values and then click! All the related data is completed for them. By marrying APEX and Flow together, I have reduced the end-users data entry time by a good 5 minutes. This adds up very quickly!
Marrying Flow and APEX together could work a number of ways. I could take advantage of flow screens to add some additional variables or user input to modify the records that are created. This same method could be use for other “mass updates” of child records. For example, I could use flow input fields to change the owner or update the status of multiple records without having to also create a Visualforce page.
So what does this look like? Here’s a silent video of what this looks like from an end user’s stand point: https://www.youtube.com/watch?v=MrVItQjTEGA
How about you? What use cases can you think of?
Set Up Your Own “MVP”Office Hours For Your Own Users
-
[…] Apex and Flow a Match Made For Awesome […]
Leave a Reply
Reblogged this on SutoCom Solutions.
Thanks Brian! I would love to learn more about this topic, as always your insight is super useful and makes things so much easier on everyone!
Hi Brian, thanks for this posting. I actually found got to it from this morning’s “Happy New Year” posting. This is very cool. Can I take a look at the CreateDeliverables helper class you referenced?
Thanks,
David
P.S. Happy new year 2015!
You’re welcome. I’m no longer at the company where I wrote this. I’ll see if I have a version from writing up the blog post.
Brian – Another very useful post. While researching the topic of having a Flow call Apex, I ran across this Salesforce documentation suggesting the use of @InvocableMethod annotation as it gives greater flexibility: https://help.salesforce.com/HTViewHelpDoc?id=vpm_designer_elements_apex.htm&language=en_US
Looks like @InvocableMethod just GA’d Spring 15: https://help.salesforce.com/help/pdfs/en/salesforce_spring15_release_notes.pdf
InvocableMethod is new for Spring’15. It can also be used to call Apex as an action from the Process Builder