Friday, April 18, 2014

Salesforce Flow Using Record IDs at the Start or at the Finish

Salesforce Flow can be combined with Visualforce pages to provide greater flexibility and automation to the user interface so that Salesforce users have fewer opportunities for mistakes. 
Racer X doesn't always like to start with the group.

 

Start

By invoking a Flow through a Visualforce page, you have the option to create a button on the particular object you intend to manipulate.  In this example, a button on the Lead object is configured to access a Visualforce page that invokes a Flow to convert the Lead.

Because the button exists on a specific record detail page, the standard controller makes the record ID accessible for the specific data being displayed when the button is clicked.  This means that the record can be converted without additional Apex code.  The Visualforce page would look something like this:

<apex:page standardcontroller="Lead" >

    <flow:interview name="LeadConversion">
            <apex:param name="thisLeadID" value="{!Lead.Id}"/>
    </flow:interview>

</apex:page>

 Finish

Finishing the Flow by bringing the user to a specific record detail page is more difficult. The easiest solution by far is to provide the information and actions the user needs as part of the Flow rather than as something they see after the Flow is finished. 

But even the complicated solution, adding Apex code to a custom Apex controller or extension to specify a finishlocation, is not too difficult.  Simple code enables Salesforce Flow to finish on record detail page. Even so, there are some considerations for defining a finishlocation:
  • Visualforce is required to specify a finishlocation and only URLs in your Salesforce instance can be specified within the finishlocation attribute on the Flow according to documentation
  • For variable finishlocations, an Apex controller is also required
  • Rather than referencing variables as part of the finishlocation, use a variable in place of a finshlocation on the Visualforce page
Here is a simple method to add to your Apex controller code to use a specific record ID in the finish location:

        public PageReference getpRefFinishLocation() {      

            String temp = 'home/home.jsp';
            if(myflow!=null) temp = string.valueOf(myflow.RecID);
            PageReference pRef = new PageReference('/' + temp);
            return pRef;

        }

Use code like the example above to access a variable, RecID in this case, from your flow and incorporate that into the URL for the page users see when they finish executing the Flow.

11 comments:

  1. I have a similar controller to get the newly created record ID from a flow to be referenced in a VF page that sets the finish location as the newly created record. The one thing I am stuck on, is writing the apex test class for the apex controller, as I don't think you can start the flow from apex. How were you able to create a test class for this?

    ReplyDelete
  2. Hi Michele,
    Here is the Salesforce doc on creating the unit test for page reference calls: http://www.salesforce.com/us/developer/docs/pages/Content/pages_controller_error_handling.htm

    ReplyDelete
  3. What about headless flows? I am working with a custom controller using good code examples similar to yours. However it does not work if you create a trigger ready flow.

    It does work if I add an ending screen to my flow but I do not want to do this as I am only updating a record and don't need to show anything just redirect the user to the modified record.

    The use case here is a custom button on a list view that will assign the oldest record to a user like a queue assigner. Would like to just run the flow and finish at the assigned record.

    ReplyDelete
    Replies
    1. Sorry for the delayed response. Where is your VF page going if it isn't going to the Finish Location? I get what you are trying to do, but if the finish location relies on the finish button to indicate when to redirect the user to a new page, then it won't work without user intervention. Programmatically, how does Visualforce know that the Flow is finished otherwise?

      Delete
  4. Can't you invoke a flow from Apex using flow.start() method?

    ReplyDelete
    Replies
    1. For anyone who isn't comfortable with Apex, Flow is a great alternative. I like to think of it as visual programing.

      Delete
  5. If there are 2 finish locations, 1 that asks them to finish and contact support due to their need being an urgent priority 1 need, and the second being after a case is created, is there a way to get the first finish to take them back home, while the 2nd takes them to the created case? When I click the 1st finish (since there is NOT a created case at that stage of the flow), it takes me to the:

    URL No Longer Exists
    You have attempted to reach a URL that no longer exists on salesforce.com

    screen, with a return URL of salesforce.com/null.

    Any help would be extremely appreciated!

    ReplyDelete
    Replies
    1. It sounds like you would want to have your finish location be a new VF page that has render option pulled from a parameter in the Flow, so it would then render message 1 or message 2 depending on what the Flow variable evaluates to.

      Delete
  6. I have created a flow on custom object filed updation (resource exit) to deactivate user and called it in Process builder (scheduled action)
    I am getting below error:
    DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User, original object:

    ReplyDelete
    Replies
    1. Hi Mangesh, I hope you found this post of mine, which might help: http://www.snugsfbay.com/2014/06/avoid-flow-trigger-errors-associated.html

      Delete
  7. Hi Bonny.

    I have a flow genrating an order from an opportunity. Once the flow finishes I want to take the user to the newly created order record. My flow copies a lot of information from the opportunity so my flow needs the opportunity ID as input. How do I pass my Opportunity ID to the flow via the VF page?

    ReplyDelete