Cancelling a Task Programmatically in Sharepoint

Scenario

A user (Test15) raised a request and the normal flow is for It to go to the reporting manager (Test10) and if the reporting manager approves it then it will go to the process owner (Test20).



But in-between if the raised user (Test15) wants to cancel the task then he should be able to cancel his request. At that time the workflow will be cancelled and the Statuses will be updated as Request Cancelled.

Example

In the following example there are the following 3 lists:

  1. EmpAdvanceRequest (MasterList) where basic requesting information will be stored, like:
    (AREmpName, ARDesignation, ARDepartment, AREmpmailId, ARType, ARReqNum, ARAssignedTo, ARStatus).

  2. AdvanceRequestType(Child List) where more requesting information will be stored, like:
    (ARTravelFromDate, ARTravelToDate, ARDateOfReq, ARPlace, ARCurrency, ARAmount, ARTransferMode, ARBankName, ARAccountNum, ARTravelRemark, ARBankRemark).

  3. AdvanceRequest_WorkFlow Tasks (Task List)

Explanation

Step 1: A user (Test15) will raise the request using the following page:



Step 2: Now the task will be forwarded to the user (Test10). User (Test10) will view its task in his Dashboard below.



The underlined area shows the task that is created with the following Advance Request Id (ADVREQ0010) and it should be approved or rejected by the Reporting Manager (Test10).

Step 3: See It below.



If the Reporting Manager (Test10) clicks Reject then the request made by user (Test15) will be Rejected. If the Reporting Manager (Test10) clicks Approve then the task will be Approved and it will be processed to the Process Owner (Test20).

Step 4: The same procedure will be followed for the Process Owner (Test20) also. In other words, if he clicks the Reject Button then the task will be Rejected. If he clicks Approve then the task will be Approved for the User (Test15) and here the workflow will be completed.

Step 5: The following is the design of the Workflow:



Turning Point

Now if the user wants to cancel his request in between the final approval or rejection.

Then how will we manage? Because there is no extra state defined for the user In the workflow. So to deal with this we will manually cancel his Request and the Running workflow for the item created by the user (Test15) outside of the workflow and will change the statuses on The Master list, Child list and Task List.

Step 6 : Now the user (Test15) will go to his dashboard and view the requests that he has made.



Now on clicking on the Requestid (ADVREQ0011) all the requests related to that Requestid will come from the ChildList (AdvanceRequestType) will be displayed in a popup with a cancel button. If the task is rejected or approved then the cancel button will not be shown.

See the following figure.



Step 7 : On clicking the CancelRequest button the task will be cancelled from the Task list, Master List and the statuses will be updated in those following the list.

The following is the code sample on a CancelRequest click.

Code Sample To Cancel The Workflow Manually

  1. protected void btnCancelRequest_Click(object sender, EventArgs e)  
  2. {  
  3.     SPSecurity.RunWithElevatedPrivileges(delegate()  
  4.     {  
  5.     using (SPSite site = new SPSite(SPContext.Current.Web.Url))  
  6.     {  
  7.         using (SPWeb web = site.OpenWeb())  
  8.         {  
  9.             web.AllowUnsafeUpdates = true;  
  10.             SPWorkflowManager manager = site.WorkflowManager;  
  11.   
  12.             //Here We are getting the Masterlist(EmpAdvanceRequest) Item on which Workflow is running and changing its Status to Request cancelled//  
  13.   
  14.             SPListItem item = web.Lists["EmpAdvanceRequest"].GetItemById(Convert.ToInt32(ViewState["ListItemID"]));  
  15.             item["ARStatus "] = "Request Cancelled";  
  16.   
  17.             // This method is Used to get the Childlist(AdvanceRequestType) Items changing its Status to Request cancelled  
  18.   
  19.             updateAdvanceTypeList(Convert.ToString(item["ARReqNum"]));  
  20.   
  21.             //Here We are getting the Tasklist(AdvanceRequest_WorkFlow Tasks) Item and Cancelling the Running Workflow and changing its Status to Request cancelled here the Foreach loop is getting the currently running workflow from the task List based on the masterList item and then its changing the workflow task status and cancelling all the running workflow based on that item.//  
  22.   
  23.             foreach (SPWorkflow workflow in manager.GetItemActiveWorkflows(item))  
  24.             {  
  25.                 foreach (SPWorkflowTask WorkflowTasks in workflow.Tasks)  
  26.                 {  
  27.                     WorkflowTasks["ARTaskStatus"] = " Request cancelled ";  
  28.                     WorkflowTasks.Update();  
  29.                 }  
  30.                 SPWorkflowManager.CancelWorkflow(workflow);  
  31.             }  
  32.             item.Update();  
  33.             web.AllowUnsafeUpdates = false;  
  34.             ViewState["ListItemID"] = null;  
  35.         }  
  36.     }  
  37.     });  
  38. }  
  39. //Here is the Code to Update the ChildList Status to Request cancelled//  
  40. private void updateAdvanceTypeList(string RequestNum)  
  41. {  
  42.     try  
  43.     {  
  44.         SPSecurity.RunWithElevatedPrivileges(delegate()  
  45.         {  
  46.             using (SPSite site = new SPSite(SPContext.Current.Web.Url))  
  47.             {  
  48.                 using (SPWeb web = site.OpenWeb())  
  49.                 {  
  50.                     SPList list = web.Lists["AdvanceRequestType"];  
  51.                     SPQuery AdvanceRequestQuerry = new SPQuery();  
  52.                     AdvanceRequestQuerry.Query = @"<Where><Eq><FieldRef Name='ARReqNum' /><Value Type='Text'>" + RequestNum + "</Value></Eq></Where>";  
  53.                     AdvanceRequestQuerry.ViewFields = string.Concat("<FieldRef Name='ID'/>","<FieldRef Name='ARStatus'/>");  
  54.                     SPListItemCollection coll = list.GetItems(AdvanceRequestQuerry);  
  55.                     DataTable dt = new DataTable();  
  56.                     dt = coll.GetDataTable();  
  57.                     web.AllowUnsafeUpdates = true;  
  58.                     foreach (SPListItem item in coll)  
  59.                     {  
  60.                         item["ARStatus"] = "Request Cancelled";  
  61.                         item.Update();  
  62.                     }  
  63.                     web.AllowUnsafeUpdates = false;  
  64.                 }  
  65.             }  
  66.         });  
  67.         }  
  68.         catch (Exception ex)  
  69.         {  
  70.             throw ex;  
  71.         }  
  72.     }  
  73. }