Creating a batch job with query based filter in D365 back-office
There are often business processes that requires us to run specific operations as a batch process. Dynamics 365 Head quarters (HQ) allows us to be able to periodically execute batch jobs.
To create a custom batch job you need to extend the RunBaseBatch class. The following lines of code show how we can create a simple export job.
class InvoiceExport extends RunBaseBatch
{
Query query;
QueryRun invoiceQueryRun; // QueryRun object that will be used to generate data for invoices to be exported.
DialogGroup dialogGroupSetup; // This is a dialog group.
DialogField dialogFieldDownloadFile; // This is a dialog field.
boolean downloadFile; // This is a variable declaration that will store the user input.
// You need to initialize the macro so that your initial dialog values are registered.
// Note if this is an extension of an existing dialog then you
#define.CurrentVersion(1)
#localmacro.CurrentList
downloadFile
#endmacro
public container pack()
{
return [#CurrentVersion, #CurrentList, invoiceQueryRun.pack()];
}
boolean unpack(container packedClass)
{
Version version = RunBase::getVersion(packedClass);
container packedQuery;
switch (version)
{
case #CurrentVersion:
[version, #CurrentList, packedQuery] = packedClass;
if (SysQuery::isPackedOk(packedQuery))
{
invoiceQueryRun = new QueryRun(packedQuery);
}
break;
default:
return false;
}
return true;
}
public Object dialog()
{
DialogRunbase dialog = super();
dialogGroupSetup = dialog.addGroup('Invoice export');
dialogFieldDownloadFile = dialog.addFieldValue(extendedTypeStr(NoYesId), downloadFile, 'Download File', 'Download File');
return dialog;
}
public void dialogPostRun(DialogRunbase dialog)
{
super(dialog);
}
public boolean getFromDialog()
{
// This gets and sets the value for the dialog field based on user input.
downloadFile = dialogFieldDownloadFile.value();
return super();
}
protected boolean canRunInNewSession()
{
return false;
}
private static ClassDescription description()
{
return 'Invoice export'; // The dialog description.
}
public void initQueryRun()
{
this.initInvoiceQuery();
invoiceQueryRun = new QueryRun(query);
}
public QueryRun queryRun()
{
return invoiceQueryRun;
}
public void run()
{
try
{
this.exportData();
}
catch (Exception::Deadlock)
{
retry;
}
}
public boolean showQueryValues()
{
return true;
}
public static void main(Args _args)
{
InvoiceExport invoiceExport = new InvoiceExport();
invoiceExport.initQueryRun();
if (invoiceExport.prompt())
{
invoiceExport.runOperation();
}
}
private void initInvoiceQuery()
{
query = new Query();
QueryBuildDataSource custInvoiceTransQBDS = query.addDataSource(tableNum(CustInvoiceTrans));
// join CustInvoiceJour
QueryBuildDataSource custInvoiceJourQBDS = custInvoiceTransQBDS.addDataSource(tableNum(CustInvoiceJour));
custInvoiceJourQBDS.joinMode(JoinMode::InnerJoin);
custInvoiceJourQBDS.addLink(fieldNum(CustInvoiceTrans, ParentRecId), fieldNum(CustInvoiceJour, RecId));
// join RetailCustInvoiceJourTable
QueryBuildDataSource retailCustInvoiceJourTableQBDS = custInvoiceJourQBDS.addDataSource(tableNum(RetailCustInvoiceJourTable));
retailCustInvoiceJourTableQBDS.joinMode(JoinMode::ExistsJoin);
retailCustInvoiceJourTableQBDS.addLink(fieldNum(CustInvoiceJour, RecId), fieldNum(RetailCustInvoiceJourTable, CustInvoiceJour));
// join RetailExternalIdToCustomerMap
QueryBuildDataSource externalIdQBDS = custInvoiceJourQBDS.addDataSource(tableNum(RetailExternalIdToCustomerMap));
externalIdQBDS.joinMode(JoinMode::ExistsJoin);
externalIdQBDS.addLink(fieldNum(CustInvoiceJour, OrderAccount), fieldNum(RetailExternalIdToCustomerMap,CustomerAccountNumber));
// join RetailChannelTable for all channels
QueryBuildDataSource retailChannelTableQBDS = retailCustInvoiceJourTableQBDS.addDataSource(tableNum(RetailChannelTable));
retailChannelTableQBDS.joinMode(JoinMode::ExistsJoin);
retailChannelTableQBDS.addLink(fieldNum(RetailCustInvoiceJourTable, RetailChannel), fieldNum(RetailChannelTable, RecId));
}
private void exportData()
{
while (invoiceQueryRun.next())
{
CustInvoiceTrans custInvoiceTrans = invoiceQueryRun.get(tableNum(CustInvoiceTrans));
CustInvoiceJour custInvoiceJour = invoiceQueryRun.get(tableNum(CustInvoiceJour));
if (custInvoiceTrans && custInvoiceJour)
{
InventDim inventDim = InventDim::find(custInvoiceTrans.InventDimId);
CustTable custTable = CustTable::find(custInvoiceJour.OrderAccount);
// do something
}
}
}
}
Comments
Post a Comment