AX 2012 / D365FnO – RUNNING NEW CUSTOM SSRS REPORT FROM THE SELECTED RECORD OF GRID USING X++

D365fno-PostImage

In this blog, I will explain you how to run an SSRS DP based report from the selected record with YES and NO dialog for multiple design in a form in D365FnO and AX 2012 using X++.

In Microsoft Dynamics 365 for Finance and Operations (D365FnO) and Microsoft Dynamics AX 2012, reports are used to present and summarize data from various sources in a structured and organized manner. Reports can be generated from various modules such as sales, purchase, inventory, financials, and many more. These customized reports can help businesses in making informed decisions and analyzing data more effectively. we will create SSRS report in D365FnO using RDP, Controller, Contract and UIBuilder classes.

STEP 1: Create temp table for storing report data.

  • Set the Table Type property of table to TempDB.
  • Drag and drop fields which you want to show on the report, into your temporary table i.e. TmpDeliveryOrder. You can also create new fields by right-clicking the fields node -> new -> selecting data type. But, this is slow process as you have to set the properties for each field as well. After creating table and adding the fields, Build and Synchronize your project. See the temporary table in the below:

STEP 2: Add following listed classes in your project.

  • DeliveryOrderContract
  • DeliveryOrderController
  • DeliveryOrderDP

STEP 2: Add the following code in the classes.

DeliveryOrderContract:

[
    DataContractAttribute,
    SysOperationGroupAttribute("JOB CARD", "JOB CARD", "1")
]
public class DeliveryOrderContract
{
    SalesId     salesId;
    RefRecId    packingSlipRecId;

    [
        DataMemberAttribute('PackingSlip RecId'),
        SysOperationLabelAttribute(literalstr("PackingSlip RecId")),
        SysOperationHelpTextAttribute(literalstr("Enter PackingSlip RecId")),
        SysOperationDisplayOrderAttribute('1')
    ]
    public RefRecid parmPackingSlipRecId(RefRecid _packingSlipRecId = packingSlipRecId)
    {
        packingSlipRecId = _packingSlipRecId;
        return packingSlipRecId;
    }

    public SalesIdBase parmSalesId(SalesIdBase _salesId = salesID)
    {
        SalesID = _salesId;
        return SalesID;
    }
}

DeliveryOrderController:

class DeliveryOrderController extends SrsReportRunController
{
    DeliveryOrderContract   jobCardContract;
    SalesTable              salesTable;
    SalesLine               salesLine;
    InventQualityOrderId    qualityID;
    CustPackingSlipJour     custPackingSlipJour;
    #define.ReportName('DeliveryOrder.Report')
    #define.ReportName1('DeliveryOrder.Report1')


    protected SrsReportDataContract getReportContract()
    {
        SrsReportDataContract ret;
        ret = super();
        return ret;
    }

    protected void initializeParameters(boolean calledFromInitParmDefault)
    {
        super(calledFromInitParmDefault);
    }

    public CustPackingSlipJour parmCustPackingSlipJour(CustPackingSlipJour _custPackingSlipJour = custPackingSlipJour)
    {
        custPackingSlipJour = _custPackingSlipJour;
        return custPackingSlipJour;
    }

    SalesTable parmSalesTable(SalesTable _parmSalesTable = salesTable)
    {
        salesTable = _parmSalesTable;
        return salesTable;
    }

    protected void preRunModifyContract()
    {
        jobCardContract = this.parmReportContract().parmRdpContract();
        jobCardContract.parmPackingSlipRecId(this.parmCustPackingSlipJour().RecId);
        super();
    }

    public static void main(Args _args)
    {
        CustPackingSlipJour     packingSlipJour;
        InventQualityOrderId    qualityOrderID;
        DeliveryOrderController controller = new DeliveryOrderController();

        if(_args)
            packingSlipJour = _args.record();

        if (Box::yesNo("Do you want to print the Item Price and Amount?", DialogButton::No, "Confirmation") == DialogButton::Yes)
        {
            controller.parmCustPackingSlipJour(packingSlipJour);
            controller.parmArgs(_args);
            controller.parmShowDialog(false);
            controller.parmReportName(#ReportName);
            controller.preRunModifyContract();
            controller.startOperation();
        }
        else
        {
            controller.parmCustPackingSlipJour(packingSlipJour);
            controller.parmArgs(_args);
            controller.parmShowDialog(false);
            controller.parmReportName(#ReportName1);
            controller.preRunModifyContract();
            controller.startOperation();
        }
    }
}

DeliveryOrderDP:

[
    SRSReportParameterAttribute(classStr(DeliveryOrderContract))
]
class DeliveryOrderDP extends SRSReportDataProviderBase
{
    TmpDeliveryOrder  tmpDeliveryOrder;

    [
        SRSReportDataSetAttribute(tablestr("TmpDeliveryOrder"))
    ]
    public TmpDeliveryOrder GetData()
    {
        select * from tmpDeliveryOrder;
        return tmpDeliveryOrder;
    }

    public static void main(Args args)
    {
        DeliveryOrderDP  obj = new DeliveryOrderDP();
        obj.processReport();
    }

    [SysEntryPointAttribute(false)]
    public void processReport()
    {
        CustPackingSlipJour                 packingSlipJour;
        CustPackingSlipTrans                packingSlipTrans;
        CustTable                           custTable;
        SalesTable                          salesTable;
        SalesLine                           salesLine;
        SalesId                             salesId;
        Query                               query   =   new query();
        QueryRun                            queryRun;
        QueryBuildDataSource                qbds,qbds1;
        QueryBuildRange                     qbr,qbr1,qbr2;
        DeliveryOrderContract               rdpContract;
        RefRecId                            pacKingSlipRecId;
        int                                 i   =   1;
        Amount                              totalNetAmount = 0;
        EcoResDescription                   amountInWords;
        CurrencyCode                        currencyCode;

        rdpContract         =   new DeliveryOrderContract();
        rdpContract         =   this.parmDataContract() as DeliveryOrderContract;
        pacKingSlipRecId    =   rdpContract.parmPackingSlipRecId();

        qbds   =   query.addDataSource(tableNum(CustPackingSlipJour));

        if (pacKingSlipRecId)
        {
            qbr =   qbds.addRange(fieldNum(CustPackingSlipJour, RecId));
            qbr.value(queryValue(pacKingSlipRecId));
        }

        qbds1   =   qbds.addDataSource(tablenum(CustPackingSlipTrans));
        qbds1.addLink(fieldNum(CustPackingSlipJour,PackingSlipId),fieldNum(CustPackingSlipTrans,PackingSlipId));
        qbds1.addLink(fieldNum(CustPackingSlipJour,SalesId),fieldNum(CustPackingSlipTrans,SalesId));
        qbds1.addLink(fieldNum(CustPackingSlipJour,DeliveryDate),fieldNum(CustPackingSlipTrans,DeliveryDate));
        qbds1.relations(false);
        qbds1.joinMode(JoinMode::InnerJoin);

        queryRun    =   new QueryRun(query);

        while (queryRun.next())
        {
            packingSlipJour     =   queryRun.get(tableNum(CustPackingSlipJour));
            packingSlipTrans    =   queryRun.get(tableNum(CustPackingSlipTrans));
            salesTable          =   SalesTable::find(packingSlipJour.SalesId);
            custTable           =   CustTable::find(salesTable.CustAccount,false);
            currencyCode        =   salesTable.CurrencyCode;

            select salesLine
            where   salesLine.SalesId       ==  salesTable.SalesId
            &&      salesLine.ItemId        ==  packingSlipTrans.ItemId
            &&      salesLine.InventTransId ==  packingSlipTrans.InventTransId;

            //Header
            tmpDeliveryOrder.SalesId            =   salesTable.SalesId;
            tmpDeliveryOrder.CustAccount        =   salesTable.CustAccount;
            tmpDeliveryOrder.CustName           =   salesTable.customerName();
            tmpDeliveryOrder.Locator            =   salestable.customerPhone();
            tmpDeliveryOrder.Transdate          =   packingSlipJour.DeliveryDate;

            tmpDeliveryOrder.JobCardId          =   salesTable.SalesId;
            tmpDeliveryOrder.PackingSlipId      =   packingSlipJour.PackingSlipId;
            tmpDeliveryOrder.InventLocationId   =   salesTable.InventLocationId;
            tmpDeliveryOrder.LPO                =   salesTable.CustomerRef;
            tmpDeliveryOrder.Street             =   custTable.address();
            
            //Line
            tmpDeliveryOrder.SerialNo           =   i;
            tmpDeliveryOrder.ItemId             =   salesLine.ItemId;
            tmpDeliveryOrder.ItemDescription    =   salesLine.itemName();
            tmpDeliveryOrder.Qty                =   packingSlipTrans.Qty;
            tmpDeliveryOrder.SalesPrice         =   salesLine.SalesPrice;
            tmpDeliveryOrder.LineAmount         =   tmpDeliveryOrder.Qty    *  tmpDeliveryOrder.SalesPrice;
            if (salesLine.SalesQty  !=  0)
            {
                tmpDeliveryOrder.LineDiscountAmount =   (salesLine.LineDisc/salesLine.SalesQty) * tmpDeliveryOrder.Qty;
            }
            tmpDeliveryOrder.NetAmount          =   tmpDeliveryOrder.LineAmount -   tmpDeliveryOrder.LineDiscountAmount;
            tmpDeliveryOrder.UserId             =   salesTable.createdBy;
            tmpDeliveryOrder.insert();

            totalNetAmount  +=  tmpDeliveryOrder.NetAmount;

            i++;
        }

        amountInWords   =   Global::numeralsToTxt(totalnetAmount);

        ttsBegin;
        update_recordSet    tmpDeliveryOrder
        setting AmountInWords   =   amountInWords
        where   tmpDeliveryOrder.RecId  !=  0;
        ttsCommit;
    }
}

STEP 3: Add new report in your project.

Add a report in your project named as DeliveryOrder.

Add data set in your report named as DeliveryOrderDS and set properties of data sets as follows:

  • Data Source Type: Report Data Provider

Set query property by clicking on the three dots in the properties window. A new window will open and select DeliveryOrderDP. Click next and then select fields. Select TmpDeliveryOrder table for DeliveryOrderDS data set.

STEP 4: Add output menu item for report in your project.

Create an output menu item. Set the properties of output menu item as follows:

  • Object: DeliveryOrderController
  • Object Type: Class
  • Subscriber access level: Unset
  • Needs Record: Yes

See the below screenshot for reference.

Create an extention of form where you want to show the output menu item in my example I am using CustPackingSlipJournal. In the form, create Menu Item Button and set the properties as follows:

  • Data Source: CustPackingSlipJour
  • Needs Record: Yes
  • Menu Item Name: Name of OutputMenuItem (DeliveryOrderOutput)
  • Menu Item Type: Output

See the below screenshot of all project structure for reference.

STEP 5: Run the report from the user interface.

Go to Account receivable > Sales order > All sales order > Pick and Pack > Packing slip journal. Press the delivery order button.

See the below screenshot for reference.

This site uses cookies to offer you a better browsing experience. By browsing this website, you agree to our use of cookies.