Technical Notes, Zetadocs

HOWTO: Extend Zetadocs to add additional attachments to the Reminder report using customizations

ZTN4397

ID: ZTN4397

This Zetadocs technical note applies to:

  • Version 7.0 of Zetadocs for NAV and later
  • Zetadocs for NAV Delivery Plus

Summary

This article demonstrates how you can use the Zetadocs for NAV Delivery Plus WriteAdditionalEmbCommsToFile function to fetch additional related documents from SharePoint Server or the Zetadocs Archive which are then combined with the printed NAV report into a single PDF. This will then be sent to the NAV recipient.

Note: The interface of this function has changed for version 7.0 of Zetadocs for NAV.

Out of the box you can use Zetadocs templates to attach common documents like Conditions of sale and purchase, however in order to attach documents related to a specific NAV record, you’ll need to implement business logic in Codeunit 9009962: Zetadocs-Send Customize. This is useful where there are supporting documents like Work specification drawings or RFPs that need to be sent with to the Quote, Order or Invoice.

The code in this article shows how to retrieve a previously archived document in Zetadocs Archive based on some metadata, in this case the unique ID for the Posted Sales Invoice. This metadata is created by Zetadocs, but the logic can be extended to incorporate your document structures within NAV or outside of NAV as long as the documents to be attached are already in PDF format and accessible to the Zetadocs client.

Zetadocs Delivery Plus is a chargeable add-on to Zetadocs Delivery Essentials.

More information

The steps below have been written for an environment which has Dynamics NAV 2015 installed and configured with Zetadocs. Similar steps may apply to other versions of Dynamics NAV.

Prerequisite - Support for SharePoint Online (O365)

Support for SharePoint Online (O365) has been added in the following hotfix ZTN4423. If you intend to use SharePoint Online please install the hotfix detailed in the technote above and then continue following the steps in this technote.

Create a Zetadocs Template

  1. Create the Zetadocs Template from the Zetadocs Client. If you require further information, please consult the Zetadocs for NAV Essentials Guide or the Zetadocs Help.
  2. Share the Zetadocs Template if it is not shared already.

Typically: \\\Zetadocs templates

  1. Create the template in NAV:
    1. Open the Windows Client and in the Navigation Pane select Departments > Administration > Application Setup > Zetadocs Setup > Zetadocs Template List.
    2. Create a new entry, fill the form and click OK. In this example:

 

Create a new Zetadocs Document Set

  1. Open the Windows Client and in the Navigation Pane select Departments > Administration > Application Setup > Zetadocs Setup > Advanced > Zetadocs Document Sets
  2. Create a new Zetadocs Document Set, fill the form and click OK. In the example:

Create a Zetadocs System Rule

  1. Open the Windows Client and in the Navigation Pane select Departments > Administration > Application Setup > Zetadocs Setup > Advanced > Zetadocs System Rules
  2. Create a new Zetadocs System Rule, fill the form and click OK. In the example:

Where the Document Set No and the Template ID are the records created in previous steps.

Modify the Reminder report including Zetadocs code

  1. Open the Object Designer in the Development Environment.
  2. Export the Reminder report in text and create a backup of it.
  3. Run the Zetadocs Interface Modification Tool selecting the Reminder report.
  4. Import the modified Reminder report in NAV and compile it.
  5. Apply the Zetadocs layout modifications in the report.
  6. Test the report. Run the report from the Development Environment to verify that the output is generated successfully.

If you require further information please follow the advice in the NAV Objects and Interfaces section of the Zetadocs for NAV Essentials Installation Guide.

Add a new entry to the Zetadocs Report Settings

  1. Open the Windows Client and in the Navigation Pane select Departments > Administration > Application Setup > Zetadocs Setup > Advanced > Zetadocs Report Settings
  2. Create a new entry, fill the form based on your settings and click OK. In the example:

Extend Send Customize Codeunit: WriteAdditionalEmbCommsToFile

Codeunit 9009962: Zetadocs-Send Customize contains two examples: 1) how to add the external document number as an additional dynamic field when sending an invoice with Zetadocs; 2) how to add additional file attachments to the emails sent by Zetadocs for a Sales Header record.

  1. If you are using ZDNAV 8.0 or earlier, download the updated Zetadocs-Send Customize and Zetadocs-Archive codeunits from and follow the installation instructions.
  2. From the Object Designer, open Codeunit 9009962: Zetadocs-Send Customize
  3. Scroll to the WriteAdditionalEmbCommsToFile trigger.
  4. Uncomment the block comment in the function.

Note: uncommenting the code enables an example of how to add additional file attachments to the emails sent by Zetadocs for a Sales Header record. If you do not intend to use it, please comment the case statement related to the table “36: // Sales Header”.

  1. Create a new case statement and paste the following code:

    297: // Issued Reminder Header

    BEGIN

      //Get Zetadocs General Settings

      IF NOT GeneralSettings.FIND('-') THEN

      BEGIN

        EXIT;

      END;

      //Verify that achiving is enabled

      IF GeneralSettings.Archiving = GeneralSettings.Archiving::Off THEN

      BEGIN

        EXIT;

      END;

      //Create the codeunit

      IF NOT ZdArchive.Create() THEN

      BEGIN

        EXIT;

      END;

      //Initialize the codeunit based on your archiving option

      CASE GeneralSettings.Archiving OF

        GeneralSettings.Archiving::SharePoint:

          BEGIN

            ZdArchive.Initialize('sharepoint: ' + GeneralSettings."Datastore Location");

          END;

        GeneralSettings.Archiving::Zetadocs:

          BEGIN

            ZdArchive.Initialize('zetadocs: ' + GeneralSettings."Archive Service Location");

          END;

        ELSE

        BEGIN

          EXIT;

        END;

      END;

      //Legacy code for Zetadocs Archive ID

      tmpGUID := ZdSendIntegration.GetZetadocsArchiveID(Record, ZdSendSettings."Report ID");

      // Get the other record links

            ZdInitData.INIT;

            ZdInitData."No." := 1;

            ZdInitData."Record ID" := Record;

            IF NOT ZdInitData.INSERT THEN

            BEGIN

              ZdCommon.Log(ZdCommon.LogLevelError, 'C9041215.SetRecordID() Error constructing initialization data.');

              EXIT;

            END;

            IF NOT ZdInterface.GetRecordInitData(ZdInitData, ZdRecordLinks) THEN

            BEGIN

              ZdCommon.Log(ZdCommon.LogLevelError, 'C9041215.SetRecordID() Error constructing initialization data.');

              EXIT;

            END;

            IF NOT ZdInitData."Archiving Enabled" THEN

            BEGIN

              ZdCommon.Log(ZdCommon.LogLevelWarning, 'C9041215.SetRecordID() Archiving not enabled, not sending initialize command');

              EXIT;

            END;

            // These are record links for the records related to the current one

            IF ZdRecordLinks.FINDFIRST THEN BEGIN

              REPEAT

                MetadataToMatch.INIT;

                MetadataToMatch."Upload ID" := CREATEGUID;

                MetadataToMatch.Name := 'ZetadocsRecordLink';

                MetadataToMatch.Type := MetadataToMatch.Type::TEXT;

                MetadataToMatch.Value :=ZdRecordLinks."Record Link";

                MetadataToMatch.INSERT;

              UNTIL ZdRecordLinks.NEXT = 0;

            END;

            // This is record link for the record that is being sent

      IF ISNULLGUID(tmpGUID) THEN

      BEGIN

                MetadataToMatch.INIT;

                MetadataToMatch."Upload ID" := CREATEGUID;

                MetadataToMatch.Name := 'ZetadocsRecordLink';

                MetadataToMatch.Type := MetadataToMatch.Type::TEXT;

                MetadataToMatch.Value := ZdConnector.GetRecordLink(Record);

                MetadataToMatch.INSERT;

      END ELSE

      BEGIN

        MetadataToMatch.INIT;

        MetadataToMatch."Upload ID" := CREATEGUID;

        MetadataToMatch.Name := 'ZetadocsArchiveID';

        MetadataToMatch.Type := MetadataToMatch.Type::TEXT;

        MetadataToMatch.Value := ZdUtilities.TrimGuidBrackets(FORMAT(tmpGUID));

        MetadataToMatch.INSERT;

      END;

     

      //Apply filters to get the Issued Reminder Lines from the Issued Reminder Header

      IssuedReminderLine.SETFILTER(IssuedReminderLine."Reminder No.", FORMAT(RecRef.FIELD(1)));

      IssuedReminderLine.SETFILTER(IssuedReminderLine."Document Type", 'Invoice');

      IssuedReminderLine.SETFILTER(IssuedReminderLine.Type, 'Customer Ledger Entry');

      IF IssuedReminderLine.FIND('-') THEN BEGIN

        REPEAT

          //Apply filters to get the Customer Ledger Entries from the related Issued Reminder Lines

          CustomerLedgerEntry.SETFILTER(CustomerLedgerEntry."Entry No.", FORMAT(IssuedReminderLine."Entry No."));

          CustomerLedgerEntry.SETFILTER(CustomerLedgerEntry."Source Code", 'SALES');

          IF CustomerLedgerEntry.FIND('-') THEN BEGIN

            REPEAT

              //Apply filters to get the Sales Invoice Header from the related Customer Ledger Entry

              SalesInvoiceHeader.SETFILTER(SalesInvoiceHeader."No.", FORMAT(CustomerLedgerEntry."Document No."));

              IF SalesInvoiceHeader.FIND('-') THEN BEGIN

                REPEAT

                  //Get the Record Reference to obtain the RECORDID

                  TmpRecRef.GETTABLE(SalesInvoiceHeader);

                  //Create the metadata to match record based on the RECORDID

     tmpGUID := ZdSendIntegration.GetZetadocsArchiveID(TmpRecRef.RECORDID, ZdSendSettings."Report ID");

     IF ISNULLGUID(tmpGUID) THEN

     BEGIN

       MetadataToMatch.INIT;

       MetadataToMatch."Upload ID" := CREATEGUID;

       MetadataToMatch.Name := 'ZetadocsRecordLink';

       MetadataToMatch.Type := MetadataToMatch.Type::TEXT;

       MetadataToMatch.Value := ZdConnector.GetRecordLink(TmpRecRef.RECORDID);

       MetadataToMatch.INSERT;

     END ELSE

     BEGIN       

       MetadataToMatch.INIT;

                    MetadataToMatch."Upload ID" := CREATEGUID;

                    MetadataToMatch.Name := 'ZetadocsArchiveID';

                    MetadataToMatch.Type := MetadataToMatch.Type::TEXT;

         MetadataToMatch.Value := ZdConnector.GetRecordLink(TmpRecRef.RECORDID);

                    MetadataToMatch.INSERT;

                UNTIL SalesInvoiceHeader.NEXT = 0;

                END;

            UNTIL CustomerLedgerEntry.NEXT = 0;

          END;

        UNTIL IssuedReminderLine.NEXT = 0;

      END;

     

      MetadataFieldsToReturn.INIT;

      MetadataFieldsToReturn.Name := 'ZetadocsArchiveID';

      MetadataFieldsToReturn.INSERT;

     

      //Do not search if there is nothing to search

      IF MetadataToMatch.FIND('-') THEN

      BEGIN

        IF (ZdArchive.Search('', MetadataToMatch, MetadataFieldsToReturn, 0, RelatedDocuments, DocumentMetadata) = 0) THEN

        BEGIN

          IF RelatedDocuments.FIND('-') THEN

          BEGIN

            REPEAT

              //Check if the filename contains the strings: 'SALES-INVOICE' and '.PDF' (case insensitive),

              //to attach the document to the reminder.

              //Skip the attachment if any of the strings is not found.

              //Extend filter to meet your requirements.

              IF (StrPos(UPPERCASE(RelatedDocuments.Name),UPPERCASE('Sales-Invoice')) <> 0) AND

                 (StrPos(UPPERCASE(RelatedDocuments.Name),UPPERCASE('.pdf')) <> 0)

              THEN

              BEGIN

                file.AddCommand(STRSUBSTNO('%%[FileAttachment: %1]', RelatedDocuments.Url));

              END;

            UNTIL RelatedDocuments.NEXT = 0;

          END;

        END;

      END;

    END;                      

  1. Create the following local variables. View>C/AL Local:

Name: IssuedReminderLine

DataType: Record

Subtype: Issued Reminder Line  

---------

Name: IssuedReminderHeader

DataType: Record

Subtype: Issued Reminder Header          

---------

Name: CustomerLedgerEntry

DataType: Record

Subtype: Cust. Ledger Entry

---------

Name: SalesInvoiceHeader

DataType: Record

Subtype: Sales Invoice Header

---------

Name: TmpRecRef

DataType: RecordRef

  1. Create the following Text Constant. View>C/AL Local, then open the Text Constants tab:

Name: strSalesInv

ConstValue: Sales-Invoice

Please note that the code filters the documents by FileName. All the documents that do not contain the “Sales-Invoice” and “.pdf” strings on the name file will be skipped. This is to prevent sending all the documents (or unwanted documents) as attachments in the reminder. You can easily extend or modify this filter to meet your requirements.

Note: If you are using a non-English system please enter the translated value here.

  1. Save and Compile the Codeunit.

Extend Send Customize Codeunit: OverrideSendResults

Codeunit 9009962: Zetadocs-Send Customize (OverrideSendResults trigger) contains an example of how to change the template used depending on the payment method for a sales invoice.

  1. This example does not include the creation of additional templates, please follow the steps of how Create a Zetadocs Template detailed at the beginning of this technote if you require further information.
  2. From the Object Designer, open Codeunit 9009962: Zetadocs-Send Customize
  3. Scroll to the OverrideSendResults trigger.
  4. Uncomment the block comment in the function.

Note: uncommenting the code enables an example of how to add additional file attachments to the emails sent by Zetadocs for a Sales Invoice Header record. If you do not intend to use it, please comment the case statement related to the table “112: // Sales invoice Header”.

  1. Create a new case statement and paste the following code:

297: // Issued Reminder Header

    BEGIN

      fRef := RecRef.FIELD(28); // Field 28 = Reminder Level

      ReminderLevel := fRef.VALUE;

      IF ReminderLevel > 1 THEN BEGIN

        //Select your custom template, i.e. ZT00021

        ZdSendResult."Zd Template ID" := 'ZT00021';

      END;

      ZdSendResult."Output File Name" := 'Reminder ' + FORMAT(RecRef.FIELD(1));

      ZdSendResult.MODIFY;

    END;

  1. Create the following local variables. View>C/AL Local:

Name: ReminderLevel

DataType: Integer

Test your system

You are now ready to test your work.

  1. Ensure you have a related document against the Posted Sales Invoice which you are going to print. Note in the example above the code will only fetch documents linked to Posted Sales Invoice which are related to the Issued Reminder.
  2. Print the Reminder report to Zetadocs and preview it in the Zetadocs Client.
  3. You should now see additional document in the report preview.

References

Use the Zetadocs for NAV Installation guide for further details on the functions used in this article.

Last updated: 1st April 2016 (JV/NT/GC/JC/NT) 

Keywords: Zetadocs Customize