Skip to content

Jenwlee's Salesforce Blog

Sharing my love for Salesforce with my #Ohana

  • How To
  • Salesforce Release
    • Summer ’21 Release Highlights
    • Spring ’21 Release Highlights
    • Winter ’21 Release Highlights
    • Summer ’20 Release Highlights
    • Spring ’20 Release Highlights
    • Winter ’20 Release Highlights
    • Summer ’19 Release Highlights
    • Spring ’19 Release Highlights
    • Winter ’19 Release Highlights
    • Summer ’18 Release Highlights
    • Spring ’18 Release Highlights
    • Winter ’18 Release Highlights
    • Summer ’17 Release Highlights
  • Certification
    • How I Studied for the Platform Developer I (Beta) Exam
    • How I Studied for the Sales Cloud Consultant Certification Exam
    • How I Studied for the Sharing & Visibility Designer Exam
    • How I Studied for the Data Architecture and Management Designer Exam
    • How I Studied for the Salesforce Platform App Builder Certification Exam
    • Salesforce Administrator Exam Preparation & Exam Taking Strategy
    • How I Studied for the Salesforce Advanced Administrator Certification Exam
  • Salesforce Events
  • Trailhead
  • About Me
  • Meet Jen Lee
How To

Create a New Opportunity From a Quick Action w/ Specific Record Type Based on the User’s Profile

April 24, 2018May 23, 2021 jenwlee

CMDT

(Note: This blog post only applies to Lightning Experience. You cannot invoke a flow from a quick action in the Salesforce Classic UI.)

The business wants the ability to quickly create an opportunity record from a contact with minimal number of fields and create/associate this contact as the primary contact and “Decision Maker” on the opportunity. Additionally, this org has multiple opportunity record types and it is important to use the record type that is associated with the user’s profile.

If the requirement was as simple as create a new opportunity from the contact record, this can be done with a global action that allows for the Admin to specify the record type to use. Easy peasy. However, this is not sustainable to have a “create an opportunity” global action for each opportunity record type in the org, nor are global actions shown profile specific so you only display the global action that pertains to the user’s profile.

With the additional requirement to create an opportunity contact role record as well, it makes sense to invoke a flow from a quick action (new feature introduced in Spring 18). This flow will show a screen to collect the minimally required information and then determine what opportunity record type to use based on the user’s profile, create the opportunity using the right record type and then create the contact role for the newly created opportunity.  We will map the profile to the record type using custom metadata type.

CustomMetadataType

What’s CMDT, you ask? Quick sidebar on custom metadata types. Custom metadata types were introduced in Winter 16. It is a great feature to add to your admin toolset! If you like custom settings, you will like custom metadata types. If you don’t know what custom settings are, it’s ok.

Custom metadata is customizable, deployable, packageable, and upgradeable application metadata. First, you create a custom metadata type, which defines the form of the application metadata. Then you build reusable functionality that determines the behavior based on metadata of that type. Similar to a custom object or custom setting, a custom metadata type has a list of custom fields that represent aspects of the metadata. Unlike custom settings, the record data is metadata and can be deployed with the custom metadata type in a Change Set. No more exporting the related data and importing it to the destination org as you would do when deploying a custom setting.

For more information on custom metadata types, visit Salesforce Help & Training.

Here are a few lessons learned from implementing this use case:

  • Learn how to invoke flow from a quick action in Lightning Experience.
  • Create a custom metadata type to handle the profile to object record type mapping.
  • Use the step of querying the RecordType object to find the record type ID so we avoid having to hardcode IDs in our flows. (Note: Hardcoded Ids are bad practice.)
  • Provide descriptions, where provided, in Salesforce. This may be tedious step, I know, but your future self will thank you when you are trying to remember what you configured or assist other/future admins when troubleshooting or enhancing what was built. This includes variables, the purpose of a flow, what each flow element does, etc.

Business Use Case:  Addison Dogster is the system administrator at Universal Containers. Mary Markle is the Director of Sales Manager. Mary asked Addison if there was a way to allow her sales reps to create an opportunity right from the contact record (with the appropriate opportunity record type) and relate the contact as the primary decision maker to the opportunity.

Solution: Being the #AwesomeAdmin that Addison is, she was able to solution these requirements declaratively using a quick action, flow interacting with the Record Type, Contact, Opportunity and Opportunity Contact Role objects and using a mapping from a custom metadata type.

Create A New Opportunity.GIF

CreateanOpportunityFlow.GIF

ProfiletoRTMappingCMDT.GIF

Quick Steps:

Pre-Requisite: You are using Lightning Experience.

1.On the profiles that will be using this functionality, enable the “Run Flows” permission. If you do not take this step, the user will not see the flow Quick Action on the Lightning record page.

2. Create a custom formula field on the User object. This will show the user’s profile name, we need the profile name for the profile to RT mapping query in the flow. (Note: the current profile field on the user record is a lookup to the profile, storing the profileID, not profile name.)

Note: There is a funky thing with the way the $Profile.Name is shown for standard profiles in Lightning Experience. It shows the internal Salesforce name. For example, instead of showing “System Administrator” as the profile name, the profile name shows “PT1”, which is the internal name for System Administrator.

So, to work around this quirk in Lightning Experience, our formula is “IF ($Profile.Name = “PT1”, “System Administrator”, $Profile.Name). This reads if the profile name returned is “PT1”, then we will show “System Administrator” in its place. Otherwise, show the profile name.

In our case, our mapping is only using the System Administrator profile so we only have the one internal profile name mapping. You will need to add to the formula for each standard profile you are using in the mapping.

User-ProfileName.GIF

Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this custom metadata type is used for.

Don’t forget to set the FLS appropriately for the profiles that will be using this New Opp Quick Action.

3. Create a Custom Metadata Type (Custom Code | Custom Metadata Types), click on the “New Custom Metadata Type” button.

A. Provide the label name and label name in plural and save.

Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this custom metadata type is used for.

ProfiletoRTMappingCMDT-Properties.GIF

B. Create a custom field as a picklist data type for each object with a profile to record type mapping created in Step 3. While our use case is only for the opportunity object, Addison is making this more generic for other future profile mappings to object record types. So, she created a picklist for Opportunity, Account and Contact objects (to show the extensibility of this CMDT).

Best Practice Tip: Don’t forget to provide a description so you and other/future admins know what this custom metadata type is used for.

ProfiletoRTMappingCMDT-Object.GIF

C.  Create a custom field as a picklist data type for each profile that has a record type mapping for the CMDT created in Step 3. Note: copy and paste the profile names as they are. You will use these to query for the record type API name in flow.

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this custom field is used for.

ProfiletoRTMappingCMDT-Profile.GIF

D. Create a custom text field to hold the record type API name for the CMDT created in Step 3.

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this custom field is used for.

ProfiletoRTMappingCMDT-RecordTypeAPIName.GIF

E. Now, let’s create the custom metadata type records by clicking on the “Manage Profile to RT Mappings” and create a record for each profile to opportunity record type mapping.

ProfiletoRTMappingCMDT-ManageRecords.GIF

Navigate to the opportunity record types to get the record type name, which is the record type API name field of the CMDT record.

OppRecordType-Jen.GIFOppRecordType-Addison.GIF

ProfiletoRTMappingCMDT-Records.GIF

In this example, the system administrator will get the Jen_Opp record type and the user with the Custom: Sales Profile will get the Addison_Opp when a new opp record is created.

4. Now, we need to create a flow that will gather the minimal opportunity information from the Sales Rep, then determine the opportunity record type based on the profile, gather the record type ID using the record type API name (no hardcoding IDs, folks!), create the opportunity and then create the opportunity contact role. Go to Setup | Process Automation | Flows  in Lightning Experience.

CreateanOpportunityFlow

A. First, we are going to create six variables and one formula.

The recordId (this variable name is reserved by Salesforce) to pass the detail record ID into the flow variable for use.

recordId.GIF

The variable will store the account ID that we will lookup on the contact record.

varAccountId.GIF

The variable will store the newly created opportunity ID to use to create the opportunity contact role.

varOppID.GIF

This variable will store the opportunity’s record type API name from the CMDT.

varOppRecordTypeAPIName.GIF

This variable will store the record type ID based off the lookup of the record type.

varRecordTypeID.GIF

This last variable will store the user’s profile name to use to look up the CMDT profile mapping to record type.

varUserProfileName.GIF

We need a formula field to pull in the current user’s Id – {!$User.Id}.

varUserId.GIF

B. Create a Flow Screen called “Create an Opportunity” to gather the basic opportunity information.

CreateanOpportunityFlow-Screen.GIF

Under Header and Footer, deselect Header but keep Footer checked.

CreateanOpportunityFlow-Screen1.GIF

Under Navigation Actions, keep “Allow Finish” checked but deselect “Allow Previous” and “Allow Pause.”

CreateanOpportunityFlow-Screen2.GIF

In the Add a Field tab, locate the display text field and drag it to the screen canvas. Then configure the instructional text accordingly.

CreateanOpportunityFlow-Screen1a.GIF

In the Add a Field tab, locate the text field and drag it to the screen canvas. Then configure the opportunity name and make it required.

CreateanOpportunityFlow-Screen3.GIF

In the Add a Field tab, locate the date field and drag it to the screen canvas. Then configure the close date and make it required.

CreateanOpportunityFlow-Screen4.GIF

In the Add a Field tab, locate the picklist field and drag it to the screen canvas. Then configure the stage field. Configure the choice field.

CreateanOpportunityFlow-Screen5.GIF

Select the “Opportunity” object, select “StageName” to pull in dynamically the opportunity stage names.

CreateanOpportunityFlow-Screen5a.GIF

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this screen flow element does.

C. We are going to create a Record Lookup flow element to lookup the user’s profile name. We will query the User object where the ID equals the varUserID. Once found, we will take the value in the custom Profile Name field created in Step 2 in the variable varUserProfileName.

CreateanOpportunityFlow-RecordLookup.GIF Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record lookup flow element does.

D. We are going to create another Record Lookup flow element to the Profile to RT Mapping custom metadata type where the Object is “Opportunity” and the Profile is the variable varUserProfileName. Once found, we will take the value from the Record Type API Name and store it in the variable varOppRecordTypeAPIName.

We are doing this step so we do not need to hardcode the record type ID in the flow. Instead, we are performing a lookup to get the ID.

CreateanOpportunityFlow-RecordLookupA.GIF

E. Next, we will create another Record Lookup flow element to get the record type ID based on the record type API name.  We will query the RecordType object where the DeveloperName equals the variable varOppRecordTypeAPIName and sObjectType equals to Opportunity. We then take the record type ID and store it in the variable varRecordTypeID.

CreateanOpportunityFlow-RecordLookupB.GIF

F. Let’s create our last Record Lookup flow element on the Contact record to get the Account ID querying where the Contact’s ID equals the variable recordId and will take the AccountId and store it in the variable varAccountID. We will associate the opportunity to the account.

CreateanOpportunityFlow-RecordLookupC.GIF

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record lookup flow element does.

G. Create a Decision flow element to determine if we have enough information to create the opportunity and opportunity contact roles. In the outcome “Info Exists” where the variable varAccountID is not null (i.e. is null {!GlobalConstant.False}) and the variable varOppRecordTypeAPIName is not null (i.e. is null {!GlobalConstant.False}). The default outcome is Missing Information.

CreateanOpportunityFlow-Decision.GIF

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this decision flow element does.

H. Let’s create a Record Create flow element to create the opportunity. We will assign values to the AccountId, Amount, CloseDate, Name, RecordTypeId and StageName fields based on the inputs from the flow screen or variables. Then once created, we want to store the opportunity ID in a variable called varOppID.

CreateanOpportunityFlow-RecordCreate.GIF

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record create flow element does.

I. We will create a Record Create flow element to create the opportunity contact role. We will create the OpportunityContactRole and specify the ContactId with the contact’s variable recordId, IsPrimary to true (i.e. {!GlobalConstant.True}), OpportunityId to the variable varOppID and Role to “Decision Maker.”

CreateanOpportunityFlow-RecordCreateA.GIF

 

Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record create flow element does.

J. Add the subflow Send Flow Fault Email. For instructions on how to create this, go to Step 2 of blog post: Maximize Maintainability With Process Builder and Componentized Visual Workflow.

K. Set your flow starting point. And connect the flow elements and the fault connectors to match the below…

CreateanOpportunityFlow-Connectors.GIF

L. Save as and provide the following properties. We’re going to call this flow “Create an Opportunity.”

CreateanOpportunityFlow-Properties.GIF

Best practice tip: Provide a description so you and other/future admins know what this flow is used for.

M. Click the “Close” button.

N. On the flows screen, activate the flow.

CreateanOpp-ActivateFlow.GIF

5. Create the Quick Action. Go to the Object Manager | Contact | Buttons, Links, and Actions. Click to create a “New Action.” Select the flow you created in Step 4.

Best practice tip: Provide a description so you and other/future admins know what this quick action is used for.

ContactAction.GIF

6. Don’t forget to add the Quick Action to the appropriate page layout for it to show. In the Page Layout Editor, locate the quick action under Mobile & Lightning Actions and drag it to the location among the mobile and lightning actions and Save.

ContactAction-AddToPageLayout.GIF

Now, before you deploy the changes to Production, don’t forget to test your configuration changes.

  1. Log in as the intended user.
  2. Navigate to a contact and click on the “New Opp” quick action.
  3. Provide the opportunity information and save.
  4. Verify that the opportunity with the correct record type mapping and opportunity contact role records were created as expected.
  5. Test steps 1-4 as each profile with a RT mappimng

Deployment Notes/Tips:

  • The custom field, visual workflow, quick action, page layout changes, custom metadata type and its records can be deployed to Production in a change set (or can be deployed using a tool such as Dreamfactory’s Snapshot).
  • You may want to manually update the User custom field’s FLS for each profile
  • You will find the flow in a change set under the Flow Definition component type.
  • Activate the flow post deployment as it deploys inactive in Production.

 

 

Share this:

  • Tweet

Like this:

Like Loading...

Related

Share this:

  • Tweet

Like this:

Like Loading...
Custom Metadata Type Flow Lightning Experience Quick Action Salesforce visual workflow

Post navigation

Previous Post Remove a Contact from Campaign(s) When Opt Out Marketing Campaigns
Next Post Invoke a Flow from a Global Action

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 12,838 other subscribers

Check out my previous posts

About the Author

Native Bostonian. 4x Salesforce MVP, Dreamforce 16-19 presenter & other Salesforce and community hosted events, 8x Salesforce Certified (Salesforce Application Architech, Salesforce Administrator, Advanced Administrator, Platform App Builder, Sales Cloud Consultant, Security and Visibility Designer, Data Management and Architecture Designer, Platform Developer I), co-host of Automation Hour, Salesforce enthusiast and blogger, Trailhead addict (8x Ranger!), #LifeWithGoldie, and Lightning Champion.

Named Salesforce MVP on 7/29/16

Trailblazer!

Salesforce Trailblazer post published on 8/16/17.

#AwesomeAdmin Award Recipient

I am so truly honored to be the recipient of Salesforce's #AwesomeAdmin Award at the 2016 Boston Salesforce World Tour.

1/14/16 Girly Geek of the Week

My Tweets
Website Powered by WordPress.com.
  • Follow Following
    • Jenwlee's Salesforce Blog
    • Join 1,676 other followers
    • Already have a WordPress.com account? Log in now.
    • Jenwlee's Salesforce Blog
    • Customize
    • Follow Following
    • Sign up
    • Log in
    • Copy shortlink
    • Report this content
    • View post in Reader
    • Manage subscriptions
    • Collapse this bar
 

Loading Comments...
 

    %d bloggers like this:
      %d bloggers like this: