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:
- EmpAdvanceRequest (MasterList) where basic requesting information will be stored, like:
(AREmpName, ARDesignation, ARDepartment, AREmpmailId, ARType, ARReqNum, ARAssignedTo, ARStatus).
- AdvanceRequestType(Child List) where more requesting information will be stored, like:
(ARTravelFromDate, ARTravelToDate, ARDateOfReq, ARPlace, ARCurrency, ARAmount, ARTransferMode, ARBankName, ARAccountNum, ARTravelRemark, ARBankRemark).
- 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
- protected void btnCancelRequest_Click(object sender, EventArgs e)
- {
- SPSecurity.RunWithElevatedPrivileges(delegate()
- {
- using (SPSite site = new SPSite(SPContext.Current.Web.Url))
- {
- using (SPWeb web = site.OpenWeb())
- {
- web.AllowUnsafeUpdates = true;
- SPWorkflowManager manager = site.WorkflowManager;
-
-
-
- SPListItem item = web.Lists["EmpAdvanceRequest"].GetItemById(Convert.ToInt32(ViewState["ListItemID"]));
- item["ARStatus "] = "Request Cancelled";
-
-
-
- updateAdvanceTypeList(Convert.ToString(item["ARReqNum"]));
-
-
-
- foreach (SPWorkflow workflow in manager.GetItemActiveWorkflows(item))
- {
- foreach (SPWorkflowTask WorkflowTasks in workflow.Tasks)
- {
- WorkflowTasks["ARTaskStatus"] = " Request cancelled ";
- WorkflowTasks.Update();
- }
- SPWorkflowManager.CancelWorkflow(workflow);
- }
- item.Update();
- web.AllowUnsafeUpdates = false;
- ViewState["ListItemID"] = null;
- }
- }
- });
- }
-
- private void updateAdvanceTypeList(string RequestNum)
- {
- try
- {
- SPSecurity.RunWithElevatedPrivileges(delegate()
- {
- using (SPSite site = new SPSite(SPContext.Current.Web.Url))
- {
- using (SPWeb web = site.OpenWeb())
- {
- SPList list = web.Lists["AdvanceRequestType"];
- SPQuery AdvanceRequestQuerry = new SPQuery();
- AdvanceRequestQuerry.Query = @"<Where><Eq><FieldRef Name='ARReqNum' /><Value Type='Text'>" + RequestNum + "</Value></Eq></Where>";
- AdvanceRequestQuerry.ViewFields = string.Concat("<FieldRef Name='ID'/>","<FieldRef Name='ARStatus'/>");
- SPListItemCollection coll = list.GetItems(AdvanceRequestQuerry);
- DataTable dt = new DataTable();
- dt = coll.GetDataTable();
- web.AllowUnsafeUpdates = true;
- foreach (SPListItem item in coll)
- {
- item["ARStatus"] = "Request Cancelled";
- item.Update();
- }
- web.AllowUnsafeUpdates = false;
- }
- }
- });
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- }