Workflow participant based Approval in Microsoft Dynamics 365 finance and operations using X++

Workflow participant based Approval in Microsoft Dynamics 365 finance and operations using X++


Hi Readers! In a previous article, I discussed the creation of a custom workflow in FO D365. I explained why I chose the HCMWorker table for the Person field lookup. This allows me to access active employees/workers in a specific legal entity with department/competency managers assigned to their competencies. This setup will ultimately facilitate assigning workflow approvals to the respective managers.

Don't forget to assign department managers to workers' competencies before starting the workflow.

Let's get right into it.

1. Add a new class in your project with the name "CustomLeaveReqWFParticipantProvider" and write the below code in it.

class  CustomLeaveReqWFParticipantProvider  implements WorkflowParticipantProvider
{   
  /// <summary>    
 /// Get participant token for workflow    
/// </summary>    
/// <returns>Token list</returns> 
   public WorkflowParticipantTokenList getParticipantTokens() 
   {    
    WorkflowParticipantTokenList tokens = WorkflowParticipantTokenList::construct();    
tokens.add("LeaveDepartmentManager","Leave Department Manager");            
    return tokens;
    }    

  /// <summary>  
  /// Resolve leave department manager token   
 /// </summary> 
   /// <param name = "_context">Leave department workflow context</param>  
  /// <param name = "_participantTokenName">Participant token name</param>   
 /// <returns>Workflow user list</returns>
    public WorkflowUserList resolve(WorkflowContext _context, 
       WorkflowParticipantToken _participantTokenName)
    {              
        WorkflowUserList userList = WorkflowUserList::construct();    
     if  (!_participantTokenName)   
     {        
         throw error("Participant token not assigned");       
      }  
         
  if  (_participantTokenName == "LeaveDepartmentManager")   
   {      
       HcmPersonnelNumberId worker   =  
       LeaveDepartmentManager::find(_context.parmRecId()).PersonnelNumber;                      
       DirPartyRecId ManagerPersonId = this.getManagerPersonId(worker); 

       if (ManagerPersonId)      
        {              
           userList.add(DirPersonUser::findParty(ManagerPersonId).User);         
         }           
      else     
        {    
            throw error("Position is not assigned to worker"); 
         }     
    }     
   return userList;   
    }     

  /// <summary>
  /// Get department manager   
  /// </summary> 
  /// <param name = "_hcmWorkerRecId">HcmWorkerRecId </param> 
   /// <returns>DiPartyRecId of manager</returns>   
 public DirPartyRecId getManagerPersonId(HcmPersonnelNumberId _hcmWorkerRecId)    
{    
      HcmPositionWorkerAssignment              workerPosition;    
       OMDepartmentRecId                             department;
       HcmWorkerRecId                                   departmentManger;   
       DirPartyRecId                                         managerId;      
       HcmWorker                                            hcmWorker;   
       CustomEmployeeTable                              employeeTable;       

       select firstonly Position from workerPosition          
            join PersonnelNumber from  hcmWorker              
                where  workerPosition.Worker        == hcmWorker.RecId   
            join PersonnelNumber from employeeTable           
               where employeeTable.PersonnelNumber == hcmWorker.PersonnelNumber     
                && hcmWorker.PersonnelNumber        == _hcmWorkerRe

        department            =   HcmPositionDetail::findByPosition(workerPosition.Position).Department;                 
        departmentManger =  OMOperatingUnit::find(department,OMOperatingUnitType::OMDepartment).HcmWorker;             
       managerId   = HcmWorker::find(departmentManger).Person;     
           return managerId;   
 }
}        

??getParticipantTokens method is invoked by the workflow configuration UI when surfacing the list of roles for role-based assignment. ??The unique ID of the participant token will be passed to the resolve method of the class implementing the WorkflowParticipantProvider interface.

resolve method resolves a participant token (role) into a list of users. In its params, _participantTokenName is The participant token that was selected for role-based assignment. It returns the workflow user list. Here it ensures if particpantTokenName matches what is configured in the workflow (Participant provider needs reconfiguration of workflow designer) and if the worker exists and position is assigned. Later retrieving worker against the department manager.

2. Before moving forward, build the project with DB sync then select Add New Item from your project. Add participant provider "CustomEmployeeWFParticipantProvider" with ParticipantProvider as a suffix. In old versions of Visual Studio, you may not be able to add a participant provider from the Add New Item window.

In that case, you can simply duplicate out-of-the-box (default) participant providers in your project and then change their labels.


3. Once you have the participant provider, go to its properties, give the label as it will be shown in workflow designer, select the Provider Class just created and set Available For All Workflow Templates to No, else this participant provider will be visible in the workflow designer of all workflow types.



4. Select the Workflow Types element in the participant provider. Add New Workflow Type Reference ,


5. Go to properties of newly added WFType reference, and copy/paste (drop dialogue will not show WFType) the name of the Workflow type for which the participant provider required.


6. Go to the D365 FO app from the browser and open the workflow designer window by clicking on Workflow from the workflows list of that module which is specified in the WFCategory. Double-click the central node, navigate to the properties of the code node


On properties window select Assignment from Left Pane, then Participant from Participant type from right Pane.


Move to the Role based next to the Assignment type. There select participant provider from Type of participant: drop dialog.


Select Participant which lies below Type of participant. You will only see one token name visible that was written in the participant provider class. Close the window

Click Save and Close to close the designer


Select Activate the new version in the next window and then Ok, whenever modify something in the workflow designer


Navigate to your form and initiate the workflow. In my example, I have not set any conditions in the workflow designer, except to assign the workflow for approval to the manager of the Department to which the employee belongs.

If you encounter a "Position is not assigned to Worker" error, debugging the participant provider class may help or revisit the position assignment to the Department Manager. assigned as Admin Role in Users

Remember to assign a System administration role to the Department Manager in System Administration -> Users --> Users to test and verify all workflow approval events.




That’s it, I hope this will help you define participants-based workflow approval assignments in the workflow.

Thank you.

Rashid Munir Sahu

要查看或添加评论,请登录

Rashid Munir Sahu的更多文章

社区洞察

其他会员也浏览了