How To

Add Product(s) to an Opportunity W/O Specifying Quantity and Price

OpportunityImage-Revised2

For those who have added products to an opportunity in Salesforce, you know that you need to specify a quantity and sales price for each product added which overrides the opportunity amount.

However, not all industries sell products that way, especially the financial services industry as an example. Prices for financial instruments are based on the market price, not a negotiated price like those who sell widgets. So, setting the quantity and sales price when adding product(s) to an opportunity does not make sense. Therefore, in the financial services industry, as an example, adding products to opportunities is a painpoint for the sales reps as these fields do not have any meaning in their business. For this reason, these companies may not have adopted the use of products in Salesforce for use with opportunities.

While we want to provide a way for users to add products to an opportunity using flow screens, bypassing the need to specify the quantity and sales price, we need to preserve the opportunity amount and not zero it out in favor of total price of the products added to the opportunity.

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

  • Create an interactive flow screens with dynamic record choice and loops.
  • Learn how to invoke a flow and pass parameters into a flow from a custom button.
  • 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.

 

Shoutout1.pngI want to give a shout out to my friend and Automation Hour co-host, David Litton.

Via his blog, David provides an unmanaged package that allowed me to parse a multi-select picklist of products within my flow.                                                                                                          

Business Use Case:  Addison Dogster is the system administrator at Universal Containers. Steven Moon is the Director of Sales. The Sales Reps have complained about specifying the quantity and sales price to track products to an opportunity since the information is meaningless in the financial services industry. Steven asked Addison if there was anything she could do to address this painpoint as the other option was to stop using Salesforce products altogether. Steven noted that he did not want the opportunity amount zeroed out when products are added.

Solution: Being the #AwesomeAdmin that Addison is, she was able to solution this by building interactive flow screens with dynamic picklist items and looping while meeting the requirement of allowing sales reps to add products without asking for the quantity and sales price while retaining the same opportunity amount.

AddaProductToAnOppClassic.gif

View the image full screen

Flow-AddaProducttoAnOpp.GIF

Quick Steps: 

1. Let’s create a visual workflow to add product(s) selected by the user to the opportunity and retain the original opportunity amount.

Flow-AddaProducttoAnOpp

For those using Salesforce Classic, visual workflows can be found in Create | Workflows & Approvals | Flows. In Lightning Experience, it is found under Process Automation | Flows.

A. First, we will create all the resoucess we need to reference in our flow. This is done by going to the Resource tab in the Flow Designer and creating a new resource.

Best practice tips: Don’t forget to provide a description so you and other/future admins know what each resource does.

The following are variables to be created…

varOppLineItem.GIF

varOpportunityAmount.GIF

varOpportunityID.GIF

varProductID.GIF

varProductNameNoSpace.GIF

varSingleProduct.GIF

This is a collection variable. This will hold the parsed out product IDs that were in the multi-select product picklist.

Collection_All_IDs_In_One.GIF

Here are the sObject variables to create…

sObjOppLineItemToBeCreated.GIF

sobjVarSingleProduct.GIF

sObjVarUnitPrice.GIF

The following are sObject Collection variables to create…

sObjCollectionVarProductIDs.GIF

sObjNewCollectionOppLineItem.GIF

We need a formula to remove the beginning space in the parsed out product names to use in the lookup.

RemoveSpaceFormula.GIF

B. We are going to create a Screen flow element to search for the product. This screen has instructional text and a required text box called Product for the user to input the product name to search for. Set the navigation option to “Don’t show Previous button” and uncheck Show Pause button.

Flow-AddaProducttoAnOpp-Screen1.gif

View image in full screen

C. Create Fast Lookup flow element to query the Products object based on the product name containing what the user input in the previous screen. The products are stored in a sObject Collection variable, sObjCollectionVarProductIDs.

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

Flow-AddaProducttoAnOpp-FastLookup.GIF

D. Create the a Decision flow element to determine whether there are any products found in Step C. Essentially, we need to look at the sObject Collection Variable sObjCollectionVarProductIds and see if there are values (or is null = false). The default outcome will be set to No Products.

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

Flow-AddaProducttoAnOpp-Decision.GIF

E. In our next step, we add a Screen flow element where we inform the user that there are no products were found matching the search criteria. The screen element shown is a display text field. Set the navigation option to “Don’t show Previous button” and uncheck Show Pause button.

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

Flow-AddaProducttoAnOpp-ScreenNoProducts.gif

View image full screen

F. We will create a Record Lookup flow element to lookup up the opportunity amount on the opportunity to store that for safekeeping before we start adding products that will override that value. We will query the Opportunity object where the ID is the variable varOpportunityID that will be passed as a parameter in the custom button. Once found, we will take the value in the Amount field and store it in the variable varOpportunityAmount.

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

Flow-AddaProducttoAnOpp-RecordLookup.GIF

G. We are going to create a Screen flow element that will show the opportunity amount pre-populated from the opportunity (which can be updated) and the products(s) that match the search criteria provided for the user to select from (multi-select list). Set the navigation option to “Don’t show Previous button” and uncheck Show Pause button.

We are going to add a display text and a radio button that will have a dynamic choice.

Best practice tips: Don’t forget to provide a description so you and other/future admins know what screen is for.

Here is the screen to configure the opportunity amount and pre-populate it with the variable amount.

Flow-AddaProducttoAnOpp-Screen-OppAmount.GIF

Here is the screen to configure the dynamic product list, which returns the product name and stores the Id in the variable varProductId field.

Flow-AddaProducttoAnOpp-DynamicRecordChoice.GIF

Follow the steps in the animated gif to build the screen.

Flow-AddaProducttoAnOpp-ScreenProductSearchResults.gif

View image full screen

H. Now, let’s create another screen flow element. This will show the selected products. Set the navigation option to “Don’t show Previous button” and uncheck Show Pause button. This is just a text field that pulls in the screen multi-select field, Product_s.

Best practice tips: Don’t forget to provide a description so you and other/future admins know what screen is for.

Flow-AddaProducttoAnOpp-ScreenProductList.gif

View image in full screen

I. Next, we are bringing in the flow we installed from David Litton’s unmanaged package into this flow. This contains steps that will allow us to parse out a multi-select list of products into a collection that we can use in flow. We need to set up the inputs and outputs. 

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

Flow-AddaProducttoAnOpp-ParseProducts.gif

View image in full screen

J. Now, we will create a loop flow element to go through the products in the collection. So, it is essentially taking the parsed list of products in the collection All_IDs_in_One and puts each product it loops through in the variable varSingleProduct.

Flow-AddaProducttoAnOpp-Loop.GIF

K. Now, let’s add an Assignment flow element that will remove the starting space in front of the product name so we can perform a record lookup in the next step.

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

Flow-AddaProducttoAnOpp-AssignmentRemoveSpace.GIF

L. Next, we need to perform a record lookup since we only have the product name at this point. We need the product ID. So, we are doing a query on the Product object where the product name contains the product name from the search. Once a match is found, we will take the ID and store it in the variable varProductID.

Best practice tips: Don’t forget to provide a description so you and other/future admins know what this record lookup is for.

Flow-AddaProducttoAnOpp-RecordLookupInLoop.GIF

M. Next, we need to use a Fast Lookup flow element to pull the pricebookentry information for the product to use when creating the opportunity line item later on.

Best practice tips: Don’t forget to provide a description so you and other/future admins know what this fast lookup is for.

Flow-AddaProducttoAnOpp-FastLookupinLoop.GIF

N. Now, let’s add an Assignment flow element to assign values for when we create the opportunity line item.

  • {!sObjOppLineItemToBeCreated.OpportunityId} equals {!varOpportunityID}
  • {!sObjOppLineItemToBeCreated.Product2Id} equals {!sobjVarSingleProduct.Id}
  • {!sObjOppLineItemToBeCreated.PricebookEntryId} equals {!sObjVarUnitPrice.Id}
  • {!sObjOppLineItemToBeCreated.Quantity} equals 1
  • {!sObjOppLineItemToBeCreated.ListPrice} equals {!sObjVarUnitPrice.UnitPrice}
  • {!sObjOppLineItemToBeCreated.TotalPrice} equals {!sObjVarUnitPrice.UnitPrice}

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

Flow-AddaProducttoAnOpp-AssignmentOppLineItem.GIF

O. Now, for our final Assignment flow element…This will add the sObject collection variable !sObjNewCollectionOppLineItem adds the sObject variable sObjOppLineItemToBeCreated.

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

Flow-AddaProducttoAnOpp-AssignmentAddRecord.GIF

P. We’ve gotten to out opportunity line item create step! Let’s add a Fast Create flow element where we are taking the items in the sObject Collection Variable sObjNewCollectionOppLineItem and creating the opportunity line item records.

With this step, we have fulfilled the requirement to add products to an opportunity without specifying a quantity and sale price.

Best practice tips: Don’t forget to provide a description so you and other/future admins know what this fast create is for.

Flow-AddaProducttoAnOpp-FastCreate.GIF

Q. We now need the Record Lookup flow element to lookup one of the products (i.e. opportunity line item) associated with the opportunity by querying the OpportunityLineItem where the OpportunityID equals the variable varOpportunityID. Then for the first one it finds, I want to store the ID in the variable varOppLineItem.

Best practice tips: Don’t forget to provide a description so you and other/future admins know what this fast create is for.

Flow-AddaProducttoAnOpp-RecordLookupOppLineItem.GIF

R. Now, to fulfill the last requirement of retaining the opportunity amount, we will take the opportunity amount and update the total amount of a product. Here we will do a record update in the OpportunityLineItem object where the Id equals the variable varOppLineItem. Once found, we will update the Total Amount field with the variable Opportunity_Amount from the screen input field.

Flow-AddaProducttoAnOpp-RecordUpdate.GIF

S. Lastly, we will show a Screen flow element to show the user a confirmation message that the selected product(s) have been associated to the opportunity.

Flow-AddaProducttoAnOpp-ScreenSuccess.gif

View image in full screen

T. 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.

Flow-AddaProducttoAnOpp-FlowFault.GIF

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

Flow-AddaProducttoAnOpp-Connectors.GIF

V. Save as and provide the following properties.

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

Flow-AddaProducttoAnOpp-Properties.GIF

W. Click the “Close” button.

X. On the flows screen, activate the flow.

Flow-AddaProducttoAnOpp-Activate.GIF

2. Now, we need to create the custom Opportunity button that invokes the flow and passes the parameters.

Take note of the flow URL.

Flow-AddaProducttoAnOpp-FlowURL.GIF

Navigate to the Buttons, Links, and Actions section for the Opportunity object.

We will call the button “Add a Product(s)” that is a Detail Page Button.

Use this for the URL:

/flow/Add_Product_s_to_an_Opportunity?varOpportunityID={!Opportunity.Id}

Let’s deconstruct the URL.

  • “/flow/Add_Product_s_to_an_Opportunity?” is the URL from the flow detail record.
  • “?” is needed when we want to pass parameters into the flow.
  • “varOpportunityID={!Opportunity.Id}” indicates that we are passing the opportunity record’s ID as the flow variable varOpportunityID.

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

AddProductsCustomButton.GIF

If you are using Lightning Experience, you can add this flow component to the Opportunity page using Lightning App Builder.

AddaProductToAnOpp.gif

View image in full screen

3. Add the custom button to the opportunity page layout.

AddButtontoOppPageLayout.GIF

Secondarily, update the Products related list on the opportunity page to remove all fields shown except product name and remove all of the out of the box buttons. We only want the users to use our custom Products button.

ProductsRelatedList.GIF

Congrats, you configured the solution! You’ve implemented a process to allow the user to add product(s) to an opportunity without specifying the quantity and sales price while retaining the opportunity amount.

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

  • Create an opportunity with an amount.
  • Click on the “Add Product(s)” custom button.
  • Add product(s) and confirm the opportunity amount field is prepopulated with the opportunity amount
  • Confirm on the opportunity that the new product(s) are added and the amount is retained.

Deployment Notes/Tips:

  • Visual workflow, custom button and opportunity page layout(s) can be deployed to Production in a change set (or can be deployed using a tool such as Dreamfactory’s Snapshot).
  • Activate the visual workflow as it is deployed as inactive into Production. 

2 thoughts on “Add Product(s) to an Opportunity W/O Specifying Quantity and Price

  1. Hi,

    Thank you for Wonderful Blog!!
    I have one query over here. Can we edit the amount after adding the Products.

    Like

Comments are closed.