4

I want to insert a record in an object 'Invoice__c', after that I want to create an attachment related to this invoice. This attachment is a visualforce rendered as PDF. I have problems to call createInvoiceAttachment after createInvoice int the same execution context. In different context everything is right. What can i do?

Exectuion

Invoice__c i = Utils.createInvoice('0064E000002Jc91');
Utils.createInvoiceAttachment(i);

Utils class

public class Invoice {

    public static Invoice__c createInvoice(String oppId){
      Invoice__c inv        = new Invoice__c();
      inv.opp__c            = oppId;
      insert inv;
    }


    public static Attachment createInvoiceAttachment(Invoice__c inv){

      PageReference pdf = Page.InvoicePage;
      pdf.getParameters().put('id',inv.id);

      Attachment at     =   new Attachment();
      at.Body           =   pdf.getContentAsPDF();
      at.ParentId       =   inv.Id;
      insert at;
    }

}
  • what the error it is throwing? – Santanu Boral Aug 20 '16 at 21:46
5

The problem is that the modification you are making in the current transaction has not been committed when you make the getContentAsPDF call, as that call is treated as a separate transaction now. This change was delivered as a Critical Update, and that update auto-activated in January 2016. Deactivating that update as Santanu suggests is the pragmatic fix right now, but there may be a time when this change cannot be deactivated.

To fix without requiring the deactivation, you need to move the logic to a point after the transaction commits. One way is to use one of the asynchronous Apex mechanisms such as @future. Another way, if this logic is part of a controller, is to redirect back to an additional method in the controller that does the PDF generation as each controller request is a separate transaction.

3

After Summer'15 release getContent() and getContentAsPDF() behave as callouts. Refer getContent as callout

According to your requirement, if you do not want to them treated as callouts then update the deactivate the entry from Critical Update section.

From Setup, click Critical Updates.

Click Deactivate for “PageReference getContent() and getContentAsPDF() Methods Treated as Callouts.”

  • 1
    This would only be a temporary solution that would last only a few months. It'd be better to fix the code so it works correctly next release. – sfdcfox Aug 21 '16 at 4:32
  • @sfdcfox, but what will be the correct code if there is only 1 action after the insert and it is generating the pdf? I try at future but for some reason it breaks – manza Mar 9 '18 at 8:54
  • @manza You need to use @future(callout=true) and make sure you do not have any DML before you do the callout in the future method (normal callout limitations). – sfdcfox Mar 9 '18 at 15:04
  • @sfdcfox thank you so much for the comment, but what I dont understand or know how to do, is I need to do the DML before, becuase the pdf is based on the record, I have added a future method that is called after the DML so within the method there is no DML, but I think the problem is the constructor of the pdf page controller has a DML to bring the values, will this be the cause of the PDF been broken only when called from my future method? can you please give me a suggestion on how to by pass this? Thank you – manza Mar 9 '18 at 19:06
  • @manza Consider asking a new question, and include your code. It's hard to get anything done in comments, and you shouldn't be revivifying old threads like this. We're not a forum, we're a Q&A community. – sfdcfox Mar 9 '18 at 19:21

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.