I have a community site with e-shop. I have a process builder which fires a platform event after 24 h of opportunity creation if it is not closed by then. Opportunities are created by community users. Problem is the automated process that handles the whole logic of creating quote object to the opportunity and then generating quote pdf seems to miss couple of information on the pdf. I've tried changing the opportunity owner to automated process but the quote information was still incomplete. Here's the code below and quotes for the same opportunity but created in these two ways:

invoice 1 invoice 2

global without sharing class FF_QuoteService {

    global static void prepareQuoteForOpportunity(String opportunityId) {
//        changeOpportunityOwnerToAutomatedProcess(opportunityId);
        Quote newQuote = createQuote(opportunityId);
        createQuoteLineItems(newQuote, opportunityId);

    private static Quote createQuote(String opportunityId) {
        Opportunity opportunity = [SELECT Id,Name,CreatedById,OwnerId,Owner.Email,CreatedBy.Email FROM Opportunity WHERE Id = :opportunityId];
        Quote newQuote = new Quote();
        newQuote.OpportunityId = opportunityId;
        Contact contact = [SELECT Id,Email FROM Contact WHERE Email = :opportunity.CreatedBy.Email];
        newQuote.ContactId = contact.Id;
        newQuote.Email = contact.Email;
        newQuote.Name = 'Quote for ' + opportunity.Name;
        insert newQuote;
        return newQuote;

    private static void createQuoteLineItems(Quote quote, String opportunityId) {
        List<OpportunityLineItem> opportunityItems = [SELECT Id,UnitPrice,TotalPrice,Quantity,Product2Id,PricebookEntryId FROM OpportunityLineItem WHERE OpportunityId = :opportunityId];
        for (OpportunityLineItem opportunityItem : opportunityItems) {
            QuoteLineItem quoteItem = new QuoteLineItem();
            quoteItem.QuoteId = quote.Id;
            quoteItem.UnitPrice = opportunityItem.UnitPrice;
            quoteItem.Quantity = opportunityItem.Quantity;
            quoteItem.Product2Id = opportunityItem.Product2Id;
            quoteItem.PricebookEntryId = opportunityItem.PricebookEntryId;
            insert quoteItem;

    public static void generatePdf(String quoteId,String opportunityId, String email, String contactId) {
        String templateID = '0EH090000018wx1';
        String quoteUrl = '/quote/quoteTemplateDataViewer.apexp?id=';

        quoteUrl += quoteId;
        quoteUrl += '&headerHeight=190&footerHeight=188&summlid=';
        quoteUrl += templateID ;
        quoteUrl += '#toolbar=1&navpanes=0&zoom=90';

        PageReference pg = new PageReference(quoteUrl);
        QuoteDocument quotedoc = new QuoteDocument();

        Blob b = pg.getContentAsPDF();

        quotedoc.Document = b;
        quotedoc.QuoteId = quoteId;
        insert quotedoc;
//        changeOpportunityOwnerToOriginal(opportunityId);

    private static void sendEmail(String opportunityId, String email, QuoteDocument document, String contactId){
        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
        message.setToAddresses(new String[] { email });
        List<OrgWideEmailAddress> addresses = [SELECT Id FROM OrgWideEmailAddress WHERE Address = 'patryk.badowiec@britenet.com.pl'];
        if (!addresses.isEmpty()) {

        Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
        efa.setFileName('Furni Future marketing quote');

        message.setFileAttachments(new List<Messaging.EmailFileAttachment>{efa});

        EmailTemplate template = [SELECT Id, Subject, HtmlValue FROM EmailTemplate WHERE Name = 'Quote notification'];

        try {
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] { message });
        } catch (Exception exc) {
//            System.debug(exc);
            throw exc;

    private static void changeOpportunityOwnerToAutomatedProcess(String opportunityId){
        String automatedProcessUserId = [SELECT Id,Name FROM User WHERE Name = 'Automated process'].Id;
        Opportunity opportunity = [SELECT Id FROM Opportunity WHERE Id=:opportunityId];
        opportunity.OwnerId = automatedProcessUserId;
        upsert opportunity;

    private static void changeOpportunityOwnerToOriginal(String opportunityId){
        Opportunity opportunity = [SELECT Id,CreatedById FROM Opportunity WHERE Id=:opportunityId];
        opportunity.OwnerId = opportunity.CreatedById;
        upsert opportunity;


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.