Creating Document Layouts for Customers and Vendors

In NAV 2107, one can email documents to multiple customers or vendors, provided that each customer or vendor has a Document Layout record for the report. To add a record, go to the Customer or Vendor Card, then select Navigate in the Action ribbon, then Document Layouts.

Probably the most common use for this is to send statements to customers. If there is not Document Layout record for the customer for the report, or the Send to Email field is not populated, then the customer will be skipped for emailing.

If you have many customers or vendors, it is tedious to add a document layout record to them all, for every document to be emailed to them. Also, editing them to change the email layout code will be time-consuming.

One solution is to create a processing only report on the Customer and Vendor tables, which would add or update a Document Layout record for each customer and vendor. The table is 9657 Custom Report Selections, even though it is captioned Document Layout. You would need to repeat this for the Sales Invoice and any other report you want to batch email. A downside is that the processing only report would need to be run when new customers and vendors are editing, or emails are changed. That could be overcome by scheduled the report as a job. An advantage of this solution is that no modification of standard objects is required.

Rather than programming values for the new Document Layout records, I created added a record to table 9657 by running the table, and inserting a new line with Source No. DEFAULT (enter this before Source Type so don’t get validation error), Source Type 18, Usage C.Statement, Sequence 1, Report ID 1316. Use for Email Attachment is ticked, and I chose to tick Use for Email Body.

Since I set the Source No. does not match a Customer No., the record will not be used when the report is run. To make it more user-friendly, I created a custom page on the Custom Report Selection table with the view set to Source No. CONST DEFAULT. In the OnNewRecord trigger, the Sequence is set to 1 and the Source No. is set to DEFAULT. Both fields are not editable because those values should not be changed. I added this list page to the Administration, Application Setup, General menu. Now an administrator can add new default records for other documents.

I created processing only report 50000 to create Document Layout records for Customers and Vendors for all DEFAULT Custom Report Selection records. Download processing only report to add Document Layout records

An alternative solution is to create and edit the Document Layout records within the processing codeunit 8800. It has the advantage of adding only records that will be used, and always keeping the Document Layout records current but it does require a developer license.

I am still using the DEFAULT record that I created for the report alternative. I edited codeunit 8800, ProcessReportPerObject. After the line that starts with EVALUATE(IteratorJoinFieldValue I inserted:

IF ReportDataRecordRef.FINDSET THEN BEGIN

CustomReportSelectionDefault.SETRANGE(“Report ID”,ReportID);
CustomReportSelectionDefault.SETRANGE(“Source No.”,’DEFAULT’);
IF CustomReportSelectionDefault.FINDFIRST THEN

FoundDefaultRecord := TRUE;

REPEAT

JoinValue := FORMAT(ReportDataIteratorFieldRef.VALUE,20);
CustomReportSelection.SETRANGE(“Report ID”,ReportID);
CustomReportSelection.SETRANGE(“Source No.”,JoinValue);
CustomReportSelection.SETRANGE(Sequence,1);
IF NOT CustomReportSelection.FINDFIRST AND FoundDefaultRecord THEN BEGIN

CustomReportSelection.INIT;
CustomReportSelection.”Source Type”:= ReportDataRecordRef.NUMBER;
CustomReportSelection.”Source No.” := JoinValue;
CustomReportSelection.”Report ID” := ReportID;
CustomReportSelection.”Send To Email” := ReportDataRecordRef.FIELD(102).VALUE;
CustomReportSelection.Sequence := 1;
CustomReportSelection.Usage := CustomReportSelectionDefault.Usage;
CustomReportSelection.INSERT;

END;

IF FoundDefaultRecord THEN BEGIN

CustomReportSelection.”Custom Report Layout Code” := CustomReportSelectionDefault.”Custom Report Layout Code”;
CustomReportSelection.”Use for Email Attachment” := CustomReportSelectionDefault.”Use for Email Attachment”;
CustomReportSelection.”Use for Email Body” := CustomReportSelectionDefault.”Use for Email Body”;
CustomReportSelection.”Email Body Layout Code” := CustomReportSelectionDefault.”Email Body Layout Code”;
CustomReportSelection.MODIFY;
COMMIT;

END;

UNTIL ReportDataRecordRef.NEXT = 0;

CustomReportSelection.SETRANGE(“Report ID”);
CustomReportSelection.SETRANGE(“Source No.”);
CustomReportSelection.SETRANGE(Sequence);

END;

I added two local variables:
CustomReportSelectionDefault DataType Record Subtype 9657
FoundDefaultRecord DataType Boolean

My code will add a new record if the customer does not have one for the report, and updates existing records. The Send to Email is the customer’s E-mail, but with a little more programming, we could set it to the primary contact’s E-Mail, if it exists.

The code also works for vendors, as is. This much better than having the Accounts staff do this one record at a time.