Wednesday 24 March 2010

Assigning a task to multiple users in MOSS Workflow

I have been thinking of writing about this for quite a while now!!! Finally managed to sit down to write about the peculiar issue which we faced few weeks back in a Project.

Scenario

Business documents are created and shared using a document library in MOSS. The documents go through the approval process on creation/updating. A list of approvers is assigned. Document can be approved by any one of the approver.

Problem

The out of the box (OOTB) Approval workflow available in MOSS has the capability to add multiple approvers to an item added to document library or list. However it changes only the routing process of the approval workflow i.e. the approval task is to be sent to all the approvers (parallel) or task sent to one approver at a time (serial). (Refer the below picture)

MOSSworkflowApprovers

If we configure our workflow as parallel, then when a document or list item is created/updated, a separate task will be created for all the approvers. (Refer the below picture)

mossworkflowtasksootb

All the approvers have to approve the task for the document/list item to be approved.

However, in our scenario there should be only one task created irrespective of the number of approvers. Any one of the approvers can approve the task. This warranted a custom workflow solution to be built.

In a custom workflow we need to create a task which is assigned to multiple approvers. WF has the CreateTask activity which helps to create the task.

mosscustomworkflowpic1

MethodInvoking event of CreateTask activity is used to assign properties like assignedTo to the task which is created. (Refer the MethodInvoking event of CreateTask activity)

   1: private void createTaskAct_MethodInvoking(object sender, EventArgs e)
   2: {
   3:     try
   4:     {
   5:         using (SPSite site = new SPSite("http://madhu-win2k3:5000/Docs"))
   6:         {
   7:             using (SPWeb web = site.OpenWeb())
   8:             {
   9:                 TaskID = Guid.NewGuid();
  10:                 TaskProps = new SPWorkflowTaskProperties();
  11:                 TaskProps.Title = "Demo Task";
  12:                 TaskProps.AssignedTo = @"1;#MADHU-WIN2K3\Administrator;#15;#MADHU-WIN2K3\sharepointuser";
  13:                 //TaskProps.AssignedTo = web.SiteUsers[0].ID.ToString();
  14:                 TaskProps.Description = "test";
  15:                 TaskProps.ExtendedProperties["comments"] = comments;
  16:                 TaskProps.ExtendedProperties["instructions"] = instructions;
  17:             }
  18:         }
  19:  
  20:     }
  21:     catch (Exception ex)
  22:     {
  23:         Debug.WriteLine(ex);
  24:     }
  25: }

However, the CreateTask activity doesn’t support assigning the task to multiple users even though AssignedTo field of the Workflow Tasks list is changed to allow multiple selection (Refer the below Pic).

mossworkflowtasksassignedTo

Solution

One of the solution to the above problem was to have some other way to assign the task to multiple users since the CreateTask activity was not doing the job.

OnTaskCreated Activity to the rescue. OnTaskCreated activity provides a great way to tap into the task which has been been created and assign properties. The invoked event of the OnTaskCreated activity is used to assign the above said properties. (Refer the sample code for invoked event)

   1: private void onTaskCreated1_Invoked(object sender, ExternalDataEventArgs e)
   2: {
   3:     try
   4:     {
   5:         using (SPSite site = new SPSite("http://madhu-win2k3:5000/Docs"))
   6:         {
   7:             using (SPWeb web = site.OpenWeb())
   8:             {
   9:                 web.AllowUnsafeUpdates = true;
  10:                 SPList list = web.GetList("http://madhu-win2k3:5000/Docs/Lists/Tasks/AllItems.aspx");
  11:                 SPListItem item = list.Items.GetItemById(onTaskCreated1.AfterProperties.TaskItemId);
  12:                 item["Assigned To"] = @"1;#MADHU-WIN2K3\Administrator;#15;#MADHU-WIN2K3\sharepointuser";
  13:                 item.Update();
  14:             }
  15:         }
  16:     }
  17:     catch (Exception ex)
  18:     {
  19:         Debug.WriteLine(ex);
  20:     }
  21: }

With the above code it is now possible to assign the same task to multiple approvers. Thus any one of the approver can approve the task to make the corresponding document/list item approved.

However, for the above code to work it is necessary that the version settings for workflow tasks be disabled. Otherwise, we will get the following error “This task is currently locked by a running workflow and cannot be edited” when the task is approved or rejected.

Caveat

Caveat of the above approach is the version of the Workflow Tasks list has be disabled. This might not be possible in all scenarios.

Other Solutions

One of the other possible solution will be to create another column in the Workflow Tasks list which can allow multiple select to store “assigned to” users.

Another solution might be to create a field control to assign multiple users and use the field control to create a custom column in the Workflow Tasks list.

Technorati Tags: ,

1 comment:

  1. i got this thing working. but my workflow engine started behaving very strangely when i enabled AssignedTo field to accept multiple users. Besides this 'This task is currently blocked by a running workflow and cannot be edited' erroe - even after disabling the version on the list, my events were not firing when they were supposed to. I tried lots of things but nothing worked and finally i'd to take it back. i don't know whether there's any proper solution to this problme or not but i couldn't manage to get it worked.

    ReplyDelete