AX2012: SysOperation part 2: SysOperationServiceController
Hi again.
In part 1, we created a nice batch using data contracts, service operation and the SysOperationServiceController class.
Today, we will place our menu item on the Customers form, so we can process the customer that is selected in the grid. It will look like this:
A thing that is still missing though, is a way to work with the Args that are passed when a menu item is executed. We want to be able to set the query on our data contract before showing the batch dialog. We might also want to have a default value in some fields, for example, the date should be today’s date every time we launch the dialog.
We can do all of that by extending the SysOperationServiceController class.
So let’s do that!
Create a new class that extends SysOperationServiceController
{
}
Now let’s create a method that constructs an instance of this class based on the Args object
{
KlForCustTesterServiceController klForCustTesterServiceController;
;
// create a new instance of the controller
klForCustTesterServiceController = new KlForCustTesterServiceController();
// initialize from args
// one of the things this will do is read the "parameters" property from the menu item
klForCustTesterServiceController.initializeFromArgs(_args);
// return a new instance of this controller
return klForCustTesterServiceController;
}
Above is the basic code that should be in your construct method. However, this doesn’t do anything more than the SysOperationServiceController already does, so let’s add the logic that sets the date to today’s date.
{
KlForCustTesterServiceController klForCustTesterServiceController;
klForCustTesterDataContract klForCustTesterDataContract
;
// create a new instance of the controller
klForCustTesterServiceController = new KlForCustTesterServiceController();
// initialize from args
// one of the things this will do is read the "parameters" property from the menu item
klForCustTesterServiceController.initializeFromArgs(_args);
// get datacontract
// the string should be the same as the parameter name!
klForCustTesterDataContract = klForCustTesterServiceController.getDataContractObject('_klForCustTesterDataContract');
// default current date
klForCustTesterDataContract.parmTransDate(systemDateGet());
// return a new instance of this controller
return klForCustTesterServiceController;
}
As you can see, the Data Contract is fetched using the getDataContractObject() method. This will also unpack any values that were packed before, just like a normal RunBase would.
Setting the date is a simple as setting the parm method on the data contract.
Now let’s add the logic that creates the correct query by adding a range based on the record in the Args variable.
{
KlForCustTesterServiceController klForCustTesterServiceController;
klForCustTesterDataContract klForCustTesterDataContract;
CustTable custTable;
Query query;
;
// create a new instance of the controller
klForCustTesterServiceController = new KlForCustTesterServiceController();
// initialize from args
// one of the things this will do is read the "parameters" property from the menu item
klForCustTesterServiceController.initializeFromArgs(_args);
// get datacontract
// the string should be the same as the parameter name!
klForCustTesterDataContract = klForCustTesterServiceController.getDataContractObject('_klForCustTesterDataContract');
// default current date
klForCustTesterDataContract.parmTransDate(systemDateGet());
// check if the record is of type CustTable
if(_args && _args.dataset() == tableNum(CustTable))
{
// cast record
custTable = _args.record();
// create new query
query = new query(queryStr(KlForCustomers));
// add range
query.dataSourceTable(tableNum(CustTable)).addRange(fieldNum(CustTable, AccountNum)).value(queryValue(custTable.AccountNum));
// set query on datacontract
klForCustTesterDataContract.setQuery(query);
}
// return a new instance of this controller
return klForCustTesterServiceController;
}
There you go. Now we need to make a main method that uses this construct method, and starts the operation:
{
KlForCustTesterServiceController klForCustTesterServiceController;
;
klForCustTesterServiceController = KlForCustTesterServiceController::newFromArgs(_args);
klForCustTesterServiceController.startOperation();
}
We also need to create a new menu item. Right click you project – New – Menu Item.
Enter the following properties:
ObjectType: Class
Object: KlForCustTesterServiceController
Parameters: KlForCustTesterDataService.testCustomer
Next, add the menu item to the CustTable form:
Finally before testing, click the Generate Incremental CIL button to generate CIL.
Right click the CustTable form and click Open. This will open the Customers form. Switch to the grid view (Ctrl + Shift + G), and select a record. Then click the button we just added.
Note: a bug (or something I do wrong?) I found is that the query values that are displayed on the dialog seem to be “lagging”. The wrong values are shown, but when you click ok, the correct values are used, unless you click the select button.
This can be fixed by adding this line before returning the controller object:KlForCustTesterServiceController.queryChanged("_klForCustTesterDataContract.parmQuery", query);This is probably not a nice way to do this, so I’ll look into it, and let you know.
When you click Ok on the dialog, you should see that only the customer you’ve selected will be processed. You will also see that the date has been set to today’s date, just like we wanted.
This was originally posted here.
*This post is locked for comments