This is part 1 of a series of 3 blog posts where I demonstrate how to create batch classes using the SysOperation classes (Read the introduction here)
We are going to create a batch that looks like this:

And we are going to do that without creating a RunBaseBatch class!
Let’s create a new class, KlForCustTesterDataContract:
The string DataContractAttribute indicates that this class is a Data Contract. The square brackets [] indicate that this string is an attribute (You can read more about attributes on MSDN).
Next, let’s add Data Members to this contract by first declaring them in the class declaration
We add a string field, a date field, and a query. We still need to create parm methods for these variables.
This is just a simple string field, nothing special here except for the DataMemberAttribute attribute that indicates that this method is da data member.
The date field is of type TransDate, so we’ll give it a nicer label by using the SysOperationLabelAttribute attribute to specify the label used.
Also note that, when two attributes are specified, the are separated by a comma (,).
{
transDate = _transDate;
return transDate;
}
We will also add a query, so we can loop all customers. As you can see, we can specify the query by using the AifQueryTypeAttribute. The query KlForCustomers is just a query in the AOT with CustTable as a datasource (see xpo file at the end).
Next, we add two helper methods that are not Data Members, so we can easily set and get the query variable.
To get the query:
To set the query:
Right click the class, click properties, and set the run on property to server.
Adding a service operation to this service class is as simple as adding a method. As you can see, the SysEntryPointAttribute attribute indicates that this is a service operation, and our data contract is used as an argument.
Of course, this method needs some demo functionality, so let’s add that:
In the properties of this node, set the class property to KlForCustTesterDataService
Expand the node of your service, then right click on the Operations node.
Click Add operation and check the add checkbox next to the method we’ve created, and click OK.
Do this by right clicking your project – New – Menu item. Name it KlForCustTesterDataService.
Enter the following properties:
ObjectType: Class
Object: SysOperationServiceController
Parameters: KlForCustTesterDataService.testCustomer
As you can see, we don’t link directly to our service class, in stead, the class SysOperationServiceController will be used, and will know what service operation to start because it is specified in the parameters property. More about these controller class in part 2 of this series.

After CIL was generated, right click the menu item and click Open. You should see your batch class. As you can see, all fields from the datacontract are displayed, and a select button was automatically generated so you can modify the query.

Output when run in batch:

We are going to create a batch that looks like this:

And we are going to do that without creating a RunBaseBatch class!
Note: Just to be clear: the batch class won’t actually do anything useful, everything is just for demo purposes.Okay, let’s start!
1. Data Contract
First, we will create a data contract. The data contract contains data members that represent the fields that will be available on the dialog.Let’s create a new class, KlForCustTesterDataContract:
[DataContractAttribute]
class KlForCustTesterDataContract
{
}
class KlForCustTesterDataContract
{
}
Next, let’s add Data Members to this contract by first declaring them in the class declaration
[DataContractAttribute]
class KlForCustTesterDataContract
{
Name name;
TransDate transDate;
str packedQuery;
}
class KlForCustTesterDataContract
{
Name name;
TransDate transDate;
str packedQuery;
}
This is just a simple string field, nothing special here except for the DataMemberAttribute attribute that indicates that this method is da data member.
[DataMemberAttribute]
public Name parmName(Name _name = name)
{
name = _name;
return name;
}
public Name parmName(Name _name = name)
{
name = _name;
return name;
}
Also note that, when two attributes are specified, the are separated by a comma (,).
[DataMemberAttribute
,SysOperationLabelAttribute(literalStr("@SYS11284"))] // today's date
public TransDate parmTransDate(TransDate _transDate = transDate)
,SysOperationLabelAttribute(literalStr("@SYS11284"))] // today's date
public TransDate parmTransDate(TransDate _transDate = transDate)
{
transDate = _transDate;
return transDate;
}
[DataMemberAttribute,
AifQueryTypeAttribute('_packedQuery', querystr(KlForCustomers))
]
public str parmQuery(str _packedQuery = packedQuery)
{
packedQuery = _packedQuery;
return packedQuery;
}
AifQueryTypeAttribute('_packedQuery', querystr(KlForCustomers))
]
public str parmQuery(str _packedQuery = packedQuery)
{
packedQuery = _packedQuery;
return packedQuery;
}
To get the query:
public Query getQuery()
{
return new Query(SysOperationHelper::base64Decode(packedQuery));
}
{
return new Query(SysOperationHelper::base64Decode(packedQuery));
}
public void setQuery(Query _query)
{
packedQuery = SysOperationHelper::base64Encode(_query.pack());
}
{
packedQuery = SysOperationHelper::base64Encode(_query.pack());
}
2. Service class and operation
Next, let’s create a service class called KlForCustTesterDataService.
class KlForCustTesterDataService
{
}
{
}
Adding a service operation to this service class is as simple as adding a method. As you can see, the SysEntryPointAttribute attribute indicates that this is a service operation, and our data contract is used as an argument.
[SysEntryPointAttribute]
public void testCustomer(KlForCustomerTesterDataContract _klForCustomerTesterDataContract)
{
}
public void testCustomer(KlForCustomerTesterDataContract _klForCustomerTesterDataContract)
{
}
[SysEntryPointAttribute]
public void testCustomer(KlForCustTesterDataContract _klForCustTesterDataContract)
{
QueryRun queryRun;
CustTable custTable;
;
// info the name parameter
info(_klForCustTesterDataContract.parmName());
// create a new queryrun object
queryRun = new queryRun(_klForCustTesterDataContract.getQuery());
// loop all results from the query
while(queryRun.next())
{
custTable = queryRun.get(tableNum(custTable));
// display the accountnum
info(custTable.AccountNum);
}
}
public void testCustomer(KlForCustTesterDataContract _klForCustTesterDataContract)
{
QueryRun queryRun;
CustTable custTable;
;
// info the name parameter
info(_klForCustTesterDataContract.parmName());
// create a new queryrun object
queryRun = new queryRun(_klForCustTesterDataContract.getQuery());
// loop all results from the query
while(queryRun.next())
{
custTable = queryRun.get(tableNum(custTable));
// display the accountnum
info(custTable.AccountNum);
}
}
3. Service
Right click your project, and choose New – Service. Give this service the same name as the service class, KlForCustTesterDataService.In the properties of this node, set the class property to KlForCustTesterDataService
Expand the node of your service, then right click on the Operations node.
Click Add operation and check the add checkbox next to the method we’ve created, and click OK.
4. Menu item
All we need to do now is create a menu item so we can start our dialog.Do this by right clicking your project – New – Menu item. Name it KlForCustTesterDataService.
Enter the following properties:
ObjectType: Class
Object: SysOperationServiceController
Parameters: KlForCustTesterDataService.testCustomer
As you can see, we don’t link directly to our service class, in stead, the class SysOperationServiceController will be used, and will know what service operation to start because it is specified in the parameters property. More about these controller class in part 2 of this series.
5. Run it!
But wait, we still have to do one small thing: compile our X++ into the common intermediate language (CIL). Don’t worry, it’s easy. Just click the Generate Incremental CIL button in the toolbar (this might take a while).
After CIL was generated, right click the menu item and click Open. You should see your batch class. As you can see, all fields from the datacontract are displayed, and a select button was automatically generated so you can modify the query.

Output when run in batch:

No comments:
Post a Comment