Generate and send invoice/quote PDFs via API

Hi SuiteCRM Community,

we are using the API (v4.1) to automatically create about 200 invoices monthly using a cron job without the need of manually working inside of the webUI in SuiteCRM (SuiteCRM v 7.10.6 based on SugarCRM v 6.5.25 -Build 344).

We want to send out these generated invoices as emails, preferably as PDF attachments. If this is not possible, we would like to retrieve the PDF binary file from SuiteCRM via the API either as a binary object or a string of the location where the generated invoice was saved as a PDF on the filesystem, so that we can then programmatically work with this PDF. This means if it is not possible to send the invoice as an email attachment using the API natively from SuiteCRM we will write a small PHP or PY application which does this task using native PHP/PY code.

I did a bit of an investigation and found a few threads

Printing a PDF using the API
https://community.sugarcrm.com/thread/21621

Printing invoice as a PDF using the API
https://suitecrm.com/suitecrm/forum/developer-help/15949-invoice-print-as-pdf-from-list-view
And
https://suitecrm.com/suitecrm/forum/developer-help/2765-add-print-as-pdf-optoin-in-other-module

some useful links:
https://github.com/salesagility/SuiteCRM/blob/master/modules/AOS_PDF_Templates/sendEmail.php
https://github.com/salesagility/SuiteCRM/blob/master/modules/Emails/EmailUIAjax.php
https://github.com/salesagility/SuiteCRM/blob/master/include/SugarPHPMailer.php

I have also checked the headers for me it looks like that the UI sends a post request to

https://CRM/index.php?entryPoint=generatePdf

With (in my case) these values:
module AOS_Invoices
task pdf
templateID 6836f4e4-de49-27fe-6e15-5b20988fe59c
uid 38bead15-2994-3354-b6f8-5b6a87dc52c6

and then the browser receives the PDF as a binary object.

Can we do that using the API or do we need to simulate the login process to get the cookies and then perform the http post to get the PDF returned?

Can anyone assist me and point me in the right direction?

Looking at what I found on the internet, I am aiming to use this thread to help others to get some useful information.

Regards,
Aiden.

May I suggest a different approach? I believe it will be easier.

Just tweak the code for the campaigns, when it is about to send with an attachment, so that instead of sending the same attachment out to everyone, it grabs a separate file for each one, based on some naming convention (like invoice 007-may-2018.pdf for customer number 007).

You can either get the file from the file system, or from the related beans (Notes/Attachements).

Any progress here?
I am also looking into how to create the PDFs and email them by using some API.

How I would approach this is:

  1. Extend the 4_1 API to create a new entrypoint e.g. API call like “generate_pdf”
  2. Look at what the generatePDF method requires via the UI. I would suggest finding out where the entrypoint leads to - hint modules/AOS_PDF_Templates/generatePdf.php
  3. Using that script base your functionality within your new custom API call to perform it. Appears that you ‘at least’ need the UID and TemplateID (assuming its the record id and the record id of the pdf template). So when you have created the new API call you ensure you have those parameters as the minimum passed through.
  4. I would suggest as part of your custom API call that you return the public url of the PDF by either moving the created pdf into a public directory OR you could create a new note record and add the pdf to that note and return the note id to then make the downloadable accessible e.g. /index.php?entryPoint=download&id=&type=Notes

Hope that helps.

Hi,

That’s nearly what we did for QuickCRM to open or send a PDF in the app, except that our function returns the PDF contents instead of the URL so that we can implement both actions.

You should also have


		$GLOBALS['disable_date_format']= false;
		// generate PDF
		$GLOBALS['disable_date_format'] =true;

to avoid dates being displayed in database format.

@samus-aran,
It would have been much easier if you had an intermediate function with $module,$uid,$templateID and $task as parameters so that this function could be called from a custom API, rather then completely re-writing a custom generatePdf.php that changes $_REQUEST to values obtained by the API
And with a new $task value like ‘raw’ that would return the PDF contents with $pdf->Output("", “S”);
Then, any change or improvement you would make in PDF generation would be used in a custom generatePdf.php

I second @blqt suggestion on Making the Generate PDFs (modules/AOS_PDF_Templates/generatePdf.php) actions more generic such as adding an option to send back generated PDFs URL and Raw data for user use in their view.

One other suggestion as a side note is that can TCPDF not become a second library for generating PDFs apart from mPDF (v5.7.1 released 2013 is included in SuiteCRM) .

On a side note, adding a parse function in SugarFieldBase.php, overriden for enums and other fields requiring it to display the actual value would:

  • make that function easier to extend (for example to display signature fields from SugarOutfitters or SuiteCRM Store or any kind of custom types)
  • definitively solve the issue with Email templates not correctly parsed in most SuiteCRM versions.