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...