Extend the standard reports in Dynamics 365 finance and operations

In this article, I will show the procedure for the SSRS Reports development and customization in Dynamics 365 finance and operations (Version 8.1 and above).The scenario is you would like to extend...

In this article, I will show the procedure for the SSRS Reports development and customization in Dynamics 365 finance and operations (Version 8.1 and above).

The scenario is you would like to extend the customer account statement report with 2 main tasks

Same with AX 2012 version, there is no change on how you developer a new SSRS report with query based and report data provider. But if you want to extend or modify the standard one you need to understand how to use extensions in general, Event handlers and Chain of Command.

The steps

1. Adding a new field

The main temp table is CustAccountStatementExtTmp, right click and create an extension; I’m going to add a new string field MaxTxT

2. Duplicate the report

Duplicate the CustAccountStatementExt report in the Application explorer > AOT > Reports > CustAccountStatementExt as shown in below screen shot:

Rename the report and provide any appropriate name: MaxCustAccountStatementExt

3. Modify the report design, right click on report dataset and choose restore to refresh the new field

Open report designer and add that field into a table

4. Create a new Extension class that extends the standard report controller class.

class MaxCustAccountStatementExtController_Ext extends CustAccountStatementExtController{}

//Add construct
public static MaxCustAccountStatementExtController_Ext construct()
{
    return new MaxCustAccountStatementExtController_Ext();
}

Copy the main method from the standard controller class and add references to the new Controller class

public static void main(Args _args)
{
    SrsPrintMgmtFormLetterController controller = new MaxCustAccountStatementExtController_Ext();
    controller.parmReportName(PrintMgmtDocType::construct(PrintMgmtDocumentType::CustAccountStatement).getDefaultReportFormat());
    controller.parmArgs(_args);
    MaxCustAccountStatementExtController_Ext::startControllerOperation(controller, _args);
}
 
protected static void startControllerOperation(SrsPrintMgmtFormLetterController _controller, Args _args)
{
    _controller.startOperation();
}

Optional method, determine which default design for report

protected void outputReport()
{
    SRSCatalogItemName  reportDesign;
    reportDesign = ssrsReportStr(MaxCustAccountStatementExt,Report);
    this.parmReportName(reportDesign);
    this.parmReportContract().parmReportName(reportDesign);
    formletterReport.parmReportRun().settingDetail().parmReportFormatName(reportDesign);
    super();
}

5. Create new report handler class

class MaxCustAccountStatementHandler {}

We have two different ways to Populate the data in the Report handler class:

  • Add a temp table Inserting event, row-by-row calculations.
[DataEventHandlerAttribute(tableStr(CustAccountStatementExtTmp), DataEventType::Inserting)]
public static void CustAccountStatementExtTmpInsertEvent(Common c, DataEventArgs e)
{
    CustAccountStatementExtTmp    tempTable = c;
    tempTable.MaxTxT = "Hello world";
}
  • Add a data processing post-handler, inserting operations that use a single pass over the result set of the standard solution.
[PostHandlerFor(classStr(CustAccountStatementExtDP), methodstr(CustAccountStatementExtDP, processReport))]
public static void TmpTablePostHandler(XppPrePostArgs arguments)
{
    CustAccountStatementExtDP dpInstance = arguments.getThis() as CustAccountStatementExtDP;
    CustAccountStatementExtTmp tmpTable = dpInstance.getCustAccountStatementExtTmp();
    ttsbegin;
    while select forUpdate tmpTable
    {
        tmpTable.MaxTxT = "Hello world";
        tmpTable.update();
    }
    ttscommit;
}

6. Add a delegate handler method to start to use your custom report.

In this example, extend the getDefaultReportFormatDelegate method in the PrintMgtDocTypeHandlerExt class by using the following code.

class MaxPrintMgtDocTypeHandlersExt
{
    [SubscribesTo(classstr(PrintMgmtDocType), delegatestr(PrintMgmtDocType, getDefaultReportFormatDelegate))]
    public static void getDefaultReportFormatDelegate(PrintMgmtDocumentType _docType, EventHandlerResult _result)
    {
        switch (_docType)
        {
            case PrintMgmtDocumentType::CustAccountStatement:
                _result.result(ssrsReportStr(MaxCustAccountStatementExt, Report));
                break;
        }
    }
}

7. Create extension for the existing menu items

Navigating to the CustAccountStatementExt output menu item and create extension.

Also make sure to set the value of the Object property to MaxCustAccountStatementExtController_Ext to redirect user navigation to the extended solution.

That’s all, this is what you should have

8. Update the Print management settings to use the custom business document

Go to Account payable > Inquiries and reports > Setup > Forms > Form setup Click Print Management, find the document configuration settings, and then select the custom design

9. Run report and test the result