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.