function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
tengeltengel 

Flow finishLocation equal to originating record

I'm having difficulty setting the finishLocation of a flow. I would like users to return to the originating Account record from which they started the flow from upon clicking the Finish button.

 

I have an object with a master-detail relationship to Account. In the object's related list on the Account, I have a custom button. When clicked, the custom button loads a Visualforce page with a flow:interview embedded in it. Here is the button's URL structure:

 

https://na4.salesforce.com/apex/UWRScheduler?acct_id={!Account.Id}&acct_name={!Account.Name}

 Here is the Visualforce page without any finishLocation set:

 

<apex:page standardController="Account">
        <flow:interview name="UWScheduler" />
</apex:page>

 Here's what I have tried:

 

Attempt1: In the custom button, set the retUrl=%2F{!Account.ID}
Result1: Upon clicking Finish in the flow, I loop back to the first flow screen, and the URL = /apex/UWRScheduler?sparkID=UWScheduler

 

 

Attempt2: Set the following in the Visualforce page:

finishLocation="{!URLFOR($Action.Account.View, Account.Id, null, true)}"

Result2:

Invalid parameter for function URLFOR
Error is in expression '{!URLFOR($Action.Account.View, Account.Id, null, true)}' in component <flow:interview> in page uwrscheduler

 

Attempt3: Set the following in the Visualforce page:

finishLocation="{!URLFOR('/{!Account.Id}')}"

 Result3: Clicking Finish in the flow logs me out of Salesforce!

 

Please help! My first flow is almost complete!

Best Answer chosen by Admin (Salesforce Developers) 
DarrellDDarrellD

The finishlocation isnt quite right.  You just have URLFOR/Variable.  But I haven't used URLFOR enough to tell you what it should be. I'm going to put my current working code below.  In our case we have a user creating a new record inside the Flow and wanted them to end up on the record that they just created.  So pretty much same as you, but one thing is that for this we had to use a VF extension.  In your case I don't think you need to do that since you want them to just end where they started.

 

VF Page:

<apex:page standardController="Account" extensions="flowFinishContExt_Acct" tabStyle="Account">
<!-- Checks for object accessibility -->
<apex:pageBlock rendered="{!$ObjectType.Account.accessible}">

<flow:interview name="FacilityLookup" interview="{!FacLookupFlow}" buttonLocation="both" buttonStyle="color:#990000" finishLocation="{!FinishPage}">
<apex:param name="vaentrypoint" value="EnterNewFacility"/>
</flow:interview>
</apex:pageBlock>

 

Extension for Finish Page:

public class flowFinishContExt_Acct {

private final Account acct;

//Uses Standard Account Controller
public flowFinishContExt_Acct(ApexPages.StandardController stdController) {
this.acct = (Account)stdController.getRecord();
}

//Calls referenced Flow below
public Flow.Interview.FacilityLookup FacLookupFlow {get; set;}

//Gets Id of variables below from flow
public String getaccountID() {
if (FacLookupFlow==null) return '';
else return FacLookupFlow.vafacilityid;
}

//Used for Flow finish location
public PageReference getFinishPage(){
PageReference p = new PageReference('/apex/FacilityMainTabbed?id=' + getaccountID());
p.setRedirect(true);
return p;
}

}

All Answers

DarrellDDarrellD

It's going to look a little more like attempt 3. But what you want to do is assign the initial account I'd to a flow variable and then use the flow variable, not the {Account.id} field as your finish location.  Also see my post below about returning variables back from a Flow.

 

http://boards.developerforce.com/t5/Visual-Workflow/Flow-variables-not-passing-back-to-VF-Controller-Extension/m-p/504513#M803

tengeltengel

Thanks for replying, Darrell. That doesn't seem to work either, though. When I click Finish in the flow, I get logged out of Salesforce. The flow does what it's designed to do (create records), but the final action just isn't happening as expected.

 

In the flow, I assigned the Account ID to the variable acct_id. Here is what my VF page looks like:

<apex:page standardController="Account">
        <flow:interview name="UWScheduler" finishLocation="{!URLFOR('/{!acct_id}')}" />
        <p>Test</p>
</apex:page>

 Maybe there is something essentially faulty with my flow? As I mentioned, this is my first flow so I wouldn't be surprised! The end result of the flow creates either 4 or 12 new records, depending upon decisions made in the wizard.

DarrellDDarrellD

The finishlocation isnt quite right.  You just have URLFOR/Variable.  But I haven't used URLFOR enough to tell you what it should be. I'm going to put my current working code below.  In our case we have a user creating a new record inside the Flow and wanted them to end up on the record that they just created.  So pretty much same as you, but one thing is that for this we had to use a VF extension.  In your case I don't think you need to do that since you want them to just end where they started.

 

VF Page:

<apex:page standardController="Account" extensions="flowFinishContExt_Acct" tabStyle="Account">
<!-- Checks for object accessibility -->
<apex:pageBlock rendered="{!$ObjectType.Account.accessible}">

<flow:interview name="FacilityLookup" interview="{!FacLookupFlow}" buttonLocation="both" buttonStyle="color:#990000" finishLocation="{!FinishPage}">
<apex:param name="vaentrypoint" value="EnterNewFacility"/>
</flow:interview>
</apex:pageBlock>

 

Extension for Finish Page:

public class flowFinishContExt_Acct {

private final Account acct;

//Uses Standard Account Controller
public flowFinishContExt_Acct(ApexPages.StandardController stdController) {
this.acct = (Account)stdController.getRecord();
}

//Calls referenced Flow below
public Flow.Interview.FacilityLookup FacLookupFlow {get; set;}

//Gets Id of variables below from flow
public String getaccountID() {
if (FacLookupFlow==null) return '';
else return FacLookupFlow.vafacilityid;
}

//Used for Flow finish location
public PageReference getFinishPage(){
PageReference p = new PageReference('/apex/FacilityMainTabbed?id=' + getaccountID());
p.setRedirect(true);
return p;
}

}

This was selected as the best answer
415montgomery415montgomery

DarrellD, can you also share the test class for the code please? Thanks.

DarrellDDarrellD

Well the test for the VF page is about the best could accomplish given that you cannot instantiate a Flow from a test class...yet.  I got some help from SalesForce on this to get my code coverage up a bit.  I bolded the relevant part for the Controller Ext and VF page.

 

/**
This code tests the AddressTypeEntryNew VF Page
Calls appropriate VF Page
Cannot instatiate a Flow from test as of Winter 13. Will need to add when possible

Tests:
testAddressEntryNew

*/
@isTest
public class FlowFinishControllerExtension_Test {

static testMethod void testAddressTypeEntryNew_AddApplyMethod() {
System.debug('Starting AddressTypeEntryNew...');

//Use the PageReference Apex class to instantiate a page
System.debug('AddressTypeEntryNew - Setup page reference');

// Uses test file to create accounts
List<sObject> testAddressType = Test.loadData(ONE__Address_Type__c.sObjectType, 'testAddressTypes');

//Verify that all 200 test accounts were created
System.assert(testAddressType.size() == 200);

//Get 1st test record
ONE__Address_Type__c at1 = (ONE__Address_Type__c)testAddressType[0];
String addrtypeName = at1.Name;
System.debug(addrtypeName);

PageReference AddrTypePageRef = Page.AddressTypeEntryNew;
Test.setCurrentPage(AddrTypePageRef);

ApexPages.StandardController controller = new ApexPages.StandardController(at1);
flowFinishControllerExtension controllerExt = new flowFinishControllerExtension(controller);
string TestStr=addrtypeName;
controllerExt.getFinishPage();
controllerExt.getAddressTypeId();

// Run Tests
// Cannot instatiate a Flow from test class as of Winter 13 so not much to test here. Eventually should call Flow.
System.test.startTest();
System.debug('AddressType_Test - Add AddressType');
System.debug('AddressType_Test - Save');
System.test.stopTest();

}
}

Jeff BloomerJeff Bloomer

Here's what worked for me.  I also have a flow that starts from the Account screen.  The code for my button is:

 

/apex/Customer_Service_Request?txt_AcctID={!Account.Id}

 Then, the code I used for my Visualforce page was:

 

<apex:page >
    <flow:interview name="Customer_Service_Request" finishLocation="/{!$CurrentPage.parameters.txt_AcctID}"/>
</apex:page>

 Works like a charm for me.

Kerry TownsendKerry Townsend

Hi 

 

I am trying to do a very similar thing to tengel. On Finish I would like my Flow to return to the Opportunity record it was started from.

 

I have created a visualforce page for my Flow. I have created a Detail button on the Opp that points to the visualforce page to start the Flow. I have created a controller extension that retrieves the Opportunity ID that I pass in. Unfortunately the URL that is created at the end is not correct.

 

On finish the exit URL is

https://c.cs17.visual.force.com/apex/CreateInstalmentFlow?id=006g0000002FIWc

 

but I need it to be:

https://cs17.salesforce.com/006g0000002FIWc

 

The fact that the correct ID is in the URL means that the code to retrieve it must be correct. Therefore I think it is the path I am constructing that is wrong.

 

The path is constructed using the following, it is something that I have not used before:

 

PageReference p = new PageReference('/' + getoppID() );

 

Please can you advise on what I need to change to get to the correct URL.

 

Page:

 

<apex:page standardController="Opportunity" extensions="takeMetoOppFlowController" tabStyle="Opportunity" >
    <flow:interview name="Setup_Instalments" finishLocation="{!FinishPage}" >
        <apex:param name="varOpportunityID" value="{!Opportunity.Id}"/>
    </flow:interview>
</apex:page>

 

Class:

 

public class takeMetoOppFlowController {

public takeMetoOppFlowController(ApexPages.StandardController controller) {

}


public Flow.Interview.Setup_Instalments mySetupInstalments {get; set;}

public String getoppID() {
if (mySetupInstalments==null) return '';
else return mySetupInstalments.varOpportunityID;
}

public PageReference getFinishPage(){
PageReference p = new PageReference('/' + getoppID() );
p.setRedirect(true);
return p;
}

}

 

 

Thanks

DarrellDDarrellD

I think your finishlocation has to be more like in the solution post above for the thread.

 

/Used for Flow finish location
public PageReference getFinishPage(){
PageReference p = new PageReference('/apex/FacilityMainTabbed?id=' + getaccountID());
p.setRedirect(true);
return p;

 

So you probably need:

PageReference p = new PageReference('/?id=' + getoppID()

MalgorzataMalgorzata
I know it has been an old post and the answer has been already provided. For anybody interested in having the logic in Visualforce page using URLFOR function, for the Attempt3 from the intial post, moving Account.Id parameter outside the  string between quotes worked for me, for example:
<flow:interview name="UWScheduler" finishLocation="{!URLFOR('/'+ Account.Id)}"/>
I hope it might be helpful if you do not need to add addtional logic in custom controller or controller extension.
codeman73codeman73
the answer from @Malgorzata worked for me; thanks for updating this issue with a simpler solution