Workflow in Microsoft Dynamics 365 FO

Workflow in Microsoft Dynamics 365 FO is used to automate business processes. Workflow in Microsoft Dynamics 365 F&O defines how document/record is moved through the system, approvals on the record, and decisions required at each step. So basically to understand we will take an example of a PO. Let’s just say I create a PO to buy 5 Laptops for my organization and the total cost of all the laptops is 10 lakh. and my Limit on the organizational level is limited at 5 lakh. so in workflow configuration as per a typical scenario, it will go to my manager whose limit is much greater than mine, then he will approve it or reject it depending on his decision. Configuration for workflow can be done from the front end, without any programming skills.

How to create a custom workflow:

I will be creating the custom workflow in Microsoft Dynamics 365 fo for the SCRF table(custom).

Step 1 for Workflow in Microsoft Dynamics 365 FO. Create an Enum which has the following enum values, in my case, I have created LSSCRFWorkflowStatus. It will have 4 elements

Draft

InReview

Approved

Rejected

as shown in the below picture. Make sure to create the elements in the above chronology only as by default new record should have Draft as a default value.

Workflow status Enum
Workflow status Enum – Workflow in Microsoft Dynamics 365 FO

Step 2 for Workflow in Microsoft Dynamics 365 FO. Now drag and drop this Enum in the table in which you want to apply the workflow, In my case I will be adding this enum in LSSCRFMainTable (this is a custom table) as shown below.

And make the field property

Allow Edit‘ as No

Allow Edit on Create‘ as No

Workflow status in Table
Workflow status in Table – Workflow in Microsoft Dynamics 365 FO

Step 3 for Workflow in Microsoft Dynamics 365 FO. Now go to the table methods and override ‘canSubmitToWorkflow‘ method and write code as shown below

/// <summary>
/// Return if user can submit scfr workflow
/// </summary>
/// <param name = "_workflowType">str</param>
/// <returns>If true user can else false</returns>
public boolean canSubmitToWorkflow(str _workflowType = '')
{
    boolean ret;

    ret = super(_workflowType);

    if  (this.RecId && 
        (this.SCRFWorkflowStatus == LSSCRFWorkflowStatus::Draft ||this.SCRFWorkflowStatus == LSSCRFWorkflowStatus::Rejected))
    {
        ret = true;
    }

    return ret;
}

Step 4 for Workflow in Microsoft Dynamics 365 FO. Now create another method ‘updateWorkflowStatus‘ on the table and write code as shown below

/// <summary>
/// Update the value in <c>LSSCRFMainTable</c> when workflow status changes
/// </summary>
/// <param name = "_recId">Recid of current record</param>
/// <param name = "_status">LSSCRFWorkflowStatus</param>
public static void updateWorkflowStatus(RefRecId   _recId, LSSCRFWorkflowStatus    _status)
{
    LSSCRFMainTable         mainTable;

    ttsbegin;
    select firstonly forupdate mainTable 
        where mainTable.RecId == _recId;
    
    mainTable.SCRFWorkflowStatus = _status;

    mainTable.update();
    ttscommit;
}

Step 5 for Workflow in Microsoft Dynamics 365 FO. Now create a form and put the data source as the above table, in my case my form is ‘LSSCRFMainTable‘ and create design and add controls in the design.

Adding DS in form
Adding DS in the form – Workflow in Microsoft Dynamics 365 FO

Step 6 for Workflow in Microsoft Dynamics 365 FO. Now create a display menu item for the form and set the

Object type property as Form

Object property as FormName (In my case LSSCRFMainTable)

Display menu item
Display menu item – Workflow in Microsoft Dynamics 365 FO

Step 7 for Workflow in Microsoft Dynamics 365 FO. Add the display menu item in the menu so that the user can see the form in the front end. In my case, I have added it in ‘Product Information Management’ inside Products as shown below.

Added menu extension in Menu
Added menu extension in Menu – Workflow in Microsoft Dynamics 365 FO

Step 8 for Workflow in Microsoft Dynamics 365 FO. Now create an AOT query and add the data source as shown below.

AOT query Dynamics 365
AOT query Dynamics 365 – Workflow in Microsoft Dynamics 365 FO

Now go to the property of Data source and set Dynamics Fields as Yes.

AOT query Dynamics 365 DS property
AOT query Dynamics 365 DS property – Workflow in Microsoft Dynamics 365 FO

Now build and sync the project area as shown below.

Build and Sync project area
Build and Sync project area – Workflow in Microsoft Dynamics 365 FO

Step 9 for Workflow in Microsoft Dynamics 365 FO. Once all is completed, we will start with the Workflow Category creation. To create a workflow category we will add item from solution explorer as shown below

Workflow category creation
Workflow category creation – Workflow in Microsoft Dynamics 365 FO

Now set the Label property and Module of the workflow category as shown below

Workflow category
Workflow category – Workflow in Microsoft Dynamics 365 FO

Step 10 for Workflow in Microsoft Dynamics 365 FO. Now add a workflow Type. To create a workflow type we will add item from Solution Explorer as shown below

Workflow type creation
Workflow type creation – Workflow in Microsoft Dynamics 365 FO

Once you click ok a new window will open like below, just select your category, query and Document menu item. These items were created in the previous steps. In my case

Category: LSSCRFCategory

Query: LSSCRFMAinTableWF

Document menu item: LSSCRFMainTable

Once this is created, it will create 3 classes and 2 action menu items. In my case, Classes were as follows:

Class 1: LSSCRFWFTypeEventHandler

Now in Class 1 LSSCRFWFTypeEventHandler should be updated as below

/// <summary>
/// The LSSCRFWFTypeEventHandler workflow event handler.
/// </summary>
public class  LSSCRFWFTypeEventHandler implements WorkflowCanceledEventHandler,  
	WorkflowCompletedEventHandler,
	WorkflowStartedEventHandler
{
    public void started(WorkflowEventArgs _workflowEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowEventArgs.parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::InReview);
	}

    public void canceled(WorkflowEventArgs _workflowEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowEventArgs.parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::Draft);
	}

    public void completed(WorkflowEventArgs _workflowEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowEventArgs.parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::Approved);
	}

}

Class 2: LSSCRFWFTypeSubmitManager

Now in Class 2 LSSCRFWFTypeSubmitManager should be updated as below

/// <summary>
/// The LSSCRFWFTypeSubmitManager menu item action event handler.
/// </summary>
public class LSSCRFWFTypeSubmitManager 
{
    public static void main(Args args)
	{
        #Define.Blank('')
        LSSCRFMainTable         mainTable;
        WorkflowComment         note = #blank;
        WorkflowSubmitDialog    workflowSubmitDialog;
        WorkflowCorrelationId   workflowCorrelationId;
        WorkflowTypeName        workflowTypeName = workFlowTypeStr('LSSCRFWFType');

        mainTable = args.record();

        //Opens the submit to workflow dialog.
        workflowSubmitDialog = WorkflowSubmitDialog::construct(args.caller().getActiveWorkflowConfiguration());
        workflowSubmitDialog.run();

        if (workflowSubmitDialog.parmIsClosedOK())
        {
            // Get comments from the submit to workflow dialog.
            note = workflowSubmitDialog.parmWorkflowComment();
            try
            {
                ttsbegin;

                workflowCorrelationId = Workflow::activateFromWorkflowType(workflowTypeName, mainTable.RecId, note, NoYes::No);
                mainTable.SCRFWorkflowStatus    = LSSCRFWorkflowStatus::InReview;
                mainTable.SubmittedBy           = curUserId();
                mainTable.SubmittedDate         = DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone());
                mainTable.update();

                ttscommit;
                info('Submitted to workflow.');
            }
            catch (Exception::Error)
            {
                throw error('Error on workflow activation.');
            }
        }

        args.caller().updateWorkFlowControls();
	}

}

Class 3: LSSCRFWFTypeDocument

Now in Class 3 LSSCRFWFTypeDocument should be updated as below

/// <summary>
/// The LSSCRFWFTypeDocument workflow document class.
/// </summary>
class LSSCRFWFTypeDocument extends WorkflowDocument
{
    /// <summary>
	/// Returns query name for the workflow document.
	/// </summary>
	/// <returns>
	/// Name of the query <c>LSSCRFMAinTableWF</c>.
	/// </returns>
	public queryName getQueryName()
	{
		return querystr(LSSCRFMainTableWF);
	}

}

Action menu item 1: LSSCRFWFTypeCancelMenuItem

Now in Action menu item 1 LSSCRFWFTypeCancelMenuItem should be updated as below. Set the label to ‘Recall’.

Workflow Cancel Action menu item
Workflow Cancel Action menu item – Workflow in Microsoft Dynamics 365 FO

Action menu item 2: LSSCRFWFTypeSubmitMenuItem

Now in Action menu item 2 LSSCRFWFTypeSubmitMenuItem should be updated as below. Set the label to ‘Submit’.

Workflow Submit Action menu item
Workflow Submit Action menu item – Workflow in Microsoft Dynamics 365 FO

Once all the above is done, do a build and sync of the project.

Step 11 for Workflow in Microsoft Dynamics 365 FO. Now we will create workflow approval, To create a workflow approval we will add an item from Solution Explorer as shown below

Workflow approval creation
Workflow approval creation – Workflow in Microsoft Dynamics 365 FO

Once you click next a new dialog box will open like below, fill in the details as shown below

Workflow document: This was that class that was automatically created while creating workflow type, in my case LSSCRFWFTypeDocument.

Document menu item: Menu item for the form that we created, in my case LSSCRFMainTable.

Workflow approval
Workflow approval – Workflow in Microsoft Dynamics 365 FO

Now once you click on next and finish, 2 classes and 5 menu items will be automatically created in your project area.

Class 1: LSSCRFWFApprovalEventHandler

Now in Class 1 LSSCRFWFApprovalEventHandler should be updated as below

/// <summary>
/// The LSSCRFWFApprovalEventHandler workflow outcome event handler.
/// </summary>
public final class LSSCRFWFApprovalEventHandler implements WorkflowElementCanceledEventHandler,
	WorkflowElemChangeRequestedEventHandler,
	WorkflowElementCompletedEventHandler,
	WorkflowElementReturnedEventHandler,
	WorkflowElementStartedEventHandler,
	WorkflowElementDeniedEventHandler,
	WorkflowWorkItemsCreatedEventHandler
{
    public void started(WorkflowElementEventArgs _workflowElementEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::InReview);
	}

    public void canceled(WorkflowElementEventArgs _workflowElementEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::Draft);
	}

    public void completed(WorkflowElementEventArgs _workflowElementEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::Approved);
	}

    public void denied(WorkflowElementEventArgs _workflowElementEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::Draft);
	}

    public void changeRequested(WorkflowElementEventArgs _workflowElementEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::Draft);
	}

    public void returned(WorkflowElementEventArgs _workflowElementEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::Rejected);
	}

    public void created(WorkflowWorkItemsEventArgs _workflowWorkItemsEventArgs)
	{
        LSSCRFMainTable::updateWorkflowStatus(_workflowWorkItemsEventArgs.parmWorkflowElementEventArgs().parmWorkflowContext().parmRecId(), LSSCRFWorkflowStatus::InReview);
	}

}

Class 1: LSSCRFWFApprovalResubmitActionMgr

Now in Class 1 LSSCRFWFApprovalResubmitActionMgr we don’t need to update anything

/// <summary>
/// The LSSCRFWFApprovalResubmitActionMgr menu item action event handler.
/// </summary>
public class LSSCRFWFApprovalResubmitActionMgr 
{
    public static void main(Args args)
	{
		//  TODO:  Write code to execute once work items are resubmitted.
	}

}

Action menu item 1: LSSCRFWFApprovalApprove

Update the property of the action menu item as shown below

LSSCRFWFApprovalApprove
LSSCRFWFApprovalApprove – Workflow in Microsoft Dynamics 365 FO

Action menu item 2: LSSCRFWFApprovalDelegateMenuItem

Update the property of the action menu item as shown below

LSSCRFWFApprovalDelegateMenuItem
LSSCRFWFApprovalDelegateMenuItem – Workflow in Microsoft Dynamics 365 FO

Action menu item 3: LSSCRFWFApprovalReject

Update the property of the action menu item as shown below

LSSCRFWFApprovalReject
LSSCRFWFApprovalReject – Workflow in Microsoft Dynamics 365 FO

Action menu item 4: LSSCRFWFApprovalRequestChange

Update the property of the action menu item as shown below

LSSCRFWFApprovalRequestChange
LSSCRFWFApprovalRequestChange – Workflow in Microsoft Dynamics 365 FO

Action menu item 5: LSSCRFWFApprovalDelegateMenuItem

Update the property of the action menu item as shown below

LSSCRFWFApprovalResubmitMenuItem
LSSCRFWFApprovalResubmitMenuItem – Workflow in Microsoft Dynamics 365 FO

Now do a build and synchronisation of the project area.

Step 12 for Workflow in Microsoft Dynamics 365 FO. Now open the Workflow type and add the workflow approval reference in the supported elements as shown below.

Workflow type element property
Workflow type element property – Workflow in Microsoft Dynamics 365 FO

Now for workflow type property should look as below (Just update the label for workflow type)

Workflow type property
Workflow type property – Workflow in Microsoft Dynamics 365 FO

Once all this is done, open the form on which you want to apply the workflow

Step 13 for Workflow in Microsoft Dynamics 365 FO. Go to form design set the workflow data source, enable the workflow, and set the workflow type. In my case, it is as follows

Workflow data source: LSSCRFMainTable

Workflow enabled: Yes

Workflow type: LSSCRFWFType

Enabling workflow on form
Enabling workflow on form – Workflow in Microsoft Dynamics 365 FO


Once all this is done, just build and synchronize your project area and we are good to go for front-end configuration.


Front-End configuration of workflow in Microsoft Dynamics 365 FO:


Now for the front-end configuration of the workflow for Workflow in Microsoft Dynamics 365 FO, go to the module for which you created the workflow, in my case ‘Product Information Management’ module.

Path for workflow form:

Product Information Management> Setup > Product Information and management workflow

You will see the workflows of that module in this form as shown below

Product information and management workflow
Product information and management workflow – Workflow in Microsoft Dynamics 365 FO

Click on the New button, you will see the list of workflow available in that module

Product information and management workflows
Product information and management workflows – Workflow in Microsoft Dynamics 365 FO

We can see the ‘SCRF workflow type’ that we created above, click on it.

Now a sign-in screen will open login to your account with your email ID. Enter the credentials and wait for some time(3-4 minutes), and a new window will pop up like below.

New workflow configuration
New workflow configuration – Workflow in Microsoft Dynamics 365 FO

Now drag and drop approval (in my case SCRF workflow approval) from the left side to the center.

Workflow configuration
Workflow configuration – Workflow in Microsoft Dynamics 365 FO

Now join the start with the approval and approval with the end as shown below.

Final workflow configuration
Final workflow configuration – Workflow in Microsoft Dynamics 365 FO

Now for the final part double-click on approval and, right-click properties, fill in the Work item Subject and Instruction as shown below

Work item subject and instruction in workflow configuration
Work item subject and instruction in the workflow configuration – Workflow in Microsoft Dynamics 365 FO

now click on properties of approval and select the assignment as shown below.

Workflow configuration assignment
Workflow configuration assignment – Workflow in Microsoft Dynamics 365 FO

then select the user and assign a user. In my case, I am assigning Atul as a user as shown below.

Workflow configuration assignment user
Workflow configuration assignment user – Workflow in Microsoft Dynamics 365 FO

Now click on save and close as shown below

Close and save workflow configuration
Close and save workflow configuration – Workflow in Microsoft Dynamics 365 FO

Once it is closed you can see the workflow in the ‘Product information and management workflow’ form as shown below.

Final Product information and management workflow
Final Product information and management workflow – Workflow in Microsoft Dynamics 365 FO

Now onwards, your form will be shown as below

Workflow on form - Workflow in Microsoft Dynamics 365 FO
Workflow on form – Workflow in Microsoft Dynamics 365 FO



You can also check out my previous blog: Create a custom service in d365 FO

Need help? Connect Atul

Atul Yadav
Latest posts by Atul Yadav (see all)

6 Comments

  1. Arpan

    Hi Atul, excellent blog.

    In this blog you discussed about Custom workflow.

    I like to know If I need to customize any stnd. workflow like AR or AP modules. Please insist me what to follow end to end. If any blogs you have kindly share please.

    thanks in advance!

    • Hi Arpan,

      Thank you for the kind words.

      Regarding Custom workflow, it depends on the requirement, let’s say you want to put some validation before submitting the workflow then you will write code on the canSubmitToWorkflow method of the table, this is one of the typical scenarios that we face on a day-to-day basis.

  2. Arpan

    Thanks Atul for the response.

    Actually, I asked you diff question – if we like to modify any standard workflow then what to be followed to achieve this?
    Kindly share me any link where I can get the step by step.

    thanks in advance!

    • Hi Arpan,

      Thank you for bringing this up. I initially thought you were considering customizing the standard workflow. Since the existing workflow seems to function well, I’m curious to understand the reasons for a complete change. Could you please share the use case scenario?

  3. Arpan

    Hi Atul,

    Thank you for responding. Just for the knowledge purpose I am asking. If suppose any modifications comes from the standard workflow from any modules like AR, AP etc. then how will i handle this?

    any idea on this?

    thanks in advance!

    • Hi Arpan,

      I think just create a custom workflow as shown above and update the workflow type in the form(extension) design property.

      PS: Never tried it.

Leave a Reply

Your email address will not be published. Required fields are marked *