hljs.configure({cssSelector: "code"}); hljs.highlightAll();

Thursday, August 13, 2020

SysOperation Framework in Ax 2012


              The SysOperation Framework, initially called Business Operation Framework, seem to be the new substitute of the RunBase framework. As such, it allows you to perform operations that require parameters from the user, it allows you to set the operations to be executed in batch, or in a new asynchronous way, or in a synchronous manner. The great thing is that it simplifies the pack / unpack of variables that was pretty nasty in the RunBase framework, taking advantage of the Attributes feature, introduced with AX 2012.
                  It follows an MVC(Model View Controller) pattern.

In Sysoperation Framework the key objects are

1.Data Contract:

The data contract is the model class in which we define which attributes we need for our operation, commonly set as parameters by the user in a dialog. It's nothing more than a model class with a few attributes in it. We can define a SysOperation Data Contract class simply by adding the DataContractAttribute attribute to its declaraion. Additionally, if we want a set of methods to be available to us, we can also extend the SysOperationDataContractBase base class. With this class, we can define how our basic dialog will look like to the user. We can define labels, groups, sizes and types of the parameters.

2.UIBuilder  :

The UI builder class is actually an optional class for the SysOperation framework, which kind of acts as the view part of the pattern. You should only use it if you want to add some extra behavior to the dialog that AX constructs dynamically for you. If you are perfectly happy with the dialog AX shows you when you run your operation, you shouldn't worry about this class. To create a UI Builder, you should extend the SysOperationAutomaticUIBuilder class. It will provide you a set of methods to work with the dialog's design, but we usually add extra behavior or customize a lookup inside the postBuild method.

3.Controller:

The controller class has greater responsibility than the others. As the name suggests, it is the class that orchestrates the whole operation. The controller class also holds information about the operation, such as if it should show a progress form, if it should show the dialog, and its execution mode - asynchronous or not. To create a controller class you should extend the SysOperationServiceController, which will give you all of the methods you need.

4.Service:

There are some who put the business logic on controller classes so that they also perform the operation itself. I'm particularly not a big fan of that, it's too much responsibility for a single class! The programmers who created the SysOperation framework probably think the same, and they have made a way to separate the operation. You can create a service class! The only thing you have to do is extend the SysOperationServiceBase class and you're good to go. This class is the one that should contain all the business logic. When constructing your controller, you will indicate which class holds the operation that the controller will trigger, I'll demonstrate it later.

Now lets see an example

 * Create a Data Contract Class and define the DataContractAttribute at  top of the class.
Declare  the parameters that you want in dialog box. Here i declared custaccount in the class declaration.
  
DataContract:

[DataContractAttribute,sysoperationalwaysinitializeattribute]
class DaxSysoperationDataContract implements SysOperationInitializable
{
    CustAccount  custAccount;//parameter declaration
}
//sysoperationalwaysinitializeattribute is for parameter initialization
Create Parm Methods for each parameter if you don't the parameter will not display in dialog box

[DataMemberAttribute]
public CustAccount parmCustAccount (CustAccount _custAccount  = custAccount)
{
    custAccount= _custAccount;

    return custAccount;
}
 
Service:

Next create a Service Class extend it from SysOperationServiceBase class.

class DaxSysoperationService extends SysOperationServiceBase
{

}

In this class we will create a method which Filters the sales orders based on CustAccount and Inserts the records in my own table.

 [SysEntryPointAttribute]

public void Process(DaxSysoperationDataContract _DataContract)
{

    Query query = new Query();
    QueryBuildDataSource    qbds;
    QueryBuildRange         Range,range1;
    QueryRun                qrn;
    AccountNum              accountnum;
    SalesTable              salestable;
    DaxSalesTable        sales;
    CustParameters          custParameters;
    qbds = Query.addDataSource(tableNum(SalesTable));
    Range = qbds.addRange(fieldNum(SalesTable,CustAccount));
    accountnum = _DataContract.parmCustAccount();
    Range.value(accountnum);
    qrn = new QueryRun(query);
    while (qrn.next())
    {
     salestable = qrn.get(tablenum(SalesTable));
     Sales.Name  =salestable.SalesName;
     Sales.StudentId = salestable.SalesId;
     Sales.Address   = salestable.CustAccount;
     Sales.insert();
      }

       Whenever we are defining queries  in our method must declare SysEntryPointAttribute at top of             the  method.

Controller:

class DaxSysOperationController extends SysOperationServiceController
{
}

void new(IdentifierName _className = classStr(DaxSysoperationService),

IdentifierName _methodName = methodStr(DaxSysoperationService, process),

SysOperationExecutionMode _executionMode = SysOperationExecutionMode::Synchronous

)

{

    super(_className, _methodName, _executionMode);

   this.parmClassName(classStr(DaxSysoperationService));

   this.parmMethodName(methodStr(DaxSysoperationService,process));



}

public static DaxSysOperationController construct()
{
    DaxSysOperationController      controller;

    controller = new DaxSysOperationController();

    controller.parmShowDialog(true); // Actually the default value
    controller.parmShowProgressForm(false);

    return controller;
}


public static void main(Args _args)
{
    DaxSysOperationController controller;

    controller = DaxSysOperationController::construct();

    controller.startOperation();
}


}


No comments:

Post a Comment