function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Janno RipJanno Rip 

Generate Quote PDF via Apex returns blank

Hello guys,

I am trying to automate the generation of quote pdfs. I have found a really nice blog entry on that topic here: https://automationchampion.com/2020/06/23/getting-started-with-process-builder-part-97-now-generating-a-quote-pdf-is-a-breeze-learn-how/?fbclid=IwAR0QHkSOjk2TG9hzdthNAbJ88hQjKjGX8FuV_UicCcnT_N-sfp5PJBicXVo

Everything works fine except for the fact that pdf just turns out completely blank.

Here the code from github:
Public class generateQuotePdfDocument{
    @InvocableMethod   

    //https://github.com/Rakeshistom/Auto-Generates-Quote-PDF

    public static void LeadAssign(List<Id> quoteIds)  
    { 
    //Initialize the quote url
    String quoteUrl = '/quote/quoteTemplateDataViewer.apexp?';
    
    //Get the Quote Template Id from Custom Settings
    String quoteTemplateId = Label.QuoteTemplateId;
    
    //List variable to get all the Quote Documents
    List<QuoteDocument> lstQuoteDoc = new List<QuoteDocument>();
    
    if(!quoteIds.isEmpty() && quoteIds.size() > 0) {
        
        for(Id quoteId :quoteIds) {
            //Construct the quote URL to generate PDF
            quoteUrl += 'id=' + quoteId;
            quoteUrl += '&headerHeight=197&footerHeight=10';
            quoteUrl += '&summlid=' + quoteTemplateId;
            
            //call the quote url
            PageReference pageRef = new PageReference(quoteUrl);
            
            //get the quotePdf
            Blob quoteBlob;
            
            if(Test.isRunningTest()) {
                quoteBlob = Blob.valueOf('Generate Pdf');
            } else {
                quoteBlob = pageRef.getContentAsPDF();
            }
            
            //initialze the QuoteDocument to hold the quote pdf for insertion
            QuoteDocument quoteDoc = new QuoteDocument();
            quoteDoc.Document = quoteBlob;
            quoteDoc.QuoteId = quoteId;
            lstQuoteDoc.add(quoteDoc);
        }
    }
    
    if(!lstQuoteDoc.isEmpty() && lstQuoteDoc.size() > 0) {
        Database.insert(lstQuoteDoc);
    }
    }
    }
Any thoughts what might be the problem?
Best Answer chosen by Janno Rip
Janno RipJanno Rip
I was able to fix this doing some research. Turns out I needed to call the actual code using @future(callout=true):
 
Public class generateQuotePdfDocument{

//https://github.com/Rakeshistom/Auto-Generates-Quote-PDF

@InvocableMethod   
public static void QuoteCreate(List<Id> quoteIds)  {
  callFutureMethod(quoteIds);
}

@future(callout=true)

public static void callFutureMethod (List<Id> quoteIds) {

    //Initialize the quote url
    String quoteUrl = '/quote/quoteTemplateDataViewer.apexp?';
    
    //Get the Quote Template Id from Custom Settings
    String quoteTemplateId = Label.QuoteTemplateId;
    
    //List variable to get all the Quote Documents
    List<QuoteDocument> lstQuoteDoc = new List<QuoteDocument>();
    
    if(!quoteIds.isEmpty() && quoteIds.size() > 0) {
        
        for(Id quoteId :quoteIds) {
            //Construct the quote URL to generate PDF
            quoteUrl += 'id=' + quoteId;
            quoteUrl += '&headerHeight=197&footerHeight=10';
            quoteUrl += '&summlid=' + quoteTemplateId;
            
            //call the quote url
            PageReference pageRef = new PageReference(quoteUrl);
            
            //get the quotePdf
            Blob quoteBlob;
            
            if(Test.isRunningTest()) {
                quoteBlob = Blob.valueOf('Generate Pdf');
            } else {
                quoteBlob = pageRef.getContentAsPDF();
            }
            
            //initialze the QuoteDocument to hold the quote pdf for insertion
            QuoteDocument quoteDoc = new QuoteDocument();
            quoteDoc.Document = quoteBlob;
            quoteDoc.QuoteId = quoteId;
            lstQuoteDoc.add(quoteDoc);
        }
    }
    
    if(!lstQuoteDoc.isEmpty() && lstQuoteDoc.size() > 0) {
        Database.insert(lstQuoteDoc);
    }

}
}

I still have some other issues since the pdf seems to get created before all process have been run - who determine the content. But that is more of a logic thing in my org which I will fix otherwise. Thanks for the input guys!

All Answers

AnudeepAnudeep (Salesforce Developers) 
Do you see any error in the console logs and do you see the same behavior across all browsers? 

A possible reason for this behavior may be that your org has the clickjack protection enabled. Generally, clickjack protection in Salesforce prevents a page, button, or link from appearing on your page that comes from a frame or iframe - which is the case with PDF previews. 

I suggest trying this example as well
Janno RipJanno Rip
I was able to fix this doing some research. Turns out I needed to call the actual code using @future(callout=true):
 
Public class generateQuotePdfDocument{

//https://github.com/Rakeshistom/Auto-Generates-Quote-PDF

@InvocableMethod   
public static void QuoteCreate(List<Id> quoteIds)  {
  callFutureMethod(quoteIds);
}

@future(callout=true)

public static void callFutureMethod (List<Id> quoteIds) {

    //Initialize the quote url
    String quoteUrl = '/quote/quoteTemplateDataViewer.apexp?';
    
    //Get the Quote Template Id from Custom Settings
    String quoteTemplateId = Label.QuoteTemplateId;
    
    //List variable to get all the Quote Documents
    List<QuoteDocument> lstQuoteDoc = new List<QuoteDocument>();
    
    if(!quoteIds.isEmpty() && quoteIds.size() > 0) {
        
        for(Id quoteId :quoteIds) {
            //Construct the quote URL to generate PDF
            quoteUrl += 'id=' + quoteId;
            quoteUrl += '&headerHeight=197&footerHeight=10';
            quoteUrl += '&summlid=' + quoteTemplateId;
            
            //call the quote url
            PageReference pageRef = new PageReference(quoteUrl);
            
            //get the quotePdf
            Blob quoteBlob;
            
            if(Test.isRunningTest()) {
                quoteBlob = Blob.valueOf('Generate Pdf');
            } else {
                quoteBlob = pageRef.getContentAsPDF();
            }
            
            //initialze the QuoteDocument to hold the quote pdf for insertion
            QuoteDocument quoteDoc = new QuoteDocument();
            quoteDoc.Document = quoteBlob;
            quoteDoc.QuoteId = quoteId;
            lstQuoteDoc.add(quoteDoc);
        }
    }
    
    if(!lstQuoteDoc.isEmpty() && lstQuoteDoc.size() > 0) {
        Database.insert(lstQuoteDoc);
    }

}
}

I still have some other issues since the pdf seems to get created before all process have been run - who determine the content. But that is more of a logic thing in my org which I will fix otherwise. Thanks for the input guys!
This was selected as the best answer