Getting Started with Salesforce Flow – Part 71 (Now, Generating a Quote PDF is a breeze! Learn how!)

Getting Started with Salesforce Flow – Part 71 (Now, Generating a Quote PDF is a breeze! Learn how!)

Last Updated on October 10, 2021 by Rakesh Gupta

The last thing you want your Sales teams to do is to get ensnared in manual – or procedural – activities; they are your horsepower, free them up to do what they do best – Sell! Does that mean activities – not directly related to selling – can be eschewed? Far from it! 

Let us have our cake and eat it too – think automation!!

Multiple research affirms the positive impact of automation on the bottom line! By leveraging automation, we can ensure that activities – not directly related to sales – get done without burdening your sales team. 

Let us take a simple use case – generating a quote PDF whenever a customer is ready to receive a formal proposal containing the most current pricing information and product quantities. To generate a quote pdf should not require salespeople to click a button! And, thanks to Salesforce Flow, we can make that a reality!

Objectives:

After reading this blog, you’ll be able to: 

  • Understand what a Quote is
  • Use filters and conditions to design a flow
  • Understand the Apex callout process in Salesforce Flow

Business Use case

Martin Jones is a System Administrator at Gurukul on Cloud (GoC). He received a requirement to auto-generate a quote pdf whenever a quote gets created (only if Opportunity amount is greater than 0) so that salespeople can spend less time in Salesforce and more time selling.  

What is a Quote?

A quote is a detailed list – of products or services with prices, shipping and billing addresses, payment terms and taxes, etc. – that is sent by a seller to a prospective buyer. Quotes usually have different statuses (Draft, In Review, Presented, Approved, Rejected, or Cancelled) depending on the stage of the sales process.

As of Winter’22 release, salespeople had to manually generate a quote pdf by clicking on the Generate PDF button. We can do better than that as automation champions – let us automate this process. 

Automation Champion Approach (I-do):

Usually, with Salesforce, multiple approaches are available to solve a business requirement. Choose the ones that are simple, straight forward, and consume fewer resources. 

Similarly in this scenario, either use Apex trigger or a combination of Flow and Process Builder.

Let us solve this scenario using After-save Record-Triggered Flow and Apex – as this business case involves generating PDF out of a quote record. Check out this article to understand why we are using after-save record-triggered flow for this scenario.

Before discussing the solution, let me show you a diagram of a Process Flow at a high level. Please spend a few minutes going through the following Flow diagram and understand it. Screen Shot 2020-06-17 at 1.01.02 AM Let’s begin building this automation process.

Guided Practice (We-do):

There are 3 steps to solve Martin’s business requirement using After-save Record-Triggered Flow. We must:

  1. creating a custom label to store Quote Template Id
  2. Create Apex class & Test class
  3. Salesforce flow
    1. Define flow properties for record-triggered flow
    2. Create a formula to determine whether the quote record is new or old
    3. Add a decision element to check if opportunity amount is greater than $0
    4. Add action – call an Apex class to generate quote pdf

Step 1: Creating a Custom Label 

  1. Click Setup.
  2. In the User Interface, type Custome Labels.
  3. Clicks on the New Custom Label button.
  4. Enter Short Description the Name will auto-populate. 
  5. Now enter the Quote Template Id in the Value.
  6. Click Save

PB 96.1

Step 2: Create an Apex class and Test class   

  1. Click Setup.
  2. In the Quick Find box, type Apex Classes.
  3. Clicks on the New button.
  4. Copy code from GitHub and paste it into your Apex Class. 
  5. Click Save.

PB - 97.3.45 Repeat the above steps and click the Test class. You can get the code from my GitHub repo. 

Step 3.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 Next and configure the flow as follows:
    1. How do you want to start building: Freeform
    2. Object: Quote
    3. Trigger the Flow When: A record is created or updated
    4. Set Entry Criteria
      1. Condition Requirements: None
    5. Optimize the Flow For: Action and Related Records
  5. Click Done.

Tips: Never try to write entry criteria in a Record-Triggered Flow. 

Step 3.2: Salesforce Flow – Formula to Determine Whether the Quote Record is New or Old

  1. Under Toolbox, select Manager, then click New Resource to store the audit__share mapping detail.
  2. Input the following information:
    1. Resource Type: Formula
    2. API Name: forBIsNew
    3. Data Type: Boolean
    4. Formula: IsNew()
  3. Click Done.

Step 3.3: Salesforce Flow – Using Decision Element to Check the Opportunity Amount

Now we will use the Decision element to check the opportunity amount to ensure that it is greater than $0.

  1. Under Toolbox, select Element.
  2. Drag-and-drop Decision element onto the Flow designer.
  3. Enter a name in the Label field; the API Name will auto-populate.
  4. Under Outcome Details, enter the Label the API Name will auto-populate.
  5. Condition Requirements to Execute Outcome: All Conditions Are Met (AND)
    1. Row 1:
      1. Resource: {!$Record.OpportunityId}
      2. Operator: Is Null
      3. Value: {!$GlobalConstant.False}
    2. Add Condition
    3. Row 2:
      1. Resource: {!$Record.Opportunity.Amount}
      2. Operator: Greater Than
      3. Value: 0
    4. Add Condition
    5. Row 2:
      1. Resource: {!forBIsNew}
      2. Operator: Equals
      3. Value: {!$GlobalConstant.True}
  6. Click Done.

Step 3.4: Salesforce Flow – Adding an Action to Call Apex class to Generate Quote PDF

  1. Under Toolbox, select Element.
  2. Drag-and-drop the Actions element onto the Flow designer.
  3. Select the GenerateQuotePdfDocument Apex class. 
  4. Enter a name in the Label field- the API Name will auto-populate.
  5. Set Inout Values:
    1. Field: quoteIds
    2. Value: {!$Record.Id}
  6. Click Done.

In the end, Martin’s Flow will look like the following screenshot (I turned on Auto-Layout) for this flow:

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: 53
  5. Interview Label: Record-Trigger: Quote After Save {!$Flow.CurrentDateTime}
  6. Click Save.

Almost there! Once everything looks good, click the Activate.

It’s time to test this feature!

Next time, when a Sales rep creates a quote and associates it with Opportunity (obviously Opportunity amount must be greater than 0) then, then Salesforce Flow will fire and auto-generate a quote pdf for it. 

Great! You are done! Feel free to modify it based on your business requirement. 

Formative Assessment:

I want to hear from you!

What did you learn from this post, is it relevant to you, and how will you modify the concepts taught in the post for your own business processes?

Make a post and tag me on Twitter @automationchamp using #AutomationChampionFlow.

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

17 thoughts on “Getting Started with Salesforce Flow – Part 71 (Now, Generating a Quote PDF is a breeze! Learn how!)

  1. HI , Team i need a solution for Custom Quote pdf generation.
    i am done the vf and apex class but button on PDF how to do, any idea.
    {save and email quote } && {save to quote} how to create these on PDF why because i an customizing total pdf.

  2. Hi there, I am using this and it has been working wonderfully, but I have had one issue when I updated the quote template to add some more details to the footer of the quote. For some reason when it is manually generated, the footer shows up blank. When I manually click to generate the PDF quote it shows up. Any thoughts on why this could be?

  3. I am calling this Apex from a screen flow that allows the user to input some relevant quote information before generating the quote and pdf. When I run the debug from the flow, it works wonderfully. When I run the flow from a lightning action, the pdf displays blank. I checked the debug logs for both instances and they’re practically identical so I can’t tell where it’s broken. Any thoughts?

  4. Hi Rakesh, I have an error on the test class. Error: Compile Error: Variable does not exist: RecordTypeId at line 25 column 12.
    I removed the “AND developerName = ‘Manufacturing'” as I don’t need it but still not working. Any idea why? I would also like to attach the PDF to a custom object instead of the opportunity. But let’s start to make it work 🙂

    1. If you are not using the RecordType in Opportunity, then remove all references. Like the following code:

      @istest
      private class generateQuotePdfDocumentTest {

      @testSetup
      static void setup() {

      Product2 product = new Product2();
      product.Name = 'Test Product ';
      product.ProductCode = '123';
      product.IsActive = true;
      insert product;

      PricebookEntry pbe = new PricebookEntry();
      pbe.Pricebook2Id = Test.getStandardPricebookId();
      pbe.Product2Id = product.Id;
      pbe.IsActive = true;
      pbe.UnitPrice = 10;
      insert pbe;

      Opportunity op = new Opportunity();
      op.Name = 'Test';
      op.Type = 'Value Proposition';
      op.Amount= 1200;
      op.CloseDate = Date.today().addDays(2);
      op.StageName = 'Created';

      insert op;

      Quote quote = new Quote();
      quote.OpportunityId = op.Id;
      quote.Name = 'TestQuote';
      quote.ExpirationDate = Date.today().addDays(5);
      quote.Status = 'Draft';
      quote.Pricebook2Id = Test.getStandardPricebookId();
      insert quote;

      QuoteLineItem qli = new QuoteLineItem();
      qli.QuoteId = quote.Id;
      qli.Quantity = 2;
      qli.PricebookEntryId = pbe.Id;
      qli.UnitPrice = 20;
      insert qli;
      }

      @isTest
      static void generateQuotePdfTest() {

      Quote quote = [SELECT Id, Status FROM Quote LIMIT 1];

      quote.Status = 'Draft';
      update quote;
      }

      }

  5. Awesome stuff Rakesh! I found this article yesterday and gave it a try with Flow. I was able to repurpose it for our Quote Process and have the PDF generated automatically at the end of a guided screen flow.
    Just working on attaching the PDF and emailing it to the related contact now (also in Flow).
    One other thing, i’ve never written an APEX class and test class before, so quite happy that I was able to take yours and adjust it to my requirements.
    Thanks for the great content!
    Paul

  6. I love that you have Conga and Docmotion as sponsors and yet chose to publish this kind of article, kuddos to you Sir !

Leave a Reply

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