Friday, December 21, 2007

Leave Workflow - The Final Trick

Unfortuantly, I've had to rebuild my machine & I lost my leave workflow example in the process, but I'm sure you have a good idea how to build a state machine workflow.

To update tasks via the API, use SPWorkflowTask.AlterTask and this is where the final trick comes in.

One final tip, there is a bug in WF SharePoint framework (note: I have NOT tried this with Service Pack 1, if SP1 does fix it, please let me know). Essentially, if there is more than one version of the workflow associated with an item, sometimes the workflow will go into an error state with the following message:

"The task is locked by another user and cannot be updated".

So SPWorkflowTask.AlterTask has this problem, how do we fix it? Easy enough, right a static method that looks something like this:

public class MyWorkflowTask
    public static bool AlterTask(SPListItem task, Hashtable htData, bool fSynchronous, int attempts, int millisecondsTimeout)
      if ((int)task[SPBuiltInFieldId.WorkflowVersion] != 1)
        SPList parentList = task.ParentList.ParentWeb.Lists[new Guid(task [SPBuiltInFieldId.WorkflowListId].ToString())];
        SPListItem parentItem = parentList.Items.GetItemById((int)task[SPBuiltInFieldId.WorkflowItemId]);
        for (int i = 0; i < attempts; i++)
          SPWorkflow workflow = parentItem.Workflows[new Guid(task[SPBuiltInFieldId.WorkflowInstanceID].ToString())];
          if (!workflow.IsLocked)
            task[SPBuiltInFieldId.WorkflowVersion] = 1;
          if (i != attempts - 1)
      return SPWorkflowTask.AlterTask(task, htData, fSynchronous);

task.SystemUpdate() is the big override. It will override anything, so use this knowledge with care!!!!

And that's that, you should now be able to put togethere a basic state machine workflow without to much in the way of trouble.

No comments: