Auto-generate Renewal Opportunity With Line Items

Auto-generate Renewal Opportunity With Line Items

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:

  1. Define flow properties for record-triggered flow
  2. Create a Formula field to generate a close date for a renewal opportunity 
  3. Add a Record variable to store the opportunity line item
  4. Add a Record collection variables to store opportunity line items
  5. Add a Decision element to validate the opportunity Stage equals Closed Won
  6. Add a Create Records element to generate a renewal opportunity
  7. Add a Get Records element to find line items for the old opportunity 
  8. Add a decision element to check if opportunity line item record(s) exists 
  9. Add a Loop element to extract records from the collection variable (From step 7)
  10. Add an Assignment to populate OpportunityId to the opportunity line item record variable
  11. Add an Assignment element to add all line items into a record collection variable  (Created in step 4)
  12. Add a Create Records element to insert opportunity line Items to renewal opportunity (Bulk safe)

Step 1: Salesforce Flow – Define Flow Properties 

  1. Click Setup.
  2. In the Quick Find box, type Flows.
  3. Select Flows then click on the New Flow.
  4. Select the Record-Triggered Flow option, and click on Create and configure the flow as follows:
    1. Object: Opportunity
    2. Trigger the Flow When: A record is created or updated
    3. Set Entry Criteria
      1. Condition Requirements: None
    4. Optimize the Flow For Action and Related Records 
  5. 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 

  1. Under Manager click New Resource to create a formula for renewal opportunity close date.
  2. Input the following information: 
    1. Resource Type: Formula
    2. API Name: forD_RenewalOpportunityCloseDate
    3. Data Type: Date
    4. Formula: {!$Record.CloseDate} + 365
  3. Click Done.

Step 3: Salesforce Flow – Add a Record Variable to Store Opportunity Line item Record

  1. Under Manager, click New Resource to create a variable to store opportunity line item records.
  2. Input the following information: 
    1. Resource Type: Variable
    2. API Name: varR_OpportunityLineItem
    3. Data Type: Record
    4. Object: OpportunityLineItem
    5. Check Available for Input
    6. Check Available for Output
  3. Click Done

Step 4: Salesforce Flow – Add a Record Collection Variable to Store Opportunity Line items Records

  1. Under Manager, click New Resource to create a variable to store opportunity line item records.
  2. Input the following information: 
    1. Resource Type: Variable
    2. API Name: varR_OpportunityLineItems
    3. Data Type: Record
    4. Click the Yes checkbox – Allow multiple values (collection)
    5. Object: OpportunityLineItem
    6. Check Available for Input
    7. Check Available for Output
  3. 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. 

  1. On Flow Designer, click on the + icon and select Decision element. 
  2. Enter a name in the Label field; the API Name will auto-populate.
  3. Under Outcome Details, enter the Label the API Name will auto-populate.
  4. Condition Requirements to Execute Outcome: All Conditions Are Met (AND)
    1. Row 1:
      1. Resource: {!$Record.StageName}
      2. Operator: Equals
      3. Value: Closed Won

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.

  1. On Flow Designer, click on the + icon and select Create Records element. 
  2. Input the following information:
    1. Enter Label the API Name will auto-populate.
    2. How Many Records to Create: One
    3. How to Set the Record Fields: Use separate resources, and literal values
    4. Object: Opportunity
    5. Set Field Values for the Opportunity
    6. Row 1:
      1. Field: CloseDate
      2. Value: {!forD_RenewalOpportunityCloseDate}
    7. Click Add Field
    8. Row 2:
      1. Field: Name
      2. Value: {!$Record.Name}
    9. Click Add Field
    10. Row 3:
      1. Field: Pricebook2Id
      2. Value: {!$Record.Pricebook2Id}
    11. Click Add Field
    12. Row 4:
      1. Field: RecordTypeId
      2. Value: {!$Record.RecordTypeId}
    13. Click Add Field
    14. Row 5:
      1. Field: StageName
      2. Value: Prospecting
    15. Click Add Field
    16. Row 5:
      1. Field: AccountId
      2. Value: {!$Record.AccountId}
  3. 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.

  1. On Flow Designer, click on the + icon and select Get Records element. 
  2. Enter a name in the Label field; the API Name will auto-populate.
  3. Select the Opportunity Product object from the dropdown list.
  4. Select All Conditions Are Met (AND). 
  5. Set Filter Conditions
    1. Row 1:
      1. Field: OpportunityId
      2. Operator: Equals
      3. Value: {!$Record.Id}
  6. How Many Records to Store:
    1. select All records
  7. How to Store Record Data:
    1. Choose the option to Automatically store all fields. 
  8. 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. 

  1. On Flow Designer, click on the + icon and select Decision element. 
  2. Enter a name in the Label field; the API Name will auto-populate.
  3. Under Outcome Details, enter the Label the API Name will auto-populate.
  4. Condition Requirements to Execute Outcome: All Conditions Are Met (AND)
    1. Row 1:
      1. Resource: {!Get_Line_Items}
      2. Operator: Is Null 
      3. Value: {!$GlobalConstant.False}
  5. 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.

  1. On Flow Designer, click on the + icon and select Loop element. 
  2. Enter a name in the Label field; the API Name will auto-populate.
  3. For the Record Collection Variable select {!Get_Line_Items}.
  4. For Specify Direction for Iterating Over Collection select the option First item to last item
  5. 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. 

  1. On Flow Designer, click on the + icon and select Assignment element. 
  2. Enter a name in the Label field; the API Name will auto-populate.
  3. Set Variable Values
    1. Row 1:
      1. Field: {!varR_OpportunityLineItem.OpportunityId}
      2. Operator: Equals
      3. Value: {!Create_Renewal_Opportunity}
    2. Add Assignment
    3. Row 2:
      1. Field: {!varR_OpportunityLineItem.PricebookEntryId}
      2. Operator: Equals
      3. Value: {!Line_Items.PricebookEntryId}
    4. Add Assignment
    5. Row 3:
      1. Field: {!varR_OpportunityLineItem.UnitPrice}
      2. Operator: Equals
      3. Value: 0
    6. Add Assignment
    7. Row 4:
      1. Field: {!varR_OpportunityLineItem.Quantity}
      2. Operator: Equals
      3. Value: {!Line_Items.Quantity}
  4. 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. 

  1. On Flow Designer, click on the + icon and select Assignment element. 
  2. Enter a name in the Label field; the API Name will auto-populate.
  3. Set Variable Values
    1. Row 1:
      1. Field: {!varR_OpportunityLineItems}
      2. Operator: Add
      3. Value: {!varR_OpportunityLineItem}
  4. 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.

  1. On Flow Designer, click on the + icon and select Create Records element. 
  2. Input the following information:
    1. Enter Label the API Name will auto-populate.
    2. How Many Records to Create: Multiple
    3. Select Values to Create Multiple Records: 
      1. Record Collection: {!varR_OpportunityLineItems}
  3. Click Done.

In the end, Steven’s Flow will look like the following screenshot:

Once everything looks good, perform the steps below: 

  1. Click Save.
  2. Enter Flow Label the API Name will auto-populate.
  3. Click Show Advanced.
  4. API Version for Running the Flow: 54
  5. Interview Label: Auto-generate renewal Opportunity with OLI {!$Flow.CurrentDateTime}
  6. 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. 

  1. Opportunity Aethna Home Products is in Stage Qualification and three products are associated with it, as shown in the following screenshot:
  2. 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.

Have feedback, suggestions for posts, or need more information about Salesforce online training offered by me? Say hello, and leave a message!
Preferred Timing(required)

87 thoughts on “Auto-generate Renewal Opportunity With Line Items

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

    1. Sorry Veena, but I didn’t get you.
      Do you want to add all products from the old Opportunity to new Opportunity? – Please confirm

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

  3. 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!

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

      1. 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!

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

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

          1. When you create an opportunity you have the ID – in our case {!VarT_NewOpportunityId}. In the assignment element use this ID

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

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

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

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

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

  9. 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 )

  10. 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!

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

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

  12. Hey Rakesh,

    Super interesting and helpful. How would you work with upsells/downsells during the renewal period?

    Thanks for all the help so far!

  13. 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!

  14. 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!

  15. 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?

      1. 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!

  16. 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?

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

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

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

      1. 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?

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

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

      1. 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?

  20. 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!

      1. 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}”

  21. 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. 😀

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

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

    1. 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).

        1. Use Fast Lookup on Opportunity Products to get all details for same opportunities.
        2. Use Loop element to get the Amount from each Opportunity Products and store in a SObject Variable.
        3. Add all SObject Variables data into a variable (Basically Amount)
        4. Then use Record update to update the Contract.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.