Reopen a single catalog task in a workflow

Cirrus
Kilo Sage

Hi,

I am fairly new to scripting in ServiceNow and am wondering if this is even possible? We are having issues with people reopening sctasks by changing the state, so I have been able to lock this down using ACL once state = 'Closed'. However, there are also genuine needs to reopen a task (maybe closed in error). Thanks to Dressman, we have implemented the following script which restarts the entire workflow (inc REQ and RITM) when the sctask is re-opened:

current.state = "1";
current.work_notes = "Task reopened";
current.update();
    
      //Reopen the item record & restart the workflow.
      var i = new GlideRecord('sc_req_item');
      i.addQuery('sys_id', current.request_item);
      i.query();
      while (i.next()) {
         if(i.context != '')
            new Workflow().restartWorkflow(i, true);
         i.state = "1";
         i.stage = "fulfillment";
         i.comments = "Item reopened because task " + current.number + " was reopened.";
         i.update();
      }
    
      //Reopen the request record
      var r = new GlideRecord('sc_request');
      r.addQuery('sys_id', current.request_item.request);
      r.query();
      while (r.next()) {
         r.request_state = "in_process"
         r.work_notes = "Request reopened because item " + current.request_item.number + " was reopened.";
         r.stage = "requested"
         r.update();
      }

My problem is this. The script works a treat for single task workflows, but as soon as we have workflows with multiple tasks it causes problems because every task completed up to that point gets reopened, causing duplication and unnecessary workload.

What I was wondering is for multiple task workflows, is it possible to amend this script to only reopen the current.sctask ie the task that has just been reopened (and the REQ and RITM if its the last task) without reopening all tasks closed up to this point? Using Turnstiles is not an option because we never know which task might get reopened.

 

Thanks 

1 ACCEPTED SOLUTION

I think I figured out a work around.  Not sure it is the best way to do it but it works.  Here is what I did. All business rules are on the sc_task table.

1.  I created a true/false field on sc_task table called Prevent Reopen (u_prevent_reopen) with a default value of false.

2.  Created a Before update business rule with the below code.
     Condition - you may need to add additional closed state if you have them.     

current.state.changesTo(3) || current.state.changesTo(4)

     Code:     

(function executeRule(current, previous /*null when async*/) {

	// Add your code here
	current.u_prevent_reopen = true;

})(current, previous);

3. Added the following line of code the UI Action right under the current.work_notes = 'task reopened'

current.u_prevent_reopen = false;

4. Created another before update business rule with the below code.

    Condition    

current.state.changesTo(1) && current.u_prevent_reopen == true

   Code   

(function executeRule(current, previous /*null when async*/) {

	// Add your code here
	current.state = previous.state;

})(current, previous);

View solution in original post

8 REPLIES 8

Cirrus
Kilo Sage

Agreed, the restart workflow line is needed because its the only way to 'reopen the workflow' as well, which we need anyway. Its just the fact that it reopens every closed task up to that point that's the problem. I was hoping there was some additional script you could insert, or a business rule you could create alongside, which would leave all other closed tasks alone (even though it contradicts with restarting the workflow) but I haven't been able to figure it out. We may just have to run with people changing the state of individual tasks and accept that the workflow could potentially remain closed. Thanks for looking anyway

I think I figured out a work around.  Not sure it is the best way to do it but it works.  Here is what I did. All business rules are on the sc_task table.

1.  I created a true/false field on sc_task table called Prevent Reopen (u_prevent_reopen) with a default value of false.

2.  Created a Before update business rule with the below code.
     Condition - you may need to add additional closed state if you have them.     

current.state.changesTo(3) || current.state.changesTo(4)

     Code:     

(function executeRule(current, previous /*null when async*/) {

	// Add your code here
	current.u_prevent_reopen = true;

})(current, previous);

3. Added the following line of code the UI Action right under the current.work_notes = 'task reopened'

current.u_prevent_reopen = false;

4. Created another before update business rule with the below code.

    Condition    

current.state.changesTo(1) && current.u_prevent_reopen == true

   Code   

(function executeRule(current, previous /*null when async*/) {

	// Add your code here
	current.state = previous.state;

})(current, previous);

Cirrus
Kilo Sage

I owe you Bricast. Thankyou

Now for the but! Where would you clear the Actual End date? If you look at the related list for Catalogue Tasks on the RITM it still shows an end time, so at a cursory glance all tasks appear to be complete even though the last one has been reopened 

I would add it to the UI Action.  Something like current.work_end = ''; should work.