SysOperation Framework D365 F&O
Nghia Song - Microsoft Dynamics 365 Technical Consultant
Nghia Song
Tel - WhatsApp: +84967324794
Email: songnghia.uit@gmail.com
SysOperation Framework D365 F&O
Thursday, June 17, 2021 9:35 PM
SysOperation framework permits batch logic to be written in a manner that helps running operations interactively, through the Dynamics batch server. So in this post, I am going to tell about How to code batch using SysOperation Framework in D365 F&O.
SysOperation implements the MVC (Model–View–Controller) design pattern, with the isolation of Parameters (Model), Dialog (View), and Service (Controller), for the code that’s executed. Batch using SysOperation Framework in D365 F&O makes the system more efficient.
The important objects of the SysOperation framework are outlined beneath:
Service
Service class extends from the SysOperationServiceBase class and incorporates the business logic for the batch operation. Developers typically have a tendency so as to add the business logic in controller classes, which violates the Single accountability precept.
Data Contract
Data contract class is the model class defining attributes wanted for batch operations. These attributes are provided by the user, in a dialog. DataContractAttribute attribute is required for the class and the properties methods require DataMemberAttribute attribute.
Controller
Controller class extends from the SysOperationServiceController class. It holds details about the batch operation like execution mode, present dialog or progress bar, and many others. It directs the batch operation.
UI Builder
UI Builder class extends from the SysOperationAutomaticUIBuilder class and is used for adding customized behavior to dialog/dialog fields dynamically constructed by the SysOperation framework.
In this blog post, I’ll cover three totally different scenarios (in a sequential method) for creating a batch using the SysOperation framework in D365 F&O.
Scenario 1: Creating a simple batch
To Create a simple batch we need a Controller class, Service class, and Menu Item to run it.
Controller class
public class TestControllerClass extends SysOperationServiceController
{
public void new()
{
{
super();
this.parmClassName(classStr(TestServiceClass));
this.parmMethodName(methodStr(TestServiceClass, processOperation));
this.parmDialogCaption("Batch Dialog Title");
}
public ClassDescription caption()
{
return "Batch Task Description";
}
public static void main(Args args)
{
TestControllerClass controller;
controller = new TestControllerClass();
controller.startOperation();
}
}
Service class
public class TestServiceClass extends SysOperationServiceBase
{
public void processOperation()
{
//Input any business process logic that need to be scheduled on batch
info("Running Batch Operation");
}
}
Menu Item
Name: TestSysOperationBatchMenu
Type: Action menu item
Object type: Class
Object: TestControllerClass
Then add created menu item to some Menu like Accounts payable for testing as shown below.
Scenario 2: Add custom parameters for batch operation
You can add custom parameters using parmMethods to the Data contract class.
Output can be seen in Batch job Logs
Controller class
public class TestServiceClass extends SysOperationServiceBase { public void processOperation(TestContractClass _contract) { //Input any business process logic that need to be scheduled on batch info("Running Batch Operation"); info("Date: " + date2Str(_contract.parmDate(), DateDay::Digits2, DateSeparator::Dot, DateMonth::Long, DateSeparator::Dot, DateYear::Digits4)); info("Text: " + _contract.parmText()); } }
Service class
public class TestServiceClass extends SysOperationServiceBase { public void processOperation(TestContractClass _contract) { //Input any business process logic that need to be scheduled on batch 7 info("Running Batch Operation"); info("Date: " + date2Str(_contract.parmDate(), 213, DateDay::Digits2, DateSeparator::Dot, DateMonth::Long, DateSeparator::Dot, DateYear::Digits4)); info("Text: " + _contract.parmText()); } }
Data Contract class
[DataContractAttribute] public class TestContractClass { TransDate dateValue; Description255 textValue; [DataMemberAttribute, SysOperationLabelAttribute('Date'), SysOperationHelpTextAttribute('Enter a date in past'), SysOperationDisplayOrderAttribute('1') ] public TransDate parmDate(TransDate _dateValue = dateValue) { dateValue = _dateValue; return dateValue; } [DataMemberAttribute, SysOperationLabelAttribute('Text'), SysOperationHelpTextAttribute('Type some text'), SysOperationDisplayOrderAttribute('2')] public Description255 parmText(Description255 _textValue = textValue) 23 { textValue = _textValue; return textValue; } }
Menu Item
Name: TestSysOperationBatchMenu
Type: Action menu item
Object type: Class
Object: TestControllerClass
Scenario 3: Add custom validation to dialog fields
On Parameter dialog, many times inputs need to be validated according to business logic. This can be achieved by using the UI Builder class. It helps in creation of dynamic/interactive parameters.
Controller class
public class TestControllerClass extends SysOperationServiceController { public void new() { super(); this.parmClassName(classStr(TestServiceClass)); this.parmMethodName(methodStr(TestServiceClass, processOperation)); this.parmDialogCaption("Batch Dialog Title"); } public ClassDescription caption() { return "Batch Task Description"; } public static void main(Args args) { TestControllerClass controller; controller = new TestControllerClass(); controller.startOperation(); } }
Service class
public class TestServiceClass extends SysOperationServiceBase { public void processOperation(TestContractClass _contract) { //Input any business process logic that need to be scheduled on batch 7 info("Running Batch Operation"); info("Date: " + date2Str(_contract.parmDate(), 213, DateDay::Digits2, DateSeparator::Dot, DateMonth::Long, DateSeparator::Dot, DateYear::Digits4)); info("Text: " + _contract.parmText()); } }
Data Contract class
[DataContractAttribute, SysOperationContractProcessingAttribute(classStr(TestUIBuilderClass)) ] public class TestContractClass { TransDate dateValue; Description255 textValue; [DataMemberAttribute, SysOperationLabelAttribute('Date'), SysOperationHelpTextAttribute('Enter a date in past'), SysOperationDisplayOrderAttribute('1') ] public TransDate parmDate(TransDate _dateValue = dateValue) { dateValue = _dateValue; return dateValue; } [DataMemberAttribute, SysOperationLabelAttribute('Text'), SysOperationHelpTextAttribute('Type some text'), SysOperationDisplayOrderAttribute('2') ] public Description255 parmText(Description255 _textValue = textValue) { textValue = _textValue; return textValue; } }
UI Builder class
public class TestUIBuilderClass extends SysOperationAutomaticUIBuilder { DialogField dateField; public void postBuild() { super(); // get references to dialog controls after creation dateField = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(TestContractClass, parmDate)); } public void postRun() { super(); // register overrides for form control events dateField.registerOverrideMethod(methodstr(FormDateControl, validate), methodstr(TestUIBuilderClass, validateDate), this); } public boolean validateDate(FormDateControl _dateControl) { if (_dateControl.dateValue() > today()) { error("Please select a valid date"); return false; } return true; } }
Menu Item
Name: TestSysOperationBatchMenu
Type: Action menu item
Object type: Class
Object: TestControllerClass
So you can use any of the shared scenarios, according to requirement to facilitate your customization.
From <https://daxtechie.com/batch-using-sysoperation-framework/>
No comments:
Post a Comment