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
- 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: \\
- 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