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
 - 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.
 
 - Share the Zetadocs Template if it is not shared already.
 
Typically: \\\Zetadocs templates
 - Create the template in NAV:
 
  - Open the Windows Client and in the Navigation Pane select Departments > Administration > Application Setup > Zetadocs Setup > Zetadocs Template List.
 
  - Create a new entry, fill the form and click OK. In this example:
 
 
  
 
Create a new Zetadocs Document Set
 - Open the Windows Client and in the Navigation Pane select Departments > Administration > Application Setup > Zetadocs Setup > Advanced > Zetadocs Document Sets
 
 - Create a new Zetadocs Document Set, fill the form and click OK. In the example:
 

Create a Zetadocs System Rule
 - Open the Windows Client and in the Navigation Pane select Departments > Administration > Application Setup > Zetadocs Setup > Advanced > Zetadocs System Rules
 
 - 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
 - Open the Object Designer in the Development Environment.
 
 - Export the Reminder report in text and create a backup of it.
 
 - Run the Zetadocs Interface Modification Tool selecting the Reminder report.
 
 - Import the modified Reminder report in NAV and compile it.
 
 - Apply the Zetadocs layout modifications in the report.
 
 - 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
 - Open the Windows Client and in the Navigation Pane select Departments > Administration > Application Setup > Zetadocs Setup > Advanced > Zetadocs Report Settings
 
 - 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.
 - 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.
 
 - From the Object Designer, open Codeunit 9009962: Zetadocs-Send Customize
 
 - Scroll to the WriteAdditionalEmbCommsToFile trigger.
 
 - 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”.
 - 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;                      
 - 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
 - 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.
 - 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.
 - 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.
 
 - From the Object Designer, open Codeunit 9009962: Zetadocs-Send Customize
 
 - Scroll to the OverrideSendResults trigger.
 
 - 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”.
 - 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;
 - Create the following local variables. View>C/AL Local:
 
Name: ReminderLevel
DataType: Integer
Test your system
You are now ready to test your work.
 - 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.
 
 - Print the Reminder report to Zetadocs and preview it in the Zetadocs Client.
 
 - 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