In Dynamics 365 FO implementation its common since ER’s inception to create electronics reports and business documents.
A lot can be achieved by creating data models , model mapping and by creating formats through UI than doing coding in visual studio. Also, a functional consultant or a business user can also create or modify these documents once they learn about it. You can run these documents from ER workspace.
In today’s blog post we will see what artifacts are required in order to put these documents on any specific UI in F&O. To explain that I am going to take an example of Projects form in F&O.
In my scenario we had to develop several custom ER reports and those need to be run from projects form.
First thing you need to do is create a contract class which you are going to use to run the configured ER report. Contract class is something you use to define the data structure that will be passed between different components of a business process, like parameters for a report or data needed for a specific operation.
Example of contract class looks likes this
[
DataContractAttribute
]
class SNDLWLWarrantyErReportContract extends ERFormatMappingRunBaseContract
{
RecId projTableRecId;
/// <summary>
/// Gets or sets the value of the datacontract parameter projTableRecId
/// </summary>
/// <param name = "_erBinding">RecId of <c>ProjTable</c></param>
/// <returns>RecId of <c>ProjTable</c></returns>
[DataMemberAttribute, SysOperationControlVisibilityAttribute(false)]
public RecId parmProjTableRecId(RecId _projTableRecId = projTableRecId)
{
projTableRecId = _projTableRecId;
return projTableRecId;
}
}
If required, you can create UI builder class to generate a runtime dialog box that will be used to look up the format mapping ID of the ER format that must be run.
Next step is creating service class. This service class is going to call an ER format which is going to be identified using mapping Id from UI builder class. Out of the box class ERObjectsFactory is used to run the mapping and provide output.
class SNDLWLWarrantyErReportService
{
public void generateOIReport(NBGSNDLWLWarrantyErReportContract _contract)
{
ERFormatMappingTable formattingTable;
ERFormatMappingId erMapping;
RecId projTableRecId = _contract.parmProjTableRecId();
ProjTable projTable;
select firstonly Format from formattingTable
where formattingTable.Name == “Name OF your ER report”;
erMapping = formattingTable.Format;
select firstonly ProjId from projTable
where projTable.RecId == _contract.parmProjTableRecId();
if (erMapping)
{
try
{
ERIModelDefinitionParamsAction parameters = new ERModelDefinitionParamsUIActionComposite()
.add(
new ERModelDefinitionDatabaseContext()
.addValue(tableNum(ProjTable), fieldNum(ProjTable, RecId), projTableRecId));
// Call ER to generate the report.
ERFormatMappingTable formatMapping = ERFormatMappingTable::find(erMapping);
ERObjectsFactory::createFormatMappingRunByFormatMappingId(erMapping, projTable.projid +'_'+"@NBGLabelFile:SNDLWLWarranty")
.withParameter(parameters)
.withFileDestination(_contract.getFileDestination())
.run();
}
catch
{
error("@SYP4861341");
}
}
else
{
info("@SYS300117");
}
}
}
You can either find format mapping directly by using the report name as I shown in my above code or by using your model with below code.
ERObjectsFactory::createFormatMappingTableLookupForControlAndModel(
_referenceGroupControl,
ERQuestionnairesModel,
ERQuestionnairesDataContainer).performFormLookup();
In this code sample ERQuestionnairesModel is your Model name and ERQuestionnairesDataContainer is root.
The last step is creating controller class so that you can create action menu item and add it on your form to execute the report.
class SNDLWLWarrantyErReportController extends ERFormatMappingRunBaseController
{
/// <summary>
/// Initializes the controller.
/// </summary>
/// <param name = "_args"></param>
public static void main(Args _args)
{
SNDLWLWarrantyErReportController controller = new SNDLWLWarrantyErReportController(
classStr(SNDLWLWarrantyErReportService),
methodStr(SNDLWLWarrantyErReportService, generateOIReport),
SysOperationExecutionMode::Synchronous);
SNDLWLWarrantyErReportContract contract = controller.getDataContractObject() as SNDLWLWarrantyErReportContract;
contract.parmProjTableRecId(_args.record().RecId);
controller.parmShowDialog(false);
controller.startOperation();
}
Once you create a action menu item you can add that menu item on a form and run your report for specific record selected on the form. In my scenario I added it on All projects form as shown below.

Hope you enjoyed this post.