Reopen workflow tasks if previous tasks change

jimnicholson
Giga Guru

Hey All,

New to SN, hoping you may be able to help out here.   I have a workflow that generates about 15 tasks after approval.   These tasks need to be completed in order so I have all sorts of protection around them not allowing them to be edited until it's "the tasks turn."  

The item I am stuck on, for example:

Task 1:   Closed Complete

Task 2:   Closed Complete

Task 3:   Open

Task 4:   Pending

etc...

I have created a UI Action at the task level to allow tasks that have been previously closed to be reopened (the only way they can edit these tasks is to click this button)   So when a user hits "Reopen Task" the task state is now set to Open, and they can change information.   Let's say this happens in task 1, I need a way to when they close this task again, to reopen task 2 to an "Open" state, and put Task 3 in pending.   If task 2 were to be reopened, and modified, and then closed again, task 3 would be need to be reopened after.

Essentially, I need to restart the workflow right after the point where the data changed.   Information changing in a previous task could directly impact the subsequent tasks but would never impact the previous.   This wouldn't be so difficult for me if it was just reinitializing the workflow or rolling it back, but with so many variable roll back points, it becomes trickier for me.   Also, this is a custom built app, so it's nothing like change, incident, problem, that would be out of the box.

Any ideas?   Certainly happy to post, email, etc... any information you would find helpful.

Thanks very much!

Jim

6 REPLIES 6

Valor1
Giga Guru

This is a really interesting problem.


Here's how I'd do that.


Setup: create a "Reopened" checkbox on the sc_item table


Screen Shot 2015-10-12 at 5.56.52 PM.png


We need to capture the sequencing of tasks, which one(s) have been reopened, and where to reopen from.


1. Set up some workflow.scratchpad variables (see the Run Script activity from the workflow):


if (typeof workflow.scratchpad.taskArr == 'undefined'){


      workflow.scratchpad.taskArr = [];


}


if (typeof workflow.scratchpad.resetFrom == 'undefined'){


      workflow.scratchpad.resetFrom = '';


}



2. Create "IF" conditions ahead of every task creation. Advanced script (will have to be unique for every task, but I tried to make it as easy as possible--just change line 3):


answer = resetFrom();


function resetFrom(){


      var taskOrderNumber = 1;


      // return "yes" if we haven't created the next task yet


      // (i.e. haven't yet progressed to this point)


      if (workflow.scratchpad.taskArr.length < taskOrderNumber){


              return "yes";


      }


      // check to see if we should reset from here


      // delete the additional elements of the array to ensure reopen


      if (workflow.scratchpad.taskArr[taskOrderNumber - 1] == workflow.scratchpad.resetFrom){


              workflow.scratchpad.taskArr.splice(taskOrderNumber, taskOrderNumber - workflow.scratchpad.taskArr.length);


              return "yes";


      }


      return "no";


}



3. In each and every task creation, set the   fields:


  • Reopened = false
  • Order to "100," "200," etc. for each task in sequence
  • in the "Advanced" script, put this

if (task.sys_id == ''){


    workflow.scratchpad.taskArr.push(task.setNewGuid() + '');


}


else {


    workflow.scratchpad.taskArr.push(task.sys_id + '');


}



4. Create a "Wait for condition" to look for reopened tasks


answer = hasReopenedTask();


function hasReopenedTask(){


      var scTaskGR = new GlideRecord('sc_task');


      scTaskGR.addQuery('req_item', current.sys_id);


      scTaskGR.orderBy('order');


      scTaskGR.query();


      while(scTaskGR.next()){


              if (scTaskGR.u_reopened == true && scTaskGR.hasNext()){


                      scTaskGR.next();


                      workflow.scratchpad.resetFrom = scTaskGR.sys_id + '';


                      return true;


              }


      }


      return false;


}



5. Rollback to the beginning and the "IF" activities should take care of the rest.


This is awesome, and makes total sense, thank you very much!   I have a couple follow up questions.



As I mentioned, this is a custom app, so my table names are as follows:


x_engineering_task


x_engineering_table



1.   With the "reopened" checkbox I assume set at the x_engineering_task table, should my "reopen" UI Action check this box?   If so, where is it "reset" when the rollback is performed?   Will the task regeneration handle defaulting that back to "false"?



2.   Also, with the rollback, I want to maintain information that is currently in the tasks.   Will this solution result in the information being overwritten with empty fields?   If Task 1 is updated, but task 2 is complete, I want task 2 reopened but want it to maintain the information they have previously put in.  


To answer:


  1. Yes your Reopen UI Action should set the flag to true. IIRC, the task script gets re-evaluated when you "rollback to", but you may have to play with it a little
  2. See #1: I *think* only the script gets re-evaulated, but you may have to play with it

Thank you!   I've been messing with this a bit today, and my tasks are all being generated with a state of Closed Incomplete.... any idea why in the world that would be happening?   It's a bit tough to test the rollback functionality if they are being set as closed incomplete.   I even tried forcing the state by setting the value in the task creation, but no such luck.