Append PDF Product Specifications to Printed Purchase Orders in D365FO

Let’s say that we want to print purchase orders with all corresponding product specifications appended at the end of output document generated in PDF format. We will assume that product specifications are PDF documents stored as Attachments (Document management) of built-in Products in D365FO. In this article we will provide an X++ solution for achieving this scenario in D365FO, which is based on Docentric’s capability of merging PDF documents.

Limitations

This solution has the following limitations:

  1. Output report format has to be PDF.
  2. Only Product Attachments in PDF format will be appended to the Purchase order report. If there are no such Attachments for a product item from purchase order lines, no Attachment will be appended for this product.
  3. Resulting report with the appended Product Attachments can’t be sent to the Printer print destination, because it requires documents in EMF format, and converting PDF to EMF format isn’t currently supported. All other Docentric print destinations are supported (Screen, File, Print archive, Email and also Printer with the Print as PDF option turned on).
From Docentric version 3.4.6, we support PDF to EMF conversion, thus the limitation of printing reports merged with PDF attachments to network printers for cloud environments is not a limitation anymore.
Learn how to extend the solution presented below to support the printing scenario >>>>

Setting up Product Attachments

In order to be able to test the solution, we first need to add PDF product specifications as Attachments to some products in D365FO. Open Modules > Product information management > Products and attach two PDF specifications to two different products.

We prepared two PDF documents and attached them to the products with item number A0001 and A0002 respectively.

 

The Coding Part

Custom code is required to implement our scenario. You can use the code below right away, build it and everything will just work!

The Code Explanation

We have to introduce a new class (we created DocMergePOReportWithItemAttachmentsPDF in our example) in the model where our reporting customizations are made.

This class contains a delegate method (DocReportRunDelegates_generateReportContent) which is executed whenever the report content is generated using any Docentric print destination, no matter if you are using a SSRS report design or a Docentric template. First some checks are performed, to make sure that the printing report is Purchase order, and that it is printed in the PDF output format.

Next, the PurchTable table record is fetched using the VendPurchOrderJour journal record. Having the purchase order record, we can now iterate through all the products that the purchase order lines point to. Next, another iteration takes place to collect all PDF attachments of the current product. At the end of the method, all the attachments are merged with the printed report, which is then sent to the selected print destination.

Final result

The image below shows what we get if we select Screen print destination.

Once we close the viewer form, we see the info messages, telling us what Attachments were appended to the printed purchase order.

There is more

Part of Docentric product is also customization of built-in Attachments, which enables us to mark each of Product Attachments with a Category or special Tags, so we can distinct product specifications from other Attachments, when selecting them in X++ from the DocuRef table.

Also, if you want more flexibility in terms of design (e.g. you want to place product specifications anywhere in the generated documents, for example in a table cell immediately after the purchase order line that contains that product), or if you want to support direct printing to network printers (with this solution only Print as PDF is supported for the Printer print destination), you will need to attach product specifications not as PDF documents but in MS Word format.

This way, you will be able to embed product specifications directly in the report data source, and afterwards to use them as Subdocuments from within Docentric Designer.

See how to embed T&Cs into PO data sources by customizing Docentric PO DSP class >>

See how to embed Product specifications into purchase orders using ER without coding >>

Summary

You can see that it doesn’t take much effort to append PDF Attachments to existing reports, by subscribing to Docentric delegate generateReportContent located in the DocReportRunDelegates class.

In our case we used the Purchase order report, but similar approach can be taken for any other report. You can also select Attachments for some other source tables – like purchase order lines, for example. In that case, you would only need to modify that part of the X++ code which selects the corresponding records from Attachments, i.e. the DocuRef table.

Learn how to print D365FO reports merged with PDF attachments to network printers >>>>

11 thoughts on “Append PDF Product Specifications to Printed Purchase Orders in D365FO

  1. Hi Team,

    How to attach multiple attachments in while sending project invoices using email concept.

    below code i tried, i couldn’t get the solution

    please help me how to achieve this,  customer need all formats in email.

    using System.IO;
    class SG_DocMergeMultipleAttachements
    {
    [SubscribesTo(classStr(DocReportRunDelegates), delegateStr(DocReportRunDelegates, generateReportContent))]
    public static void DocReportRunDelegates_generateReportContent(DocPrintReportSettings _printReportSettings,
    DocPrintedReport _printedReport, DocEventHandlerResult _result)
    {
    if (_printReportSettings.parmReportId() != ssrsReportStr(SG_PSAProjInvoice, Report))
    return;

    if (_printedReport.parmIsDocentricReport())
    {
    if (_printedReport.parmDocentricOutputFileFormat() != DocOutputFileFormat::PDF)
    return;
    }
    else
    {
    if (_printedReport.parmSrsOutputFileFormat() != SRSReportFileFormat::PDF)
    return;
    }

    //=================================================================================================

    ProjInvoiceJour projInvoiceJour;
    DocuRef docuRef;
    DocuType docuType;
    List attachmentsList = new List(Types::AnyType);
    MemoryStream reportMs = _printedReport.getReportContentMemoryStream();

    projInvoiceJour = ProjInvoiceJour::findRecId(_printReportSettings.parmArchiveContract().parmJournalRecId());

    // Iterate through the products related to the purchase order lines.
    // This way we will include each product only once, if some of them are repeating on multiple PO lines.

    docuRef = docuRef::findRecId(68719489390);

    DocuValue docuValue = docuRef.docuValue();

    try
    {
    using (Stream docuRefStream = DocumentManagement::getAttachmentStream(docuRef))
    {
    using (MemoryStream attachmentMs = new MemoryStream())
    {
    docuRefStream.CopyTo(attachmentMs);
    attachmentsList.addEnd(attachmentMs.ToArray());
    }
    }
    }
    catch (Exception::CLRError)
    {
    DocGlobalHelper::handleClrException(funcName(),
    strFmt(“Error while fetching Attachment (%1)”, docuRef.Name));
    }
    catch
    {
    DocGlobalHelper::handleException(funcName(),
    strFmt(“Error while fetching Attachment (%1)”, docuRef.Name));
    }

    if (!attachmentsList.empty())
    {
    attachmentsList.addStart(reportMs.ToArray());

    using (MemoryStream mergedPDFStream = DocDocumentHelper::documents2Zip(attachmentsList))
    {

    _printedReport.setReportContentContainer(DocGlobalHelper::convertMemoryStreamToContainer(mergedPDFStream));
    }
    }
    }

    }

    1. Hi Sreedhar,

      Could you please contact us at support[at]docentric.com with this issue?
      Also, in your email please explain in more detail what went wrong :).

      Thanks,
      Ana

    1. I’m sorry to tell you, but this code is not possible to use with AX 2012. This is because in AX 2012 Docentric works as a standalone service with exposed methods for generating and printing documents only, while methods for merging documents are not exposed. On the other hand, Docentric is embedded in D365FO as pure C# library and all APIs from this library can be used, including those for merging PDF documents.

      You could try to embed yourself the PDFsharp library into AX 2012. PDFsharp is open source C# library and can be used for merging PDF documents.

    1. You could try to embed yourself the PDFsharp library into AX 2012. PDFsharp is open source C# library and can be used for merging PDF documents.

      Please see the above comment for the detailed explanation.

  2. Hi,

    Thank you for this blog. This is very helpful.

    I have attached the pdf file to the purchase order, however, I am unable to view the attached file in the ‘preview’ fast tab. How do I make the pdf file viewable in the preview fast tab?

    Please help.

    Best regards,

    -Kabir

    1. Hi Kabir,

      You should be able to view the attached PDF in the preview fast tab. Please contact our support[at]docentric.com with more detailed explanation of what you did and we will see how we can help.

  3. This is a great articel. I just tested the merge and it is working great. Is there any chance to make it possible to merge also for printouts which are send to the printer?

    Unfortunately the DRA is not supporting the printing of PDFs when it runs as a service.

    1. Hi Thomas,

      In order to send merged PDFs to the printer you would first need to make a PDF to EMF conversion. Try searching for tools which support this conversion.

    2. Hi Thomas,

      We are discussing internally to support converting PDF to EMF in one of the future releases – in other words, you would be able to print PDF documents to network printers via DRA without using the ‘Print as PDF’ option turned on. This way it would become possible to use DRA running as a service.

      Unfortunately, we cannot set the exact date (yet). Please stay tuned by subscribing to our newsletter or by following us on LinkedIn. Thanks for reaching out!

      Kind regards,
      Ana

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Docentric respects your privacy. Learn how your comment data is processed >>

Docentric respects your privacy. Learn how your comment data is processed >>