Implementing a Closed/Lost Reason on Opportunity

sales-ops-solutions-comic-strip-lost-the-deal1

A recent blog post by Jared Baker of Cloud My Biz suggests including a Lost Reason picklist field on your Opportunities to assist with understanding why some deals don’t close and allowing you to focus on better quality deals.  Here’s an overview of how I have implemented that for my Sales team.

Create a Picklist of Closed/Lost Reasons

Choose reasons that are meaningful to your organization and will provide useful groupings for your Reports and Dashboards.  Here’s my complete picklist for Lost/Cancelled Reason:

l1

In addition to a custom picklist field for Lost/Cancelled Reason, I also added these fields:

Field Type Description
Trigger_Lost__c Checkbox Use button/link to set this field to trigger the Closed Lost Process Builder and control the Reason picklist values
Closed_Lost_Notes__c Text Area Additional details on why the deal was lost
Competitor_Lost_To__c Picklist List of competitors

Special Processing Note:

I share the Visualforce page and fields outlined in this post to also handle reasons we might Cancel an Opportunity after it has been Closed Won rather than Lost.  The Closed_Lost_Reason__c field is a Dependent Picklist field controlled by the value of Trigger_Lost__c.  I control what selections are available based on the value of the Trigger Lost field.

capture

For more information on Dependent Picklists see:

Dependent Picklists

Try It Out: Create a Dependent Picklist

Add a Custom Button to Trigger the Lost Processing

gwi-opportunity-batchelder-brothers-hpbx-salesforce-enterprise-edition

My Lost button executes some JavaScript that sets my Trigger Lost field to True and opens a custom Visualforce page to collect data for my Reason, Notes and Competitor fields.

{!REQUIRESCRIPT("/soap/ajax/31.0/connection.js")}

var myquery = "SELECT Id, Name, Trigger_Lost__c FROM Opportunity WHERE Id = '{!Opportunity.Id}' limit 1";

sforce.connection.sessionId = "{!$Api.Session_ID}";
result = sforce.connection.query(myquery);
records = result.getArray("records");

var myObject = records[0];
var updateRecord = new Array();

myObject.Trigger_Lost__c = true;
updateRecord.push(myObject);

result = sforce.connection.update(updateRecord);

if(result[0].getBoolean("success")){
window.location = "/apex/Opportunity_Lost?id=" + "{!Opportunity.Id}";
}else{
alert('Could not Trigger Process: '+result);
} 

Provide a Visualforce Page to Collect Details for your Lost Fields

I created a simple page with only the fields I wanted to capture when setting an Opportunity to Lost.

capture

<!--
Shared Visualforce page used to present and collect reason for Opportunity
being set to either Closed Lost or to Cancelled.
Closed Lost Reason is a dependent picklist based on the value of Trigger Lost

Eric Smith - GWI - May 2016
-->
<apex:page standardcontroller="Opportunity">
<apex:messages />
<apex:sectionheader title="{!$ObjectType.Opportunity.label} Edit" subtitle="Lost/Cancelled Opportunity"/>

<chatter:feedwithfollowers entityId="{!Opportunity.Id}"/>

<apex:form >
<apex:pageblock mode="edit" title="{!$ObjectType.Opportunity.label} Edit">
<apex:pageblockbuttons >
<apex:commandbutton value="Save" action="{!Save}"/>
<apex:commandbutton value="Cancel" action="{!Cancel}"/>
</apex:pageblockbuttons>

<apex:pageblocksection title="Lost/Cancelled Details" showheader="true" columns="1">
<apex:outputtext label="Stage" value="{!Opportunity.StageName}"/>
<apex:pageblocksectionitem />
<apex:inputfield value="{!Opportunity.Closed_Lost_Reason__c}" required="true"/>
<apex:pageblocksectionitem />
<apex:inputfield value="{!Opportunity.Closed_Lost_Notes__c}" required="false" style="width: 500px; height: 100px"/>
<apex:pageblocksectionitem />
<apex:inputfield value="{!Opportunity.Competitor_Lost_To__c}" rendered="{!Opportunity.Trigger_Lost__c}" required="true"/>
<apex:pageblocksectionitem />
<!-- This next field needs to be on the page for the dependent picklist to work -->
<!-- 0px keeps it from displaying or being changed -->
<apex:inputfield value="{!Opportunity.Trigger_Lost__c}" style="width: 0px; height: 0px"/>
</apex:pageblocksection>

</apex:pageblock>
</apex:form>

</apex:page>

Special Processing Note:

Competitor Lost To is not rendered if I’m processing a Cancel rather than a Lost and Trigger Lost is on the page because it controls the values displayed in the Closed Lost Reason picklist.

Adding More Control with a Validation Rule

I didn’t want my users to be able to select Other as their reason without explaining why so I added a Validation Rule requiring 50 or more characters in the Closed Lost Notes field if they selected Other as their reason.

capture

Process Builder kicked off by Trigger_Lost__c

When the Lost button Javascript executes, it set the Trigger_Lost__c checkbox field to True and saves the Opportunity record.  That record change causes my Stage: Set Closed Lost Process Builder to execute.  The only action I’m currently doing there is setting my Opportunity Stage to Closed Lost.

capturecapture2

How do I use this Data?

Here’s a monthly report I run that lists all of my Lost or Cancelled Opportunities.  It is organized by what Stage the Opportunity was in before it was changed to Lost.

gwi-lost-cancelled-opportunities-salesforce-enterprise-edition

Go ahead and give this one a try

Adding this feature to your org will give you some good practical experience with Custom Buttons, Visual Force pages, Dependent Picklists, Validation Rules, Process Builder and Reports.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s