How to Make Custom Workflow in D365fo X++

 How to Make Custom Workflow in D365fo X++

Steps: 

1. Add a new base enum with the name “CustomWorkflowBaseEnum”

2. Add the elements in the newly created enum by right click on the enum and selecting “Add Element”.

3. Create a custom table with the name “CustomWorkflowTable” and add three fields (Id, name, CustomWorkflowBaseEnum) in the table.

4. Add a field group in this table by right click on the field groups and click “New Group”.

5. Change the name of the field group to “CustomWorkflowFieldGroup” and drag the fields in the field group according to your requirements. From clicking a learning perspective, I drag and drop all the fields in the group.

6. Override CanSubmitToWorkflow method of this table

7. Add a new method with the name "UpdateWorkflowStatus" in this table.

public boolean canSubmitToWorkflow(str _workflowType = '') { boolean ret; ret = super(_workflowType); if(this.CustomWorkflowBaseEnum != CustomWorkflowBaseEnum::Approved) { ret = true; } else { ret = false; } return ret; } /// <summary> /// /// </summary> public static void updateWorkflowStatus(RefRecId recId , CustomWorkflowBaseEnum status) { CustomWorkflowTable customWorkflowTable; ttsbegin; select forupdate customWorkflowTable where customWorkflowTable.RecId == recId; customWorkflowTable.CustomWorkflowBaseEnum = status; customWorkflowTable.update(); ttscommit; }


8. Add a custom form with the name “CustomWorkflowForm

9. Add our custom table “CustomWorkflowTable” in the datasource of the form.

10. Set the form design pattern as "Custom".

11. Add the action pane and a grid and drag and drop the datasource fields in the grid.

12. Set the allowEdit property of the enum control in the grid to No

13. Create a display menu item “CustomWorkflowMenu”.

14. Enter the created form name in the object property and set the label of the menu item.

15. Now create an extension of Accounts Receivable module in the project

16. Drag the menu item in the “InquiriesAndReport” section.

17. Create a new query with the name “CustomWorkflowQuery”

18. Add our table "CustomWorkflowTable" in the datasource of the query and set the dynamics field property to No.

19. Build the project with database synchronization.

20. Add work flow category “CustomWorkflowCategory”

21. Set module property to “SalesOrder” and also set the label.

22. Add a workflow type “CustomWorkflowType”

23. A new window will appear.  Enter category name, query name, display menu item name

24. Below classes and action menu items will automatically be created.

25. Change the label of workflow type submit action menu item.

26. Change the label of workflow type cancel action menu item

27. Add the below code in the submit manager class.

public static void main(Args args) { // TODO: Write code to execute once a work item is submitted. CustomWorkflowTable customWorkflowTable; WorkflowComment note = ""; WorkflowSubmitDialog workflowSubmitDialog; WorkflowCorrelationId workflowCorrelationId; WorkflowTypeName workflowTypeName = workFlowTypeStr("CustomWorkflowType"); //Opens the submit to workflow dialog. workflowSubmitDialog = WorkflowSubmitDialog::construct(args.caller().getActiveWorkflowConfiguration()); workflowSubmitDialog.run(); if (workflowSubmitDialog.parmIsClosedOK()) { customWorkflowTable = args.record(); // Get comments from the submit to workflow dialog. note = workflowSubmitDialog.parmWorkflowComment(); try { ttsbegin; workflowCorrelationId = Workflow::activateFromWorkflowType(workflowTypeName, customWorkflowTable.RecId, note, NoYes::No); customWorkflowTable.CustomWorkflowBaseEnum = CustomWorkflowBaseEnum::Submit; customWorkflowTable.update(); ttscommit; // Send an Infolog message. info("Submitted to workflow."); } catch (Exception::Error) { error("Error on workflow activation."); } } args.caller().updateWorkFlowControls(); }

28. Add the below code in workflow type event handler class

public void started(WorkflowEventArgs _workflowEventArgs) { // TODO: Write code to execute once the workflow is started. CustomWorkflowTable::updateWorkflowStatus(_workflowEventArgs.parmWorkflowContext().parmRecId(),CustomWorkflowBaseEnum::Submit); } public void canceled(WorkflowEventArgs _workflowEventArgs) { // TODO: Write code to execute once the workflow is canceled. CustomWorkflowTable::updateWorkflowStatus(_workflowEventArgs.parmWorkflowContext().parmRecId(),CustomWorkflowBaseEnum::Completed); } public void completed(WorkflowEventArgs _workflowEventArgs) { // TODO: Write code to execute once the workflow is completed. CustomWorkflowTable::updateWorkflowStatus(_workflowEventArgs.parmWorkflowContext().parmRecId(),CustomWorkflowBaseEnum::Cancel); }

29. Change the Workflow Enable property to Yes and add the workflow type name on the form design property.

30. Build the project with database synchronization.

31. Now add the workflow approval “CustomWorkflowApproval”

32. A window will appear.

Select workflow document (It’s the class which was created automatically it returns the query).

Enter field group of the custom table.

Enter display menu item name.

Some classes and action menus are created automatically.

33. Add the below code in the workflow approval event handler class.

public void started(WorkflowElementEventArgs _workflowElementEventArgs) { // TODO: Write code to execute once the workflow is started. } public void canceled(WorkflowElementEventArgs _workflowElementEventArgs) { // TODO: Write code to execute once the workflow is canceled. CustomWorkflowTable::updateWorkflowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), CustomWorkflowBaseEnum::Rejected); } public void completed(WorkflowElementEventArgs _workflowElementEventArgs) { // TODO: Write code to execute once the workflow is completed. CustomWorkflowTable::updateWorkflowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), CustomWorkflowBaseEnum::Rejected); } public void denied(WorkflowElementEventArgs _workflowElementEventArgs) { // TODO: Write code to execute once the workflow is denied. } public void changeRequested(WorkflowElementEventArgs _workflowElementEventArgs) { // TODO: Write code to execute once change is requested for the workflow. } public void returned(WorkflowElementEventArgs _workflowElementEventArgs) { // TODO: Write code to execute once the workflow is returned. } public void created(WorkflowWorkItemsEventArgs _workflowWorkItemsEventArgs) { // TODO: Write code to execute once work items are created. }

Change the label of workflow approval Approve Action Menu Item.

Change the label of workflow approval Delegate Action Menu Item.

Change the label of workflow approval Reject Action Menu Item.

Change the label of workflow approval RequestChange Action Menu Item.

Change the label of workflow approval Resubmit the Action Menu Item.

Now open workflow type and right click on the supported elements section and select “New Workflow Element Reference”.

Enter the workflow approval name in the Element Name property and also provide a name.

Change the label of workflow type.

Now build the project with database synchronization.

Open the form in the d365 browser, and see there is no workflow button enabled. So, we need to configure the custom workflow in the attached module as we set it in the Accounts Receivable module.

Link:

https://www.linkedin.com/pulse/custom-workflow-development-dynamics-365-finance-operations-ali

Comments