How to pass Arguments/records in RDP Report through form, how to open report from the Form using controller class (X++) in D365 Finance and operation.

 In this article, I will guide you on how to pass arguments or records from a form to a report as parameters. I have developed a report that prints the purchase order for a specific purchase ID (with either ‘Received’ or ‘Invoiced’ purchase status), which I pass through the form.

Let’s begin by creating a simple Finance and Operations project in Visual Studio. We will add all the elements required to develop the report. The following elements are necessary:

  • Temp table (with required fields, fields which mapped in Dp class)
  • Contract class
  • Data Provider Class
  • Report (Add the DP class to the Dataset of the Report, and create the report design according to your requirements)

For the PurchTable Form, create a Form Extension of the PurchTable Form and add a button group and button in the Action pane.

DP Class:

[SrsReportParameterAttribute(classStr(PurchTable_Contract))]

class PurchTable_DP extends SRSReportDataProviderBase
{
PurchReceiptTmp prt;

//Serializing The Code
[SrsReportDataSetAttribute("PurchReceiptTmp")] //Fetching Data from Table
public PurchReceiptTmp get_RecieptTable()
{
select * from prt;
return prt;
}

/// <summary>
/// Processing Report
/// </summary>
public void processReport()
{
PurchTable_Contract contract;
ListIterator iter;
List purchID;
contract =this.parmDataContract();
purchID = contract.parm_purchID();
prt.clear();
iter = new ListIterator(purchID);
while(iter.more())
{
prt.PurchId = iter.value();
this.populate_Line();
iter.next();
}
}

/// <summary>
/// This is Filling the Table
/// </summary>
public void populate_Line()
{
PurchTable pt;
PurchLine pl;
VendInvoiceJour venInvJr;
VendInvoiceTrans venInvTr;

// Query For Filling the Table
while select firstonly pt where prt.PurchID == pt.PurchId
join pl where prt.PurchId == pl.PurchId
{
if(pt.PurchStatus == PurchStatus::Received)
{
this.DataofRecievedStatus();
}
else if(pt.PurchStatus == PurchStatus::Invoiced)
{
this.DataofRecievedStatus();
while select * from venInvJr where prt.PurchId == venInvJr.PurchId
join venInvTr where prt.PurchId == venInvTr.PurchID
{
while select forupdate prt
where prt.PackingSlipId == venInvTr.getPackingSlip().PackingSlipId && prt.OrderedQuantity == venInvTr.Qty
{
ttsbegin;
prt.InvoiceId = venInvJr.InvoiceId;
prt.InvoiceQty = venInvTr.Qty;
prt.PurchPrice = venInvTr.PurchPrice;
prt.InvoiceItemId = venInvTr.ItemId;
prt.InvoiceName = venInvTr.Name;
prt.update();
ttscommit;
}
}
}
}
}

/// This Method is for collecting data in case of Purchase Status is Recieved
public void DataofRecievedStatus()
{

VendPackingSlipTrans venPacSlipTrans;
VendPackingSlipJour venPacSlipJour;
while select * from venPacSlipTrans where prt.PurchID == venPacSlipTrans.OrigPurchid
join venPacSlipJour where prt.PurchId == venPacSlipJour.PurchId && venPacSlipJour.PackingSlipId == venPacSlipTrans.PackingSlipId
{
prt.PackingSlipId = venPacSlipTrans.PackingSlipId;
prt.OrderedQuantity = venPacSlipTrans.Ordered;
prt.RecievedQty = venPacSlipTrans.Qty;
prt.ValueMST = venPacSlipTrans.ValueMST;
prt.ItemId = venPacSlipTrans.ItemId;
prt.Name = venPacSlipTrans.Name;
prt.PurchId = venPacSlipTrans.OrigPurchid;
prt.insert();
}
}
}

======================================================================
[SRSReportParameterAttribute(classStr(VTGMRLINWHSWorkReportContract))] class VTGMRLINWHSWorkReportDP extends SRSReportDataProviderBase { GMRLINWHSWorkTableCopy workTable; [SRSReportDataSetAttribute(tablestr(GMRLINWHSWorkTableCopy))] public GMRLINWHSWorkTableCopy getWorkTable() { select workTable; return workTable; } public void processReport() { VTGMRLINWHSWorkReportContract contract; ListIterator iter; List whsWorkIdList; WHSWorkId getWhsWorkId; WHSWorkTable WHSWorkTable; WHSWorkLine WHSWorkLine; // contract = this.parmDataContract() as VTGMRLINWHSWorkReportContract; contract = this.parmDataContract(); whsWorkIdList = contract.parm_WHSWorkId(); workTable.clear(); iter = new ListIterator(whsWorkIdList); // Get sales agreement header record from the contract parameter // WHSWorkTable = WHSWorkTable::find(contract.parmWHSWorkId()); while(iter.more()) { getWhsWorkId = iter.value(); WHSWorkTable = WHSWorkTable::find(getWhsWorkId); if (WHSWorkTable.RecId) { while select * from WHSWorkLine where WHSWorkLine.WorkId == WHSWorkTable.WorkId { workTable.WorkId = WHSWorkTable.WorkId; workTable.WaveId = WHSWorkTable.WaveId; workTable.WorkTransType = WHSWorkTable.WorkTransType; workTable.LoadId = WHSWorkTable.LoadId; workTable.CombinedWorkId = WHSWorkTable.CombinedWorkId; workTable.TargetLicensePlateId = WHSWorkTable.TargetLicensePlateId; workTable.OrderNum = WHSWorkTable.OrderNum; workTable.InventSiteId = WHSWorkTable.InventSiteId; workTable.InventLocationId = WHSWorkTable.InventLocationId; workTable.LineNum = WHSWorkLine.LineNum; workTable.WorkType = WHSWorkLine.WorkType; workTable.ItemId = WHSWorkLine.ItemId; workTable.WMSLocationId = WHSWorkLine.WMSLocationId; workTable.QtyWork = WHSWorkLine.QtyWork; workTable.UnitId = WHSWorkLine.UnitId; workTable.WorkStatus = WHSWorkLine.WorkStatus; workTable.itemBarCode = InventItemBarcode::findItem(WHSWorkLine.ItemId, WHSWorkLine.InventDimId, true, true).itemBarCode; workTable.ProductName = InventTable::name(WHSWorkLine.ItemId, InventDim::find(WHSWorkLine.InventDimId)); workTable.CustName = CustTable::find(SalesTable::find(WHSWorkTable.OrderNum).CustAccount).name(); workTable.wMSStoreZoneId = WMSLocation::find(WHSWorkLine.WMSLocationId, InventDim::find(WHSWorkLine.InventDimId).InventLocationId).ZoneId; workTable.inventBatchId = InventDim::find(WHSWorkLine.InventDimId).inventBatchId; workTable.expDate = InventBatch::find(InventDim::find(WHSWorkLine.InventDimId).inventBatchId, WHSWorkLine.ItemId).expDate; workTable.insert(); } // read the next record iter.next(); } } } }
  1. Class Declaration: The class PurchTable_DP extends SRSReportDataProviderBase, which is a base class for all RDP classes in Microsoft Dynamics AX/365.
  2. Data Members: The class has one data member prt of type PurchReceiptTmp.
  3. get_RecieptTable() Method: This method is decorated with the SrsReportDataSetAttribute attribute, which indicates that the method will provide data for the report. It selects all records from prt and returns them.
  4. processReport() Method: This method is responsible for processing the report. It retrieves the contract from the data contract, gets the purchase ID, and then iterates over the list of purchase IDs to populate the line.
  5. populate_Line() Method: This method populates the prt table based on the purchase status. If the purchase status is Received, it calls the DataofRecievedStatus() method. If the purchase status is Invoiced, it first calls the DataofRecievedStatus() method and then updates the prt table with invoice details.
  6. DataofRecievedStatus() Method: This method is used to collect data when the purchase status is Received. It selects records from venPacSlipTrans and venPacSlipJour based on the purchase ID and packing slip ID, and then inserts the selected data into the prt table.

The code is designed to handle the processing of purchase receipts based on their status (Received or Invoiced). It populates a temporary table (prt) with the relevant data, which is then used to generate a report. The actual report layout would be defined elsewhere, likely in an SSRS report design (RDL) file.

Contract Class:

/// <summary>
/// Forcing the report to get Parameters From User
/// </summary>

class PurchTable_Contract // This Class is used to take input Parameters From The User
{
List purchID;
[
DataMemberAttribute("purchID"), // This Serailizes the Variable
SysOperationLabelAttribute(literalStr('Purchase Order')),// This Changes the Input Parameter name
AifCollectionTypeAttribute("purchID",Types::String) // This Serializes the List Type
]

public List parm_purchID( List _purchID = purchID)
{
purchID = _purchID;
return purchID;
}
}

==================================================================
[DataContractAttribute] public class VTGMRLINWHSWorkReportContract { List whsWorkIdList; [ DataMemberAttribute("WHSWorkId"), SysOperationLabelAttribute(literalStr('Work Id')), AifCollectionTypeAttribute("WHSWorkId",Types::String) ] public List parm_WHSWorkId( List _whsWorkId = whsWorkIdList) { whsWorkIdList = _whsWorkId; return whsWorkIdList; } }

This class is used to take input parameters from the user for a report. Here’s a brief explanation of the code:

  1. Class Declaration: The class PurchTable_Contract is declared. This class is used to take input parameters from the user.
  2. Data Members: The class has one data member purchID of type List.
  3. parm_purchID() Method: This method is a getter-setter for the purchID data member. It takes an optional parameter _purchID which defaults to purchID. If _purchID is provided, it sets purchID to _purchID and then returns purchID.
  4. Attributes: The purchID data member is decorated with three attributes:
  • DataMemberAttribute: This attribute serializes the purchID variable.
  • SysOperationLabelAttribute: This attribute changes the input parameter name to ‘Purchase Order’.
  • AifCollectionTypeAttribute: This attribute serializes the List type.

This class is typically used in conjunction with a report data provider (RDP) class to supply parameters to a report. The user is prompted to enter these parameters when running the report. The parameters are then used to filter or otherwise manipulate the data that the RDP class provides to the report. In this case, the parameter is a list of purchase IDs (purchID).

Handle the Button Click Event: In the form extension class, create a static event handler method for the Clicked event of the button. In this method:

[ExtensionOf(formStr(PurchTable))]
final class PurchTableForm_Extension
{
/// <summary>
/// Gets the selected records and pass them to the Report
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
///

[FormControlEventHandler(formControlStr(PurchTable, Report), FormControlEventType::Clicked)]
public static void Report_OnClicked(FormControl sender, FormControlEventArgs e)
{
//super();
PurchTable purchtable;
FormRun formrun = sender.formRun();
FormDataSource purchTable_ds;
Array records;
purchTable_ds = sender.formRun().dataSource(1);
// purchtable = purchTable_ds.cursor(); // This line is for getting one parameter where the cursor is present

SrsReportRunController controller = new SrsReportRunController();
PurchTable_Contract purchTable_contract = new PurchTable_Contract();
List parm = new List(Types::String);
// Accessing the Report Name along with the design
controller.parmReportName(ssrsReportStr(PurchTable_Report,PurchTable_Report));

// getting all the selected records
purchtable = purchTable_ds.getFirst(true);
while(purchtable)
{
parm.addEnd(purchtable.PurchId);
purchtable = purchTable_ds.getNext();
}

// passing the parameters to the contract class
purchTable_contract.parm_purchID(parm);

controller.parmReportContract().parmRdpContract(purchTable_contract);

// Disabling the parameter Dialog field
controller.parmShowDialog(false);
controller.startOperation();

}
}

===================================================================
[ExtensionOf(formStr(WHSWorkTableListPage))] final class VTWHSWorkTableListPageFrm_Extension { /// <summary> /// Gets the selected records and pass them to the Report /// </summary> /// <param name="sender"></param> /// <param name="e"></param> [FormControlEventHandler(formControlStr(WHSWorkTableListPage, VTGMRLINWHSWork), FormControlEventType::Clicked)] public static void VTGMRLINWHSWork_OnClicked(FormControl sender, FormControlEventArgs e) { //super(); WHSWorkTable whsWorkTable; FormRun formrun = sender.formRun(); FormDataSource whsWorkTable_ds; Array records; whsWorkTable_ds = sender.formRun().dataSource(1); SrsReportRunController controller = new SrsReportRunController(); VTGMRLINWHSWorkReportContract whsWorkReportContract = new VTGMRLINWHSWorkReportContract(); List parm = new List(Types::String); // Accessing the Report Name along with the design controller.parmReportName(ssrsReportStr(VTGMRLINWHSWork,Report)); // getting all the selected records whsWorkTable = whsWorkTable_ds.getFirst(true); while(whsWorkTable) { parm.addEnd(whsWorkTable.WorkId); whsWorkTable = whsWorkTable_ds.getNext(); } // passing the parameters to the contract class whsWorkReportContract.parm_WHSWorkId(parm); controller.parmReportContract().parmRdpContract(whsWorkReportContract); // Disabling the parameter Dialog field controller.parmShowDialog(false); controller.startOperation(); } }

This class extends the form PurchTable and is used to handle the event when the Report button is clicked on the form. Here’s a brief explanation of the code:

  1. Class Declaration: The class PurchTableForm_Extension is declared. This class extends the form PurchTable.
  2. Report_OnClicked() Method: This method is decorated with the FormControlEventHandler attribute, which indicates that it’s an event handler for the Clicked event of the Report button on the PurchTable form.
  3. Inside the Report_OnClicked() Method:
  • It first initializes some variables and objects, including a SrsReportRunController object and a PurchTable_Contract object.
  • It then sets the report name in the controller.
  • It gets all the selected records from the PurchTable form’s data source and adds their purchase IDs to a list.
  • It passes the list of purchase IDs to the PurchTable_Contract object.
  • It sets the PurchTable_Contract object in the report contract of the controller.
  • It disables the parameter dialog field of the controller.
  • Finally, it starts the operation of the controller, which would run the report with the provided parameters.

This class is typically used to handle user interactions with the form. In this case, it handles the event when the Report button is clicked, gets the selected records from the form, and runs a report with those records as parameters. The actual report would be defined elsewhere, likely in an SSRS report design (RDL) file. The report would use the provided parameters to filter or otherwise manipulate the data it displays.

Comments

Popular posts from this blog

Customization on Sales invoice Report in D365 F&O

75) COC - Create a coc of the table modified method

46) D365 FO: SHAREPOINT FILE UPLOAD USING X++