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 

Get all PDFs from all Quotes from an Opportunity - Apex Inner Join?

Hello guys,

I have the following feature request:

On the opportunity level I want to see all pdfs from all quotes from that very opportunity. So I think (hopefully) this is something Apex can do for me. 

As I am not much of a developer I was thinking I need something like:
ListOfPDFs = [SELECT Id, ... FROM Quote (SELECT Id,... FROM QuotePDF) WHERE Opportunity.Id = currentOpportunity
In the end I want to display it as a simple table in visualforce. 

Any advice is appreciated

Thanks a lot!
ANUTEJANUTEJ (Salesforce Developers) 
Hi Janno,

You could run the particular soql query from the query editor to see if the soql is returning any records and if not make adjustments accordingly to meet your requirement.

>> https://www.sfdc99.com/2013/06/09/example-how-to-write-a-cross-object-soql-query/

>> https://www.sfdc99.com/2013/06/24/example-how-to-write-a-cross-object-soql-query-part-2/

I hope the above links could help in reference to get your solution.

Regards,
Anutej 
AnudeepAnudeep (Salesforce Developers) 
Hi Janno, 

Let me know if the following query helps
[SELECT id, (SELECT id, quoteId FROM QuoteLineItems) FROM Quote where opportunityId=:oppId];

Anudeep
Janno RipJanno Rip
Since I am aiming for the PDFs "QuoteLineItem" is not doing me any good. So I tried:
SELECT id, (SELECT id, QuoteId FROM QuoteDocument) FROM Quote where opportunity.Id = '0061X00000AjqmqQAB'

but it results in:

ERROR at Row:1:Column:28
Didn't understand relationship 'QuoteDocument' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names.
AnudeepAnudeep (Salesforce Developers) 
Hi Janno, 

The child relationship name is QuoteDocuments
 
SELECT id, (SELECT id, QuoteId FROM QuoteDocuments) FROM Quote where opportunity.Id = '0061X00000AjqmqQAB'
Let me know if it helps

Anudeep
 
Janno ToJanno To
Hey guys,

so I tried running the query but no results turn up even there exists a pdf in that quote. Is it even possible to access the pdf Ids?

Furthermore I tried the following:
 
public class QuoteList {

public Opportunity currentOpp {get;set;}
public List<Quote> pdfs {get; private set;} 

 public QuoteList(ApexPages.StandardController stdController) {
     currentOpp  = [SELECT Id FROM Opportunity WHERE ID =: stdController.getID()];
     }
     
 public PageReference getPdfs() {     
     
pdfs = [SELECT id,Name, (SELECT id, QuoteId FROM QuoteDocuments) FROM Quote where opportunity.Id = :currentOpp.Id];

return null;


}
}

Initially I was aiming for public List<QuoteDocuments> pdfs {get; private set;} but this is not working.

My VF Page only returns the list of quotes
<apex:page standardcontroller="Opportunity" extensions="QuoteList" docType="html-5.0" lightningStylesheets="true" action="{!getPdfs}"> 
           
            <apex:form >
        <apex:pageBlock>
            <apex:pageBlockTable value="{!pdfs}" var="pdf">
                <apex:column value="{!pdf.Name}"/> 
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
           
 </apex:page>

User-added image
This is the part where I want to see the pdfs :<
Janno RipJanno Rip
I have played around a bit and this is my best solution so far:

class:
 
public class QuoteList { 

public Opportunity currentOpp {get;set;} 
public List<Quote> quotes {get;set;} 

public QuoteList(ApexPages.StandardController stdController) 

{ 
currentOpp = [SELECT Id FROM Opportunity WHERE ID =: stdController.getID()]; 
} 

public PageReference getPdfs() { quotes = [SELECT Id,Name,(SELECT Id,Name,ContentVersionDocumentId,QuoteId FROM QuoteDocuments)FROM Quote WHERE OpportunityId = :currentOpp.id]; 

return null; 

} 
}

visualforce page:
 
<apex:page standardcontroller="Opportunity" extensions="QuoteList" lightningStylesheets="true" action="{!getPdfs}"> 

<apex:form >
<apex:pageBlock >
<apex:pageBlockSection >
<apex:repeat value="{!quotes }" var="quote"> 
<apex:repeat value="{!quote.QuoteDocuments}" var="pdf" >

<apex:outputField value="{!pdf.ContentVersionDocumentId}" /> 

<a href="/{!pdf.ContentVersionDocumentId}"> 
{!pdf.Name} 
</a> 

</apex:repeat> 
</apex:repeat> 
</apex:pageBlockSection> 
</apex:pageBlock>
 </apex:form>
 </apex:page>

For reasons I don't understand <apex:outputField value="{!pdf.ContentVersionDocumentId}" /> is directly creating a link. Which is actually what I want in the end but it has some weird behaviour when opening it in a new tab. In addition to that there seems to be a problem with the "name" when I create my quotes via a flow where the names are being defined.

User-added image