7. Adding a Query
Adding a query to the business operation class
allows the user to select a range of targets to apply the operation to,
such as sending bike-tuning offers to selected customers. To use the
query, you must be able to create an instance of QueryRun. Start by adding QueryRun as a member variable, as shown here.
public class BikeTuningOffers extends RunBase
{
DialogField dialogCreateServiceOrders;
NoYesId createServiceOrders;
CustAccount custAccount; // This member won't be used with the query.
QueryRun queryRun;
#define.CurrentVersion(2)
#define.version1(1)
#localmacro.CurrentList
createServiceOrders
#endmacro
}
|
To initialize the QueryRun object, override the initParmDefault method, as shown in the following code. This method is called by the RunBase framework if no saved object state is found by the SysLastValue framework via the unpack method.
public void initParmDefault()
{
Query query;
;
super();
query = new Query();
query.addDataSource(tableNum(CustTable));
queryRun = new QueryRun(query);
}
|
You must modify the pack method, as shown in the following example, so that you can save the state of the QueryRun object.
public container pack()
{
;
return [#CurrentVersion, #CurrentList, queryRun.pack()];
}
|
Consequently, you must also modify the unpack method to reinstantiate the QueryRun object, as shown here.
public boolean unpack(container _packedClass)
{
Version version = runbase::getVersion(_packedClass);
Container packedQuery;
;
switch (version)
{
case #CurrentVersion:
[version, #CurrentList, packedQuery] = _packedClass;
if (packedQuery)
queryRun = new QueryRun(packedQuery);
break;
default:
return false;
}
return true;
}
|
To make the QueryRun object available for presentation in the dialog box, override the queryRun method to return your QueryRun object, as shown in the following code.
public QueryRun queryRun()
{
;
return queryRun;
}
|
To show the query in the dialog box, you must override the showQueryValues method to return the value true, as follows.
boolean showQueryValues()
{
;
return true;
}
|
If you open the class now, you can see that the query is embedded in the dialog box, as shown in Figure 2.
Finally, you must change your business logic method, sendOffers, so that it uses the QueryRun object, as shown here.
private void sendOffers()
{
CustTable custTable;
BikeServiceOrderId bikeServiceOrderId;
BikeServiceOrderTable bikeServiceOrderTable;
SysMailer sysMailer;
;
sysMailer = new SysMailer();
ttsBegin;
while (queryRun.next())
{
custTable = queryRun.get(tableNum(CustTable));
if (createServiceOrders)
{
bikeServiceOrderId = NumberSeq::newGetNum(SalesParameters::
numRefBikeServiceOrderId()).num();
bikeServiceOrderTable.BikeServiceOrderId = bikeServiceOrderId;
bikeServiceOrderTable.CustAccount = custTable.AccountNum;
bikeServiceOrderTable.insert();
}
sysMailer.quickSend(CompanyInfo::find().Email,
custTable.Email,
"Tune your bike",
strFmt("Hi %1,\n\nIt's time to tune your bike....",
custTable.name));
}
ttsCommit;
}
|
8. Client/Server Considerations
Typically, you want to execute business
operation jobs on the server tier because these jobs almost always
involve several database transactions. However, you want the user dialog
box to be executed on the client to minimize client/server calls from
the server tier. Fortunately, the RunBase framework can help you run the dialog box on the client and the business operation on the server.
To run the business
operation job on the server and push the dialog box to the client, you
should be aware of two settings. On the menu item that calls the job,
you must set the RunOn property to Server; on the class, you must set the RunOn property to Called From. Figure 3 shows where to set the RunOn property of a class.
When the job is initiated, it starts on the server, and the RunBase
framework packs the internal member variables and creates a new
instance on the client, which then unpacks the internal member variables
and runs the dialog box. When the user clicks OK in the dialog box, RunBase packs the internal member variables of the client instance and unpacks them again in the server instance.