How to programmatically complete Approval workflow task

A team mate of mine was stuck with a curious issue. She was using SharePoint’s in-built Approval workflow but was using a custom ASP.net application to talk to a custom webservice hosted inside SharePoint server. That particular web service was having a method to complete the Approval workflow’s task using SPWorkflowTask.AlterTask method.

Here is the code snippet that was being used to update the task from within the web method.

    1: SPList timesheets = web.Lists["SampleList"];
    2: string listID = "";
    3: SPListItem item = timesheets.Items[0];
    4:  
    5: SPWorkflowTask taskedit = null;
    6: SPWorkflowTask task = item.Tasks[0];        
    7: taskedit = task;
    8:  
    9: if (taskedit == null)   // no matching task
   10:     return;
   11:  
   12: // alter the task
   13: Hashtable ht = new Hashtable();
   14: ht["Status"] = "Complete";
   15: ht["PercentComplete"] = 1.0f;
   16:  
   17: SPWorkflowTask.AlterTask((taskedit as SPListItem), ht, true);

 

Now no matter how it was being updated, the workflow task was being updated but the workflow itself was stuck in “In Progress” state and never completes.

This was a curious thing as I had earlier also worked with similar issue but with a custom workflow created for SharePoint using Visual Studio. I had a sample code which was working with it and the customer workflow was getting completed.

Now what was different here?

After some troubleshooting and debugging, found that Approval workflow requires a property “TaskStatus” to be set in the hashtable being passed to SPWorkflowTask.AlterTask method. The valid values for “TaskStatus” property are:

 

ht["TaskStatus"] = " # ";   // This would mean that the task has been Approved

ht["TaskStatus"] = " @ ";   // This would mean that the task has been Rejected

 

So finally the code in the web method was updated to update the TaskStatus property as below:

    1: SPList timesheets = web.Lists["SampleList"];
    2: string listID = "";
    3: SPListItem item = timesheets.Items[0];
    4:  
    5: SPWorkflowTask taskedit = null;
    6: SPWorkflowTask task = item.Tasks[0];        
    7: taskedit = task;
    8:  
    9: if (taskedit == null)   // no matching task
   10:     return;
   11:  
   12: // alter the task
   13: Hashtable ht = new Hashtable();
   14: ht["TaskStatus"] = "#";    // Mark the entry as approved
   15:  
   16: SPWorkflowTask.AlterTask((taskedit as SPListItem), ht, true);

 

After this update, the tasks where updated properly and workflow completes as expected.

 

As always… Happy Coding