Last Updated on July 31, 2023 by Rakesh Gupta
Big Idea or Enduring Question:
How do you automatically create a new Opportunity by cloning an existing opportunity with Opportunity Line Items?
Opportunities are the sales and pending deals that you want to track. By adding opportunities, we are building a pipeline, which contributes to sales forecasts. Products are a catalog of items that your company can sell. An Opportunity Product is a specific item or service that is purchased and delivered to the client as it relates to that specific opportunity.
The Opportunity Line Item is also known as Opportunity Product in the user interface. Many organizations are using the opportunity for renewal business of assets, and software. There are no out of box features that allow you to auto-generate renewal opportunities based on the close date of a current opportunity or once an opportunity is successfully closed-won.
Objectives:
After reading this article, the reader will be able to:
- Using Salesforce Flow to auto-generate renewal Opportunity
- How to use Get Record element to find the line items from old record
- How to use a Decision element to find – record variable or record collection variable contains a record or not
- How to work with Loop elements to create multiple records (or clone records)Â
Business Use case
Steven Greene is working as a System administrator at Universal Containers (UC). He received a requirement from the management to auto-create/generate a new opportunity with opportunity line items once an opportunity is closed won. Use the following logic to set the close date of the renewal opportunity
- Close Date (Renewal opportunity) = Close date (Closed won opportunity) + 365
- Set Product Unit Price = 0
Automation Champion Approach (I-do):
There are a few possible solutions for the above business scenario, but I’ll use Salesforce Flow to solve the business requirement. Before proceeding ahead, you have to understand OpportunityLineItem objects in Salesforce.Â
- OpportunityLineItem represents an opportunity line item, which is a member of the list of Product2 products associated with an Opportunity.Â
Before discussing it, let me show you a diagram of a Process Flow at a high level. Please spend a few minutes to go through the following Flow diagram and understand it.
Let’s begin building this automation process.
Guided Practice (We-do):
There are 12 steps to solve Steven’s business requirement using Salesforce Flow. We must:
- Define flow properties for record-triggered flow
- Create a Formula field to generate a close date for a renewal opportunityÂ
- Add a Record variable to store the opportunity line item
- Add a Record collection variables to store opportunity line items
- Add a Decision element to validate the opportunity Stage equals Closed Won
- Add a Create Records element to generate a renewal opportunity
- Add a Get Records element to find line items for the old opportunityÂ
- Add a decision element to check if opportunity line item record(s) existsÂ
- Add a Loop element to extract records from the collection variable (From step 7)
- Add an Assignment to populate OpportunityId to the opportunity line item record variable
- Add an Assignment element to add all line items into a record collection variable (Created in step 4)
- Add a Create Records element to insert opportunity line Items to renewal opportunity (Bulk safe)
Step 1: Salesforce Flow – Define Flow PropertiesÂ
- Click Setup.
- In the Quick Find box, type Flows.
- Select Flows then click on the New Flow.
- Select the Record-Triggered Flow option, and click on Create and configure the flow as follows:
- Object: Opportunity
- Trigger the Flow When: A record is created or updated
- Set Entry Criteria
- Condition Requirements: None
- Optimize the Flow For Action and Related RecordsÂ
- Click Done.
Tips: Never try to write entry criteria in a Record-Triggered Flow. Why? Check out this article.
Step 2: Salesforce Flow – Create a Formula to Generate Close Date For a Renewal OpportunityÂ
- Under Manager click New Resource to create a formula for renewal opportunity close date.
- Input the following information:Â
- Resource Type: Formula
- API Name: forD_RenewalOpportunityCloseDate
- Data Type: Date
- Formula: {!$Record.CloseDate} + 365
- Click Done.
Step 3: Salesforce Flow – Add a Record Variable to Store Opportunity Line item Record
- Under Manager, click New Resource to create a variable to store opportunity line item records.
- Input the following information:Â
- Resource Type: Variable
- API Name: varR_OpportunityLineItem
- Data Type: Record
- Object: OpportunityLineItem
- Check Available for Input
- Check Available for Output
- Click Done
Step 4: Salesforce Flow – Add a Record Collection Variable to Store Opportunity Line items Records
- Under Manager, click New Resource to create a variable to store opportunity line item records.
- Input the following information:Â
- Resource Type: Variable
- API Name: varR_OpportunityLineItems
- Data Type: Record
- Click the Yes checkbox – Allow multiple values (collection)
- Object: OpportunityLineItem
- Check Available for Input
- Check Available for Output
- Click Done
Step 5: Salesforce Flow – Using Decision Element to Check if Opportunity is Closed Won or Not
Now we will use the Decision element to check the StageName to ensure that it is equal to Closed.Â
- On Flow Designer, click on the + icon and select Decision element.Â
- Enter a name in the Label field; the API Name will auto-populate.
- Under Outcome Details, enter the Label the API Name will auto-populate.
- Condition Requirements to Execute Outcome: All Conditions Are Met (AND)
- Row 1:
- Resource: {!$Record.StageName}
- Operator: Equals
- Value: Closed Won
- Row 1:
Step 6: Salesforce Flow – Add a Create Records Element to Generate Renewal OpportunityÂ
 The next step is to create a new Opportunity, for this we will use the Create Records element.
- On Flow Designer, click on the + icon and select Create Records element.Â
- Input the following information:
- Enter Label the API Name will auto-populate.
- How Many Records to Create: One
- How to Set the Record Fields: Use separate resources, and literal values
- Object: Opportunity
- Set Field Values for the Opportunity
- Row 1:
- Field: CloseDate
- Value: {!forD_RenewalOpportunityCloseDate}
- Click Add Field
- Row 2:
- Field: Name
- Value: {!$Record.Name}
- Click Add Field
- Row 3:
- Field: Pricebook2Id
- Value: {!$Record.Pricebook2Id}
- Click Add Field
- Row 4:
- Field: RecordTypeId
- Value: {!$Record.RecordTypeId}
- Click Add Field
- Row 5:
- Field: StageName
- Value: Prospecting
- Click Add Field
- Row 5:
- Field: AccountId
- Value: {!$Record.AccountId}
- Click Done.
If you are using currency on the opportunity and price book, make sure to map it.Â
Step 7: Salesforce Flow – Adding a Get Record Element to Find Line Items From Closed Won opportunityÂ
The next step is to get all the Opportunity Line Items from the old opportunity.
- On Flow Designer, click on the + icon and select Get Records element.Â
- Enter a name in the Label field; the API Name will auto-populate.
- Select the Opportunity Product object from the dropdown list.
- Select All Conditions Are Met (AND).Â
- Set Filter Conditions
- Row 1:
- Field: OpportunityId
- Operator: Equals
- Value: {!$Record.Id}
- Row 1:
- How Many Records to Store:
- select All records
- How to Store Record Data:
- Choose the option to Automatically store all fields.Â
- Click Done.
Step 8: Salesforce Flow – Using Decision Element to Check if Opportunity Line Items record(s) Exist or Not
Now we will use the Decision element to check the Record Collection Variable from step 7 to find if it returns the Opportunity line items or not.Â
- On Flow Designer, click on the + icon and select Decision element.Â
- Enter a name in the Label field; the API Name will auto-populate.
- Under Outcome Details, enter the Label the API Name will auto-populate.
- Condition Requirements to Execute Outcome:Â All Conditions Are Met (AND)
- Row 1:
- Resource: {!Get_Line_Items}
- Operator: Is NullÂ
- Value: {!$GlobalConstant.False}
- Row 1:
- Click Done.
Step 9: Salesforce Flow – Add a Loop Element to Extract Records from the Record Collection Variable
The next step is to extract the opportunity line items from Record Collection Variable from step 7 one by one. For this, we will use the Loop Element.
- On Flow Designer, click on the + icon and select Loop element.Â
- Enter a name in the Label field; the API Name will auto-populate.
- For the Record Collection Variable select {!Get_Line_Items}.
- For Specify Direction for Iterating Over Collection select the option First item to last item
- Click Done.
Step 10: Salesforce Flow – Assignment Element to populate OpportunityId to a Record VariableÂ
The next step is to assign the data from the loop element to varR_OpportunityLineItem record variable. We will use an Assignment element.Â
- On Flow Designer, click on the + icon and select Assignment element.Â
- Enter a name in the Label field; the API Name will auto-populate.
- Set Variable Values
- Row 1:
- Field: {!varR_OpportunityLineItem.OpportunityId}
- Operator: Equals
- Value: {!Create_Renewal_Opportunity}
- Add Assignment
- Row 2:
- Field: {!varR_OpportunityLineItem.PricebookEntryId}
- Operator: Equals
- Value: {!Line_Items.PricebookEntryId}
- Add Assignment
- Row 3:
- Field: {!varR_OpportunityLineItem.UnitPrice}
- Operator: Equals
- Value: 0
- Add Assignment
- Row 4:
- Field: {!varR_OpportunityLineItem.Quantity}
- Operator: Equals
- Value: {!Line_Items.Quantity}
- Row 1:
- Click Done.
Step 11: Salesforce Flow – Add an Assignment to Add Line Item to a Record Collection Variable (Created in step 4)Â
The next step Is to add record variables from step 3 into a Record Collection Variable which we created in step 4, So at the end, we will create records in OpportunityLineItem.Â
- On Flow Designer, click on the + icon and select Assignment element.Â
- Enter a name in the Label field; the API Name will auto-populate.
- Set Variable Values
- Row 1:
- Field: {!varR_OpportunityLineItems}
- Operator: Add
- Value: {!varR_OpportunityLineItem}
- Row 1:
- Click Done.
Step 12: Salesforce Flow – Add a Create Records Element to Insert Opportunity Line Items to Renewal OpportunityÂ
 The next step is to create line items for renewal opportunity, for this we will use the Create Records element.
- On Flow Designer, click on the + icon and select Create Records element.Â
- Input the following information:
- Enter Label the API Name will auto-populate.
- How Many Records to Create: Multiple
- Select Values to Create Multiple Records:Â
- Record Collection: {!varR_OpportunityLineItems}
- Click Done.
In the end, Steven’s Flow will look like the following screenshot:
Once everything looks good, perform the steps below:Â
- Click Save.
- Enter Flow Label the API Name will auto-populate.
- Click Show Advanced.
- API Version for Running the Flow: 54
- Interview Label: Auto-generate renewal Opportunity with OLI {!$Flow.CurrentDateTime}
- Click Save.Â
Almost there! Once everything looks good, click the Activate button. Â
👉 Check out the video for step-by-step instructions.
Proof of Concept
Now onwards if a business user updates the Opportunity Stage to Closed Won, then Salesforce Flow will automatically fire and create a renewal opportunity with line items.Â
- Opportunity Aethna Home Products is in Stage Qualification and three products are associated with it, as shown in the following screenshot:
- Now update the Opportunity status to Closed-Won and check the renewal opportunity by navigating to the Opportunity tab.
Guided Practice (We-do):
At the moment, the renewal opportunity is not linked with an account. Update the flow to make sure that is auto associate with the same account as a closed-won opportunity.Â
Formative Assessment:
I want to hear from you!
What is one thing you learned from this post? How do you envision applying this new knowledge in the real world? Feel free to share in the comments below.
Hi Rakesh, Thank you for sharing a very useful article.
My current requirement is to automatically pick the pricebook after renewal. I have refered your other article on automatically assigning pricebook based on opportunity record type. I want to know if i can automatically update pricebook after renewal with the same quote line items.
Thanks for your help.
Veena
Sorry Veena, but I didn’t get you.
Do you want to add all products from the old Opportunity to new Opportunity? – Please confirm
Hi Rakesh,
The the flow variable fields on section 5 of the process builder do not pop up as shown in your screenshot, it only gives me an option to pick my existing activated flow, Save and that’s it.
If I then proceed to activate the process and create an opportunity it clones the opportunity but then of course does not enter any values into those fields (account id, opportunity name, opportunity id and Price book id).
I am currently using version 44.0 of Salesforce.
Thanks in advance,
Richard
I think we already had a conversation via email.
Hi Rakesh,
I have followed the same, but lineitems are not getting created to the new renewal opportunity.
Thanks
make sure that you are correctly linking new LineItems to renewal opportunity.
Hi, Rakesh! I keep getting an error on Step 4 when trying to set the Close Date Value to next year. I have tried various things to include a modified version of what you have above, a simple formula of TODAY () + 365 & {!Flow.CurrentDate} + 365. I get the error with each. Can you help? Thanks!
Make sure to use Formula field in Visual Workflow. Ideally, it should work, if not then use {!TodayPlus365} -Date variable and pass the value from Process Builder.
Please let me know how it goes.
Thank you, Rakesh!! I figured that out, but would like to make sure I’m also correctly setting up the Text Variables in Step 1. Upon entering the Variables, what are the preferred Data Type & Input/Outputs? Thanks again!
Please go through this article – https://help.salesforce.com/articleView?id=vpm_designer_resources_variable.htm&type=5
Hello Rakesh,
How would you go about adding a quote to this flow? We would like to have a quote with the line items from the new opportunity. Is this possible? Thanks in advance.
Use another Record Lookup to get data from Quote record. Then use Assignment element to update new OpportunityID and finally use Record Create element to insert new quote.
Please let me know how it goes.
Rakesh,
How would I update the Opportunity in the assignment?
Thanks
Sorry I meant how do I update the Opportunity ID in the assignment?
When you create an opportunity you have the ID – in our case {!VarT_NewOpportunityId}. In the assignment element use this ID
I’m having a hard time entering the formula on step 4. I would like to adjust it so that it was the effective date plus 10 months. Even using the close date like the process says I can’t seem to get it to work. It says the merge field doesn’t exist. Any help would be great. Thank you.
Please send me an email with screenshots here -info at automationchampion.com
I’m sorry to keep asking you questions, but I’m new to this. On Line 7 for the Assignment Element, how do I get the variable {!NEWOLI.xxx}? When I try to create this SObject Variable, it won’t let me type a period (.), so I think I’m doing something wrong. Thanks.
Just create a SObject Variable:- NEWOLI do not append anything
SObject Type:- OpportunityLineItem
Rakesh ,
Is there a way to start this automation process using a custom button?
Thanks,
Peter
Yes use flow
Yes using a custom button update the field (may be some checkbox) and use that as an entry criteria for any Process
This is Awesome! Thanks Rakesh. What would I do if I have to just copy an Amount field from the Account Object?
Thanks, Sibil! I’m glad you liked my work! 🙂
To answer your question
1. Create a Variable VarNAmount in your Flow
2. Then use Process Builder to pass the amount – [Opportunity].Account.AnnualSale__c
Thank you Sir!
🙂
Hope you are still answering questions – this flow is working perfectly for our renewal process.. was able to add all of the fields that I needed except for the Contact and Role – I know I need to do a look up for the contact id and id for the related record.. but I am unsure how to implement it on the flow. I have created a similar assignment and record creation after the line items but it isnt working – can you provide some guidance on how to add the opportunity contact and role?
You are very welcome Kris!! Glad you like it 🙂
Please send me your Flow with complete screenshots at info@automationchampio.com
Hi Rakesh, I’m getting stuck on the ‘Assign data into new SObject Variable’ Assignment – are you suposed to create New S Object Variables for the Variable and Value? It won’t let me select pre-defined text variables in the ‘Value’. Thank you
Yes, you have to create a new SObject Variable (NEWOLI) of type OpportunityLineItem
Is these opportunity line items the synced (I want if we delete the opportunityLineItem of first opportunity than in clone opportunity product also get deleted )
Nope. To implement the business logic mention above, you have to use Apex Trigger.
Hi Rakesh,
I have a field called Contract End Date on opportunity. That field is copied from the Quote. I want to set the Close Date on the new Opportunity to be the same as the Contract End Date. Is that possible?
P.S. I am using your article Auto Sync Accepted Quote with Opportunity and everything is working perfectly. Thanks!
Yes, it is possible to achieve.
It means you want to sync Close Date field with Contract End Date field. If yes, then use a Process Builder on Opportunity creation, then use Record update action to update Close Date field.
Hi Rakesh,
I am getting the error Error Occurred: INSERT — INSERT FAILED — ERRORS : (REQUIRED_FIELD_MISSING) Required fields are missing: [Name]
I tested things out and changed Name from “VarT_OldOpportunityName” to straight text “TEST” and ran the flow, it created an opp so it seems to be working, I revert it back to VarT_OldOpportunityName and it fails I dont know what I am doing wrong. Can you please help.
Seems like you forget to map Opportunity.Name field or there are no value exist for Opportunity Name
Hey Rakesh,
Super interesting and helpful. How would you work with upsells/downsells during the renewal period?
Thanks for all the help so far!
Interesting, could you please email me your use case at info@automationchampion.com
Thanks so much for this blog, it really helped me to do my first Flow & Process, an automated Opp deep clone with line items. So much better than my URL hack I was using. So many little things to work out but i enjoyed it. Thank you for doing what Salesforce doesn’t!
Thanks for your feedback!
Hi Rakesh, this flow is amazing! For some reason though the products are not carrying over and I cannot figure out why. Its the correct record type, opportunity name, price book, etc. but not the products themselves. Any ideas what I did wrong? Thanks!
Thanks, Jordan. Please send me the complete screenshot of Flow and PB at info@automationchampion.com
Hi! Everything worked great except my sales price and total price are not coming through.
Any ideas?
Make sure that you follow step-by-step instructons
This is perfect for what we need, thank you! However, when I built it I’m getting an error that says ” An error occurred at element All_in_One (FlowAssignment).
Number of iterations exceeded” Any suggestions on what I might have done incorrectly?
Please send me a screenshot of your Flow to info@automationchaampion.com
Thank you Rakesh for looking at my Flow. I was referencing the Old Line Item SOC instead of the new Line Item SOC in the All In One assignment. All works great now, I’m very excited to start using this!
Awesome Amy!
Always happy to help 🙂
I’m trying to implement a similar flow that creates multiple records, but it’s only creating one record. Do you know what mistake I should look for to solve this problem?
Chec you variable, make sure that while creating the record you have selected SObject collection
Wow, fast response. Yes, my Fast Create is using an sObject Collection variable from the previous step.
Then I have to check your Flow. Send me the complete screenshots at info@automationchampion.com
Hey Rakesh this is great!
Question about number 7 – I am creating NEWOLI.OpportunityId on step 7? And is it just a Variable or SObject Variables or SObject Collection Variables
Sobject Variable
Rakesh,
In screenshot # 2 under “It’s time to test this feature”, it looks like the Account Name is not getting passed into the new opportunity.
I am seeing the same behavior in my sandbox, how can I get the Account name to show on the new opportunity?
Also, only 1 out of the 3 line items were added to the new opportunity.
Thanks
To pass AccountId, in the step #4 pass old account id to Record create element.
only 1 out of the 3 line items were added to the new opportunity? Make sure that you’re using Sobject collection element not Sobject variable under Fast Create element
Rakesh,
Thanks a lot for all of your help. you are awesome.
Thank you
🙂
Excellent walkthrough. I too am seeking to pass the AccountId into the record create. I haven’t given it a shot yet but before I get started, do I need to use a formula field on Opportunity to store account id?
Thanks for your kind words 🙂
To answer your question, please follow the instructions
1. Create a variable in your Flow i.e. ‘VarTAccountID’
2. Use it while creating a new opportunity (Record Create – element) in Flow
3. Use Process Builder to pass the AccountID
Hi Rakesh,
Can you do a post that has process builder triggering of off Opportunity products? I think this is unique because you are able to create multiple opportunity products with a single ‘save’ action.
When a user adds new products to the Opportunity (multiple products can be added at one time). If you pass in Opportunity product record ids as a variable only the last record gets processed (you can see process builder resetting the the ids in the debug log) and the flow trigger is deferred. The flow works in the end but only on the last record.
Is this even possible?
Thanks a lot.
Can you please explain you business use case ?
Rakesh,
Here is my use case. It is quite narrow, but it can be extended.
Products have a business unit attribute (a picklist field on opportunity product called BU). Every time an Opportunity Product line item is added to an opportunity, we want to check the BU on the product that was added against the BU on the all the products on the Asset that is currently associated with the Account that the opportunity is associated with.
If the collection of Asset.Product.BU contains Opportunity product.product.BU then set a pick list field (Net New) on the Opportunity Product to ‘Existing Business’ else set the Net New field on Opportunity product to ‘New Business’
Let me know if this makes sense?
Love this! I am using this example to create something of my own. I am struggling with Step 7. Could you explain the Variables NWQOLI.OpportunityId and the values VarT_NewOpportunityId a little more?
I assume you are creating these variable in step 7? I assume the Variable is an sObject Variable and then you are referencing what in the Value? A new variable or one you already created.
Please help as I am soooo close!
In step 4 I’m creating a new Opportunity record and storing it to a variable {!VarT_OldOpportunityId}.
In step 7 I am assigning {!VarT_OldOpportunityId} to NWQOLI.OpportunityId
Hi Rakesh,
This is a great article. I am also struggling with step 7; can you explain in a bit more detail how you get it to look like in your screenshot? I can’t get the variables to look like yours. I am choosing SObject Variable type, but mine look self-refrencing like “{!NEWOLI_OpptyID} equals {!NEWOLI_OpptyID}”
Thanks for reading!
{!NEWOLI} is a SObject Variable and you have to assign New Opportunity ID to {!NEWOLI_OpptyID}
Two questions:
1) Don’t you need the ability to choose a Pricebook? Would you query from active Pricebooks and present a list to the User somehow?
2) I have a need to do a variation on this. Let’s say there are 5 Products on the Opp and you want to prioritize shipping for one or more. I would like a list of Products to be presented, have the User select one, and then enter some details, and then be asked “would you like to prioritize another? And then the user should be able to prioritize a second, third, etc.
3) Finally, building upon #2, I would like it if, when the Flow is launched again, it realizes that some Products have already been prioritized, and shows the User “these have already been prioritized, would you like to prioritize one of the remaining Products or modify one of the prioritizations you’ve already made?
I guess that’s three questions. 😀
1) Please refer step 4
2 & 3) Use Screen element to display all the products and allow them to select one or multiple items
This was great Rakesh!
At the beginning of the post you mention that there are a few possible solutions for this business case, do other solutions differ substantially from this one, or they are basically variations of the same thing?
Thanks
Variation of same thing using Apex etc
Brilliant. I had seen demos of this and wanted to get my hands dirty. This is the perfect exercise to do so. Thank you for posting this easy-to-follow walk-through.
Thank you!
Thank you so much, this was an incredible resource. You saved me and my team lots of time and frustration.
Glad to know that!
Awesome! You rock Rakesh.
Thanks Arush 🙂
Excellent! This is what I was looking for. Great work Rakesh.
Thanks Meghan 🙂
HI Rakesh,
When opportunity add products that amount reflected to contract object amount field , using flow + process builder,how to do this please help on this(urgent).
Thnaks Rakesh .