Use D365FO Customer Prepayment Invoice With Docentric

With D365FO ver. 10.0.41 Microsoft introduced support for Customer prepayment invoice as a preview feature. It is implemented as an ER report, meaning that when a report is triggered from the Prepayment invoice form, it invokes an ER format configuration, which in turn invokes the matching ER model mapping and model configurations. If you prefer using Docentric template designer for this type of invoice, there are some things that need to be additionally implemented, so that Docentric pipeline can be triggered.

Don’t worry, we did it all for you, and you can find all the necessary artefacts if you follow the link at the bottom of this article. In this article we will describe all the steps that were required to support this report through Docentric, as it can be useful for some similar situations in the future.

Set Up Accounts Receivable for Customer Prepayment Invoices

First step is to set up D365FO for Customer prepayment invoices, and to make sure that you can generate and print one such invoice through standard. We were following these resources:

Bear in mind that the above instructions were written for D365FO ver. 10.0.41, when the feature was first implemented. Namely, one specific step, important for triggering the ER report, is different on ver. 10.0.43, where we worked on implementing the Docentric replacement for this report. In that step, you need to specify the ER configuration to be used for printing, and the path to that setup is:

  • On ver. 10.0.41: Accounts Receivable > Setup > Accounts receivable parameters, Electronic documents tab > Prepayment invoice lookup
  • On ver. 10.0.43: Accounts Receivable > Setup > Form setup, Invoice tab > Prepayment invoice lookup

When you successfully set up your D365FO and create a new Prepayment invoice, you can trigger the report provided by standard by clicking the Print button on the Prepayment invoice form:

Analyze the Standard ER Report

When the Print button on the above form is clicked, it invokes the CustPrepaymentInvoice::generateGERReport() method, and passes the current Customer prepayment invoice record as a parameter.

This method does the following:

  • It first finds the related CustInvoiceJour record.
  • Then it looks for the ER format configuration that has been set up for this invoice type (remember, its location changed from ver. 10.0.41 to 10.0.43, see above). If you followed the instructions from the resources we listed above, it will be the Prepayment invoice template format configuration.
  • Finally, it invokes the execution of that ER configuration for the given CustInvoiceJour record.

Prepayment invoice template format configuration depends on the Customer prepayment invoice model and Customer prepayment model mapping configurations:

This is how the Excel format looks. It’s nothing complicated, just a few basic Legal entity-, Customer- and Invoice-related fields in the document header, with few fields in the lines.

And below is the model mapping, which you need to understand if you want to produce the report data source with the same kind of information through SSRS + Docentric pipeline:

Few important points to notice:

  • In the data model tree on the right side, there are 2 nodes:
    • Company: this is the current legal entity information, which Docentric anyway inserts into the General section of the data source, so you don’t need to worry about it.
    • Prepayment Lines: as the name suggests, it carries the information about the Prepayment invoice lines. But why is then the InvoiceAccount node inside the lines, as well as fields like InvoiceDate and InvoiceId, when they naturally belong to the header? As it turns out, you can have only one line per Prepayment invoice, so even though it would have been much cleaner to have a separate node for the header information, this structure won’t generate multiple header records, so it is acceptable.
  • Prepayment Lines node from the data model is bound to a calculated field $CustInvoiceJourJoined.
    • In the data sources tree on the left side you can see that the $CustInvoiceJourJoined calculated field combines multiple tables: invoice-related tables (CustInvoiceJour and CustInvoiceTrans) and customer-related tables (everything else).
    • $CustInvoiceJour is the one record provided by the caller X++ code.
    • $CustInvoiceTrans is the record list (but in reality: one record) linked to CustInvoiceJour through this relation: FILTER(Tables.CustInvoiceTrans, Tables.CustInvoiceTrans.ParentRecId = @.RecId)
    • $CustTable comes from the InvoiceAccount field on the $CustInvoiceJour and all the remaining tables are there to bring some information about the customer, e.g. name, address, email, phone, etc.

Nothing that you cannot achieve with one nice SQL statement in X++, right? So, let’s dig into the actual work of creating a whole new SSRS-based report, that you can easily combine with Docentric templates.

Precondition for Docentric Pipeline: Make the SSRS Happy

Docentric relies on SSRS framework, either as pure SSRS or as Docentric-over-CBD-over-SSRS. Let’s start first with the SSRS part. We have previously written a nice article that provides step-by-step instructions on how to create a new SSRS report if you plan to combine it with Docentric. In essence, to “make the SSRS happy”, you will need to implement these artefacts:

  • Menu item(s) for invoking the report.
  • Security artefacts controlling the access to the menu item(s).
  • Data contract class to exchange the information between the UI and report pipeline.
  • Report controller class to, well, control the report behavior in various scenarios.
  • Data provider (DP) class, to prepare the report data source.
    • For a stand-alone SSRS report, you need to implement complete logic for populating the data source here, in which case you also need to implement an RDP table to temporarily store the report data source.
    • In case you plan to use this report in combination with Docentric, then it is enough to implement a dummy DP class and implement the data provider logic in the Docentric data source provider (DSP) class. We have used this approach.
  • SSRS report, to provide the design for the generated document.
    • For a stand-alone SSRS report, you need to implement a complete design here.
    • In case you combine the report with Docentric, it is enough to implement a dummy SSRS report with a single Autodesign format. This is the approach we have used for this report.

These artefacts are pretty much interconnected, and it might be a challenge to follow the breadcrumbs from one to another. That’s why we listed them here in the order in which we implemented them to ensure that all dependences are correctly resolved during development, and we added few useful hints.

1. Create a data contract class

Think about the information you want to exchange between the UI and report engine – in this case we only need the RecId of the caller Customer prepayment invoice. We named this class DocCustPrepaymentInvoiceContract and below is its content.

Some important things to notice about this implementation:

  • Decorate the class with DataContractAttribute.
  • Add a class variable for the underlying record Id and implement the related parm method. In our case the class variable is custPrepaymentInvoiceRecId.
  • We don’t want this parameter to appear on the print dialog, so we used SysOperationControlVisibilityAttribute(false), but it turned out that it wasn’t enough. The SSRS format is a master in this whole chain of artefacts, so keep reading to see how the parameter visibility is controlled there.

2. Create a dummy data provider (DP) class

We named it DocCustPrepaymentInvoiceDP.

Pay attention to these details:

  • Decorate the class with SRSReportParameterAttribute that points to the data contract class created in the previous step, DocCustPrepaymentInvoiceContract.
  • Controller class should inherit from the SRSReportDataProviderBase class.
  • Add a class variable for RDP table. It is going to be a dummy temporary table that is not going to be used, but it is a formality required by the SSRS pattern. It can be any temp table that exists in D365FO, so we used the simplest, TmpRecId Follow to the end the pattern required by SSRS – implement a getter method for this dummy temp table.
  • Implement a mandatory processReport() method and leave it empty, since we won’t populate the temp table through the SSRS pipeline, but will create the report data source from scratch later in the Docentric DP class.

3. Create an SSRS report

We named it DocCustPrepaymentInvoice.

Configure the following:

  • Add one dataset, its name is irrelevant. In its Properties set Data Source Type = Report Data Provider, and in the Query window point to the DP class created in the previous step and select its dummy temp table. As a result, Query will be:
    SELECT * FROM DocCustPrepaymentInvoiceDP.TmpRecId.
     

     
  • Add one Auto design to the Designs node, and one Table for it. Set the table’s Data Set to the one created above.
     

     
  • Expand the Parameters node, select the CustPrepaymentInvoiceRecId (remember, it’s the parameter specified in the data contract class from the step 1 above), and set its Visibility property to Hidden. This will prevent the parameter from showing on the report dialog form.
     

     

4. Create the report controller class

We named it DocCustPrepaymentInvoiceController.

Notice the following:

  • The controller class should inherit from the SrsReportRunController class.
  • In its main method we connect it to the SSRS report & format combination created in the previous step by using the parmReportName() method.

Think about the behavior you want to support and implement it. We decided to go with the following:

  • We will add 2 menu item buttons to the Customer prepayment form, one for previewing the report and another for opening the Print dialog where user can configure the Print destination.
  • We will use the same menu item (see one of the steps below) for both menu item buttons. To distinguish between the user actions, we will use the Parameter property on these menu item buttons. One will be set to Preview and another to ShowPrintDialog.

To accomplish this, we implemented the prePromptModifyContract() method:

Things to notice about this method:

  • We populate the only contract parameter, custPrepaymentInvoiceRecId, from the RecId of the caller record.
  • We initialize a local isPreview variable based on the Parameter value of the caller menu item button (remember, it can be Preview or ShowPrintDialog). If it is Preview, we force the print destination (parmMediumType()) to screen, otherwise we open the Print dialog where user will have a chance to configure the print destination.

5. Create one or more menu items

We will later add these menu items to the Prepayment invoice form. Just one menu item is enough for the scenario described above (two menu item buttons, one for previewing and one for opening the Print dialog). We named this menu item DocCustPrepaymentInvoice.

This menu item should trigger the execution of the report controller class created above, so we set the following:

  • Object Type: Class
  • Object: DocCustPrepaymentInvoiceController

6. Handle the security

Decide what kind of security roles should be able to trigger this report and apply the relevant privilege. BTW, Print button provided by standard is a button type of AOT object, which doesn’t require any security 😊, so if users can open the Prepayment invoice form, they can also print the report.

7. Add the menu items to the form

Not really required to “make the SSRS happy”, but necessary to trigger the report, make an extension of the standard CustPrepaymentInvoice form and add the menu item created earlier to the form extension. Here you can see how we added two menu item buttons.

Notice how each menu item button has:

  • Menu Item Type: Output
  • Menu Item Name: DocCustPrepaymentInvoice (the one created above)
  • Parameters: Preview on the first button, ShowPrintDialog on the second.

8. Implement additional form logic

To mimic the logic applied to the standard Print button, which is enabled only after the Prepayment invoice is posted, we implemented the logic in a new extension class CustPrepaymentInvoiceForm_DR_Extension:

At this point, we were able to execute the new SSRS report by clicking any of the two newly added buttons. No report data source was generated (remember the dummy DP class) and a blank document was displayed (remember the dummy SSRS report).

SSRS is Happy, Let’s Add Docentric

We need a new Docentric data source provider (DSP) class and a new Docentric template. For that, we will perform the following steps:

  1. Implement the DSP
  2. Register the Format SSRS report, configure the DSP class for it and turn on the Generate DDSP when report runs flag.
  3. Trigger the SSRS report execution and get the DDSP file.
  4. In MS Word create a Customer prepayment invoice mockup.
  5. Load the DDSP file and design the Docentric template.
  6. Register the template in the report setup form.

1. Implement the DSP class

We implemented a new Docentric data source provider (DSP) class, where we decided to add the logic for generating the report data source from scratch. We named this class DocCustPrepaymentInvoiceDSP. As all other Docentric DSP classes, it inherits from the base DocDataSourceProviderSrsReporting class. Here is its beginning, with some class variables declared:

Before the actual data source generation is started, some convenient initialization can be done in the preRunGenerateDS() method. Here we obtained the data contract, because it holds the information about the caller Customer prepayment invoice record, and we fetched the linked records that hold the information to be presented on the invoice document:

Data source generation should be placed in the generateXmlDataSource() method. When we implement a DSP class for a fully-blown SSRS report, where data source is already generated in its pipeline, then this method usually has a call to super(), in order to preserve the SSRS-generated data source. But in this case, we are creating a data source from scratch, so we omitted the call to super().

We create one header record called Prepayment header, which has 2 sub-records, Invoice information and Customer information. We populate them with the relevant fields, based on what we saw in the ER model. Then we create a list of lines records, called Prepayment line (we explained earlier that there will be actually only one prepayment line, but it shouldn’t prevent us from creating a list with only one record.

In Docentric DSP classes we typically implement some custom placeholders, for information that users might want to use in combination with e.g. file names, email subject or body, etc. We implement these placeholders in the overrideReportRunSettings() method, which must be decorated in an appropriate way. Here you can see the beginning of this method and its decoration:

2. Register the SSRS report in the Docentric report setup form

Now when the DSP class is ready, we need to make sure that it is executed, so that we can generate the DDSP file. In the Docentric report setup form add a New entry with SSRS report name and design name pointing to DocCustPrepaymentInvoice and Report combination:

In the newly added setup, set the DSP class to point to the DocCustPrepaymentInvoiceDSP class:

Then click the Settings > Data source > Generation options menu button, and in the Data source generation options form turn on the Generate DDSP when report runs flag. Optionally, if this report should be printed in different languages, select those languages in the Preview languages field.

3. Trigger the SSRS report execution

At this point we still don’t have a template, but we will anyway trigger the report execution, with the goal to get the DDSP file. From the standard Prepayment invoice form, trigger the SSRS report execution by clicking for example the Docentric > Preview button. DDSP file will be generated and downloaded.

4. Create a Customer prepayment invoice mockup

In MS Word create a mockup (blueprint) of Customer prepayment invoice. The goal is to have a sample MS Word document that represents an example of a printed invoice. We can start with a blank document or modify some existing printout and adjust it to the requirements.

5. Design the Docentric template

Start by loading the DDSP file into the mockup. This is how the data source schema looks based on the generateXmlDataSource() implementation in the DSP class.

Work your way through the mockup and replace its static content with the dynamic content from the data source. This is how the final Docentric template looks:

6. Register the template

In the Docentric report setup form for this SSRS report, add a new Template entry and attach the newly created template (.docx file) to it.

In this phase it is recommended to upload the template file to the Azure Blob storage. Once we are satisfied with the result, we can decide to add the template to the AOT resources, so they will be deployed together with other related artefacts. Docentric delivers its SSRS replicas in this way.

We are finally ready to execute this report through Docentric. This is the result of clicking the Docentric > Preview button (notice the info bar showing the name of the SSRS report and the Template ID):

Can We Combine Docentric Templates with ER Data Source?

Short answer is yes. You might want to consider this combination if:

  • You are familiar with ER,
  • You like the idea of creating the data source through ER configurations instead of X++ code,
  • You prefer the experience of using the Docentric template designer over the ER Excel format,
  • You prefer using the Docentric improved print destinations over the ER destinations.

In this case, here is the ideal solution for you:

  • Maintain the report data source in the ER model- and model mapping configurations.
  • Desing the report format by using the Docentric template designer, and benefit from all document generation and distribution improvements that Docentric offers.

Can We Reuse the Existing ER Configurations?

General answer is it depends, and no in this case. To understand why, we should analyze the ER configurations.

Below on the left is the data model ER configuration provided by Microsoft. You can notice a SPACE character in the Prepayment Lines record list name. When such report data source reaches the Docentric engine, it throws an error due to a not allowed character in the XML node name. This is the only reason why this data model cannot be combined with Docentric. We created a new data model by deriving from the original one, and created the same structure, only with a PrepaymentLines name for the same record list. On the right is such data source upon importing it into the Docentric designer.

OK, we needed a new data model configuration due to a naming convention technicality, but what about the model mapping configuration? Below are the configured data sources in this model mapping. Entry point to this model is the caller CustInvoiceJour record, which is provided as a parameter when invoking the execution of the ER format configuration.

The information about the caller record and the ER format configuration is tightly bundled and Docentric cannot reach between the two of them to obtain the report context. Therefore, we need a new model mapping configuration that is based on the report data contract we created for the SSRS report, because we will be able to get the caller record from it.

The image above shows the derived model mapping configuration where we made the following modifications to the data sources:

  • We added a ReportDataContract object of DocCustPrepaymentInvoiceContract Its parmCustPrepaymentInvoiceRecId() method will return the RecId of the caller Customer prepayment invoice record.
  • We added a new calculated field $CustPrepaymentInvoiceTable. It filters the CustPrepaymentInvoiceTable record matching the RecId retrieved from parmCustPrepaymentInvoiceRecId. This is the formula we used:
     

     
  • We modified the expression for the $CustInvoiceJour calculated field. In the original configuration it was provided directly from the caller, but in our configuration we need to filter the CustInvoiceJour table to match the caller CustPrepaymentInvoiceTable This is the formula we used:
     

     
  • Our derived model mapping had bindings to the Prepayment Lines record list from the original model, but our derived model has a differently named record list, PrepaymentLines, so we needed to apply the same bindings to this new record list.

These are the two new ER configurations we prepared for the model and model mapping:

How To Combine the ER-based Data Source and Docentric Template?

When we design the Docentric template, we must first import a DDSP file, which has been generated either through SSRS or through ER. When a template is used during the report execution, its data source type (SSRS or ER) implicitly dictates if the data source should be generated through ER or through SSRS.

  • If the template data source is based on SSRS (and there is an SSRS report to be executed), it’s business as usual: SSRS pipeline is triggered, and once the SSRS data source is ready, Docentric will consume it.
  • If the template data source is based on ER, Docentric looks into the Docentric report setup > Settings > Data source > Configurable business documents form, where ER Data Model and ER Model mapping fields define which ER model mapping configuration to execute. Docentric triggers the execution of that model mapping and consumes the data source it generated.
     

     

This sounds like a Catch-22 situation, because:

  1. To trigger the execution of ER model mapping, we need to use a template based on an ER data source.
  2. To create such template, we need a DDSP file based on the ER data source.
  3. To generate a DDSP file based on the ER data source, we need to execute an ER model mapping.
  4. To execute an ER model mapping, we need a template based on an ER data source. Wait, isn’t it a step A above 😊?

To break this circular dependency, there is an alternative way to trigger the ER model mapping execution (step C above). In Docentric report setup > Settings > Data source > Data source generation options set Which DDSP to generate? field to Both SSRS and CBD DDSPs:

Now perform the following steps:

  • Run the report once to get 2 DDSP files, one based on the SSRS data source, and another based on the ER data source.
  • Load the ER-based DDSP file into the already existing SSRS-based template. All bindings will be wrong and marked with red color, because the data source structure is completely different, but re-binding won’t take more than few minutes for this particular report, as there are about 20 fields in the design to be fixed.
  • Add this ER-based template to the Docentric report setup. Mark it as a default, so that you can easily test by only previewing.
     

     
  • In the Prepayment invoice form click the Docentric > Preview button to get the document based on the ER data source and ER-based template:
     

     

Summary

In this article we documented how we enabled using the Customer prepayment invoice in combination with Docentric.

We needed to implement a new SSRS report that can be triggered from the Prepayment invoice form. We developed a new Docentric template for this report that produces the same result as the Microsoft-provided ER format. For users that prefer using ER, we adjusted the Microsoft-provided ER model and model mapping configurations, and created a second, ER-based Docentric template to be used with ER.

You can find all the artefacts as solution project and model on the link below.

Resources for Customer prepayment invoice

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