Microsoft_MVP_banner

AX 2012 – sysOperation Framework – Use controller class to open dialog from AX form

In my previous post on sysOperation framework Example I described how the sysOperation framework can be used for the batch functionality in contrast to RunBaseBatch framework. In this post I will explain how you can use sysOperation Framework classes to open a dialog from a AX form using contract and controller classes and then run logic in Service class.

In this example I added a new menu item “Example” on projProjectsListPage form which will call controller class. This example is create project transactions using service calls at the end.









First we need to create a contract class which holds parameters (dialog fields value or user input). To keep it simple I only added two parameters ProjId (Project Id) and ProjContractId (Project Contract Id). That’s the model part of MVC pattern and view part is automatically created by using these data member attributes.

[DataContractAttribute]
class FF_ExampleContract
{
    ProjId              projId;
    ProjInvoiceProjId   projContractId;
}
[DataMemberAttribute,
SysOperationLabelAttribute(literalStr("Selected Project Id")),
SysOperationHelpTextAttribute(literalStr("Selected Project Id from projects")),
SysOperationDisplayOrderAttribute('1')
]
public ProjId parmProjId(ProjId _projId = projId)
{
    projId = _projId;
    return projId;
}
[DataMemberAttribute,
SysOperationLabelAttribute(literalStr("Selected Project contract Id")),
SysOperationHelpTextAttribute(literalStr("Selected Project Contract Id from projects")),
SysOperationDisplayOrderAttribute('2')
]
public ProjInvoiceProjId parmProjContractId(ProjInvoiceProjId _projContractId = projContractId)
{
    projContractId = _projContractId;
    return projContractId;
}


Let’s move to controller part of sysOperation framework and create a new controller class.

For this example I don’t need to have batch tab on dialog, so I set return value to FALSE in canGoBatch() method.

class FF_ExampleController extends SysOperationServiceController
{
    Common callerRecord;
}
public static void main(Args _args)
{
    FF_ExampleController controller;
    controller = FF_ExampleController::newFromArgs(_args);
    controller.parmShowDialog(true);
    controller.initFromCaller();
    controller.startOperation();
    controller.refreshCallerRecord();
}
public static FF_ExampleController newFromArgs(Args _args)
{
    FF_ExampleController        controller;
    IdentifierName              className;
    IdentifierName              methodName;
    SysOperationExecutionMode   executionMode;
    [className, methodName, executionMode] = SysOperationServiceController::parseServiceInfo(_args);
    if (_args.record())
    {
        executionMode = SysOperationExecutionMode::Synchronous;
    }
    controller = new FF_ExampleController(className, methodName, executionMode);
    controller.parmArgs(_args);
    controller.parmCallerRecord(_args.record());
    return controller;
}
public LabelType parmDialogCaption(LabelType _dialogCaption = "")
{
    LabelType caption;
    // This appears as the window name
    caption = "Create project transaction";
    return caption;
}
protected void new(
    IdentifierName _className = classStr(FF_ExampleService),
    IdentifierName _methodName = methodStr(FF_ExampleService, example),
    SysOperationExecutionMode _executionMode = SysOperationExecutionMode::ReliableAsynchronous
    )
{
    super(_className, _methodName, _executionMode);
}
private void initFromCaller()
{
    #define.dataContractKey('_contract')
    FF_ExampleContract contract;
    ProjTable       projTable;
    contract = this.getDataContractObject(#dataContractKey) as FF_ExampleContract;
    switch (this.parmCallerRecord().TableId)
    {
        case tableNum(ProjTable) :
            projTable = this.parmCallerRecord() as ProjTable;
            contract.parmProjId(projTable.ProjId);
            contract.parmProjContractId(projTable.ProjInvoiceProjId);
            break;
    }
}
public boolean canGoBatch()
{
    return false;
}
public Common parmCallerRecord(
    Common _callerRecord = callerRecord
    )
{
    callerRecord = _callerRecord;
    return callerRecord;
}
/// <summary>
///    Refreshes the calling form data source.
/// </summary>
protected void refreshCallerRecord()
{
    FormDataSource callerDataSource;
    if (this.parmCallerRecord() && this.parmCallerRecord().dataSource())
    {
        callerDataSource = this.parmCallerRecord().dataSource();
        callerDataSource.research(true);
    }
}


In the new method of controller class it is eventually calling service class method. We could create a method in controller class itself and refer that method into the new method of controller class to process business logic. This seems to be a lot for controller class, first to handle all parameters and then process business logic, recommended way is to separate the business logic in service class and another advantage of having service class is, these operations can also be used in web services (AIF) operations. That’s the separate topic and we will talk about it later…

Let’s create new service class and add entry point method to process business logic.

class FF_ExampleService
{
    FF_ExampleContract contract;
}
[SysEntryPointAttribute]
public void createProjectTransaction(FF_ExampleContract _contract)
{
    ProjId                  projId;
    ProjInvoiceProjId       projContractId;
    contract            = _contract;
    projId          = contract.parmProjId();
    projContractId  = contract.parmProjContractId();
    /*
   
    .... create project transactions
   
    */
}


Have we achieved what we aimed at start?

We are almost there, just need to add a new action menu item and assign controller & service class to it.
























That’s it!!! run the menu item and see how it works…





Click on Example menu item from Project list page, it opened a dialog with correct title ‘Create project transactions’ and with correct Project Id passed from calling form (ProProjectsListPage). 

Happy Dax!ng…

Share:

Related Posts

Microsoft Copilot
admin

Exploring Microsoft Copilot Architecture

Microsoft Copilot isn’t just another AI tool; it’s a comprehensive platform designed to be your indispensable companion, enhancing productivity, fostering creativity, and facilitating information comprehension all through a user-friendly chat interface. The concept of Copilot emerged two years ago when Microsoft introduced GitHub Copilot, aiming to assist developers in writing

Read More »
How to enable new Microsoft teams - Public Preview!
Microsoft Teams
Faisal Fareed

How to enable new Microsoft teams – Public Preview!

New Microsoft Teams is just AWESOME, quick but useful post below shows how you have this preview feature to make your life EASY!  Open Microsoft Teams admin center [Ask admin in your organization if you don’t have access] and follow path Teams > Teams update policies > Click on an existing

Read More »

Send Us A Message

Leave a Reply

Your email address will not be published. Required fields are marked *

Recent Post

Exploring Microsoft Copilot Architecture

Exploring Microsoft Copilot Architecture

Microsoft Copilot isn’t just another AI tool; it’s a comprehensive platform designed to be your indispensable companion, enhancing productivity, fostering creativity, and facilitating information comprehension all through a user-friendly chat interface. The concept of Copilot emerged two years ago when Microsoft introduced GitHub Copilot, aiming to assist developers in writing…

How to enable new Microsoft teams – Public Preview!

How to enable new Microsoft teams – Public Preview!

New Microsoft Teams is just AWESOME, quick but useful post below shows how you have this preview feature to make your life EASY!  Open Microsoft Teams admin center [Ask admin in your organization if you don’t have access] and follow path Teams > Teams update policies > Click on an existing…

Electronic Reporting: Send vendor payments to external azure storage via X++

Electronic Reporting: Send vendor payments to external azure storage via X++

Electronic Reporting module in Microsoft Dynamics 365 Finance Operation lets you archive file generated by ER at SharePoint location and in Azure Storage as per this link Archive ER destination type – Finance & Operations | Dynamics 365 | Microsoft Learn. APIs can be used to check message status and read…

FaisalFareed@2025. All rights reserved

Design by T3chDesigns