In Automation, Blog, Flow, Tips & Tricks
You can do amazing things with Apex. You can modify and created hundreds of records. You can move data around from one record to another. You can pull data out of the metadata and use it write simply amazing things. You can create really awesome tools that help improve the user experience.
Apex can be used through a trigger (everytime a record is created, updated or deleted). It can be set to run on a scheduled basis. Apex can also be called through Visualforce on custom webpages. Apex is great for creating powering tools, but it can be limiting. Maybe you don’t want or need a full or embedded Visualforce page. Perhaps you don’t want your code to run when a record is saved. Perhaps you want to use a simple custom button. Normally, to use Apex with a custom button requires to use the Webservice which counts as a call against your limits.
Visual Flow can also create records and modify data. It can prompt the user for input that is only used within the flow and not saved. In Summer 13 flow is also limited. You can create records, but you cannot do loops. To accomplish some of things you can do easily within APEXmay require very complicated flows. You cannot harness the power of your metadata like you can with Dynamic APEX. At the same time, a flow is very easy to use. It is created by clicks and it can be called with a custom button with absolutely no visualforce required.
These two features are simply screaming to be used together. Why not marry the simplicity and easiness of Flow with the powerhouse that is Apex?

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.

An example of a summary

An example of a summary

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.

Visual of the Flow

Visual of the Flow

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?

Recommended Posts
Showing 7 comments
pingbacks / trackbacks

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.