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
class KlForCustTesterServiceController extends SysOperationServiceController { }
Now let’s create a method that constructs an instance of this class based on the Args object
public static KlForCustTesterServiceController newFromArgs(Args _args) { 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.
public static KlForCustTesterServiceController newFromArgs(Args _args) { 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.
public static KlForCustTesterServiceController newFromArgs(Args _args) { 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:
public static void main(Args _args) { 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);
his 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.
SharedProject_KlFor_SysOperation_Day2.zip
http://www.artofcreation.be/2011/08/23/ax2012-sysoperation-part-2-sysoperationservicecontroller/
留言评论
暂无留言