Topic : SysOperation /Batch Processing in D365fo.
Instead of the RunBase framework, we can use the SysOperation framework. It contains 4 classes. Based on requirements we can use the required classes.
Controller class:
This class is the main class. Here we are calling service class and we can call contract also.
public class TestSysOperationController extends SysOperationServiceController
{
public void new()
{
//super(classStr(TestSysOperationService),
methodStr(TestSysOperationService, process),
SysOperationExecutionMode::Synchronous);
super();
this.parmClassName(classStr(TestSysOperationService));
this.parmMethodName(methodStr(TestSysOperationService, process));
this.parmDialogCaption("Dialog Title");
}
public ClassDescription caption()
{
return "Task Description";
}
public static void main(Args args)
{
TestSysOperationController controller;
controller = new TestSysOperationController();
//controller = TestSysOperationController::construct();
//controller.parmShowDialog(false);//Hide the batch dialog
//controller.initFromCaller()//Get contract class
//controller.refreshCallerRecord()//Refresh caller data source
//controller.captionIsSet = false;
// controller.parmDialogCaption(isExcelUp ? "ExcelUpload" :"Manual");
controller.startOperation();
//controller.getDataContractObject()//// for sys operation
//controller.parmReportContract().parmRdpContract()
}
public static TestSysOperationController construct(SysOperationExecutionMode _executionMode
= SysOperationExecutionMode::Synchronous)
{
TestSysOperationController controller;
controller = new TestSysOperationController();
controller.parmExecutionMode(_executionMode);
return controller;
/*ClassName className;
MethodName methodName;
switch (_args.menuItemName())
{
// It will trigger change whs process in site locations
case menuItemActionStr('Action menu item name') :
className = classStr(Service);
methodName = methodStr(Service, process);
break;
default:
break;
}
return new TestSysOperationController(className, methodName);*/
}
private void initFromCaller()
{
HelperContract contract;
#define.dataContractKey('_contract')
contract = this.getDataContractObject(#dataContractKey)
contract.initialize();
contract.parmCallerTableId(this.parmCallerRecord().TableId);
}
protected void refreshCallerRecord()
{
FormDataSource callerDataSource;
callerDataSource = FormDataUtil::getFormDataSource(this.parmCallerRecord());
if (this.parmCallerRecord() && callerDataSource)
{
callerDataSource.reread();
callerDataSource.research(true);
callerDataSource.refresh();
}
}
}
--------------------------------------------------------------------------
Service Class :
Our business logic is written here and this class is called from the controller class.
public class TestSysOperationServiceClass extends SysOperationServiceBase
{
public void process(TestContractClass _contract)
{
info(‘Running’);
List list = _contract.parmVendorList();
}
}
------------------------------------------------------------------------
Contract Class :
This class is used to create the parm methods If any parameters are required in the dialog.
[
DataContractAttribute,
SysOperationContractProcessingAttribute(classstr(TestUIBuilderClass))
]
class TestContractClass
{
List vendAccountList;
[
DataMemberAttribute("Vendor"),
AifCollectionTypeAttribute("Vendor", Types::String),
SysOperationLabelAttribute(literalstr("Vend account")),
SysOperationHelpTextAttribute(literalstr("Vend account.")),
//SysOperationGroupMemberAttribute('Group'),
SysOperationDisplayOrderAttribute('1')
//SysOperationControlVisibilityAttribute(false)// Hide control
]
public List parmVendorList(List _vendAccountList = vendAccountList)
{
vendAccountList = _vendAccountList;
return vendAccountList;
}
}
-------------------------------------------------------------------------------------------------------------
UI Builder Class:
This class is used to lookup, jumpref, modified, validate methods for dialog controls. we can add groups in that dialog. This is mainly for dialog design changes.
class TestUIBuilderClass extends SysOperationAutomaticUIBuilder//SrsReportDataContractUIBuilder
{
TestContractClass myContractClass;
DialogField dialogField;
container con;
public void build()
{
// super();
// Add group to dialog
//Dialog dialogObject = this.dialog();
// dialogObject.addGroup('Group');
myContractClass = this.dataContractObject() as TestContractClass;
dialogField = this.addDialogField(methodStr(TestContractClass, parmVendorList), TestContractClass);
}
public void postBuild() //or postRun() we can use any method.
{
super();
myContractClass = this.dataContractObject() as TestContractClass;
dialogField = this.bindInfo().getDialogField(TestContractClass, methodStr(TestContractClass, parmVendorList));
dialogField.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(TestUIBuilderClass, VendorLookup), this);
//dialogField.registerOverrideMethod(methodStr(FormStringControl, modified), methodStr(TestUIBuilderClass, Vendormodified), this); // modified method.
//dialogField.registerOverrideMethod(methodStr(FormStringControl, validate), methodStr(TestUIBuilderClass, vendorValidate), this); // validate method.
//if (dialogField)
//{
// dialogField.lookupButton(2);
//}
}
public boolean vendorValidate(FormStringControl _control)
{
if(!VendTable::Exist(_control.Value()))
{
error("Selected Vendor is not exists");
return false;
}
return true;
}
public void VendorLookup(FormStringControl _control)
{
Query query = new Query();
QueryBuildDataSource vendQBD;
// QueryBuildFieldList fieldList;
vendQBD = query.addDataSource(tableNum(VendTable));
//qbds1 = qbds.addDataSource(tableNum(DirPartyTable));
//qbds1.relations(True);
//qbds1.fields().clearFieldList();
//fieldList = qbds.fields();
//fieldList.addField(fieldNum(DirPartyTable, Name));
//fieldList.dynamic(QueryFieldListDynamic::No);
vendQBD.addSelectionField(fieldNum(VendTable, AccountNum));
SysLookupMultiSelectGrid::lookup(query,
_control,
_control,
_control,
con);
}
}
Keep Daxing!!