Showing posts with label WorkflowHierarchyProviderHelper. Show all posts
Showing posts with label WorkflowHierarchyProviderHelper. Show all posts

Thursday, May 31, 2018

D365/AX7 – How to create custom workflow hierarchy assignment provider

The workflow designer provides a variety of configuration options to setup workflow as per our business needs. Workflow providers are the key components of the workflows in Microsoft Dynamics AX. These can be used to provide application specific information to the workflow instance at runtime.
You can go through the Workflow Providers Overview for brief introduction related to workflow providers in Microsoft dynamics AX.
We are going to look into the application of workflow hierarchy provider in order to solve the problem below.


Problem

To create a custom workflow hierarchy provider

Solution

Create custom workflow hierarchy provider using workflow hierarchy helper class for default behavior.

Step#1 Add new class for custom workflow hierarchy provider and implement with WorkflowHierarchyProvider class.

class MY_TaskWorkflowHierarchyProvider implements WorkflowHierarchyProvider
{
    const str Workflow_Employee = 'Employee';

    ExpressionDataSource            dataSource;
    WorkflowHierarchyProviderHelper helper;
}

Step#2 Override new method of the provider class as below

protected void new()
{
       helper = WorkflowHierarchyProviderHelper::construct();
dataSource = ExpressionDataSource::newDataSourceDefinition(Workflow_Employee, "@SYS121302");
       helper.setupDataSource(dataSource);
}

public static MY_TaskWorkflowHierarchyProvider construct()
{
       return new MY_TaskWorkflowHierarchyProvider();
}

Step#3 Implement the methods below with the default implementation of the workflow hierarchy provider using WorkflowHierarchyProviderHelper class

public anytype convertUserIdToNodeDataType(userId _userId,
WorkflowContext _workflowContext)
{
return helper.convertUserIdToNodeDataType(_userId, _workflowContext);
}

public ExpressionDataSource getDataSource()
{
return dataSource;
}

public WorkflowHierarchyProviderNode getNextNode(anytype _nodeId,
WorkflowHierarchyLevel _level,
WorkflowContext _workflowContext)
{
return helper.getNextNode(_nodeId, _level, _workflowContext, dataSource);
}

public extendedDataTypeName getNodeDataType()
{
return helper.getNodeDataType();
}

public Set getSupportedDataType()
{
return helper.getSupportedDataType();
}

public anytype convertToNodeDataType(extendedDataTypeName _dataType,
anytype _value,
       WorkflowContext _workflowContext)
{
return helper.convertToNodeDataType(_dataType, _value, _workflowContext);
}


Step#4 Add new workflow hierarchy assignment provider and set the Provider Class property with your custom hierarchy provider class name.





If the property Available for All Workflows is set to Yes, the provider will be applied to all the workflow types.
You can add your workflow type to enable this provider for the selective workflow and set the property Available for All Workflows to No.

Step#5 Build the relevant model.


Execution

Setup the workflow using task workflow hierarchy provider.


You can now add your customizations related to workflow hierarchy in this class.


Wednesday, May 30, 2018

D365/AX7 – How to add expression field for workflow hierarchy assignment


We have several scenarios when we need to have option to select additional field for hierarchy stopping condition and expression to exclude users when setting up the workflow design. Let’s have a look at how we can add field for hierarchy assignment expression for workflow.


Problem

To add field for hierarchy assignment conditions i.e. stopping condition and the condition to exclude users.
Consider a scenario where we need to assign workflow to an employee’s line managerial hierarchy. We need to add condition to exclude the workers (users) from the hierarchy, who does not belong to the department 022.

Solution

Following steps need to be performed to achieve the above requirement.
Step#1 Add new class to put all the relevant event handlers

class TaskWorkflowHierarchyProviderHandler
{
    const str Workflow_DepartmentId = 'DepartmentId';       

}

Step#2 Copy following event handlers from the class WorkflowHierarchyProviderHelper to your event handler class
1.       addAdditionalFieldsToDataSourceDelegate
2.       addDataSourceFieldsDelegate

Step#3 Add the below code to the method addAdditionalFieldsToDataSourceDelegate


/// <summary>
/// Add fields to data source
/// </summary>
/// <param name="_datasource">Expression data source</param>
[SubscribesTo(classStr(WorkflowHierarchyProviderHelper), delegateStr(WorkflowHierarchyProviderHelper, addAdditionalFieldsToDataSourceDelegate))]
public static void addAdditionalFieldsToDataSourceDelegate(ExpressionDataSource _datasource)
{
      _datasource.addField(ExpressionField::newFieldDefinition(Workflow_DepartmentId, extendedTypeStr(OMOperatingUnitNumber), "Department Id"));

}

Step#4 Add the below code to the method addDataSourceFieldsDelegate

/// <summary>
/// Add fields with values to the node data source
/// </summary>
/// <param name="_nodeDataSource">Node data source</param>
/// <param name="_workflowContext">Workflow context</param>
/// <param name="_hcmWorker">Worker at node</param>
/// <param name="_positionRecId">Positon of worker </param>
[SubscribesTo(classStr(WorkflowHierarchyProviderHelper), delegateStr(WorkflowHierarchyProviderHelper, addDataSourceFieldsDelegate))]
public static void addDataSourceFieldsDelegate(ExpressionDataSource _nodeDataSource,
WorkflowContext _workflowContext,
HcmWorker _hcmWorker,
HcmPositionRecId _positionRecId)
{
        HcmPositionDetail   postionDetail = HcmPositionDetail::findByPosition(_positionRecId);
        OMOperatingUnit     department = OMOperatingUnit::find(postionDetail.Department, OMOperatingUnitType::OMDepartment);
       
        _nodeDataSource.addField(ExpressionField::newFieldValue(Workflow_DepartmentId, extendedTypeStr(OMOperatingUnitNumber), department.OMOperatingUnitNumber));

}

This method sets the value for department Id for each worker in hierarchy.

Step#5 Build the respective model

Execution

Workflow will be assigned to the managerial hierarchy of supervisor Aaliyah. Set manager level to 2, so we have the hierarchy including Adam and Julia.


Add condition to exclude users who does not belong to department 022

Submit the workflow to verify the workflow assignment. The workflow assignment exclude the worker Adam, as he does not belong to the department 022, and thus directly assigns to Julia.