Recalculate Workflow Timer When Value Changes

sdtimb
Giga Expert

I'm using a wf Timer activity to pause until the 'Disable Date" on a Request Item is reached. The next step in the wf runs a "Disable AD User Account" Orchestration activity.

 

Issue: I need the wf Timer to reset if the Disable Date data/time is change on the Request Item. This is required in cases when the termination date or time changes from when it was originally scheduled...or when it is submitted incorrectly. Is there a way to reset the timer if/when the "Disable Date" field changes?

 

DisableLAN.jpg

 

DisableDate.jpg

9 REPLIES 9

Did you ever come up with a solution?


could change the disable task to be a sub workflow that waits


this way, you could look for that sub workflow name and restart it without restarting the main workflow


Thanks for the approach Stephen.   I've taken your advice and decided to share what I came up with.   This is a business rule for updating two timers on a change request workflow when the Start Date changes.



function onAfter(current, previous) {


  //Reschedule SCOM REST message timer


  var scomTimer = retrieveTriggerRecord('Alert - SCOM Maint Mode - 5 min before');


  if(scomTimer != 'none')


  rescheduleNextAction(5,scomTimer);



  //Reschedule late approval timer


  var lateTimer = retrieveTriggerRecord('Wait 1 hour before Implementation Start date');


  if(lateTimer != 'none')


  rescheduleNextAction(60,lateTimer);



  function retrieveTriggerRecord(timer){


  //Find the workflow context record


  var grContext = new GlideRecord("wf_context");


  grContext.addQuery('id',current.sys_id);


  grContext.query();


  if(!grContext.next())


  return 'none';



  //Find the Workflow Executing record


  var grExecuting = new GlideRecord("wf_executing");


  grExecuting.addQuery("context", grContext.sys_id);


  grExecuting.addQuery("activity.name", timer);


  grExecuting.addQuery("activity.activity_definition.name", 'Timer');


  grExecuting.query();


  if (!grExecuting.next())


  return 'none';



  //Find the sys_trigger record


  var grTrigger = new GlideRecord("sys_trigger");


  grTrigger.addQuery("name", 'WFTimer' + grExecuting.sys_id.toString());


  grTrigger.query();


  if (grTrigger.next())


  return grTrigger;


  else


  return 'none';


  }



  function rescheduleNextAction(minutes,trigger){


  var newTime = new GlideDateTime(current.start_date);


  newTime.addSeconds(-(minutes*60));


  //gs.log('DEBUG >> ' + newTime.toString());


  trigger.next_action = newTime.toString();


  trigger.update()


  }


}


Hi Dan,



I have similar Requirement whenever changes to followup field in incident, timer workflow activity should reset with updated date in follow up. But this script is not working for me. Able to find current executing workflow activity, but record in sys_trigger update is not happening.



I have used BR as After Update and Condition as Follow Up Changes.



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


var scomTimer = retrieveTriggerRecord('Alert - Incident Followup - 1 min before');  
  if(scomTimer != 'none')  
  rescheduleNextAction(1,scomTimer);  

  function retrieveTriggerRecord(timer){  
  //Find the workflow context record  
  var grContext = new GlideRecord("wf_context");  
  grContext.addQuery('id',current.sys_id);  
grContext.query();  
  if(!grContext.next())  
return 'none';  
 
  //Find the Workflow Executing record  
  var grExecuting = new GlideRecord("wf_executing");  
  grExecuting.addQuery("context", grContext.sys_id);  
  grExecuting.addQuery("activity.name", timer);   // My Activity name in Current workflow
  grExecuting.addQuery("activity.activity_definition.name", 'Timer');  
  grExecuting.query();  
  if (!grExecuting.next())  
  return 'none';  


//Find the sys_trigger record  
  var grTrigger = new GlideRecord("sys_trigger");  
  grTrigger.addQuery("name", 'WFTimer' + grExecuting.sys_id.toString());  
  grTrigger.query();  
  if (grTrigger.next())  
  return grTrigger;  
  else  
  return 'none';  
}  

  function rescheduleNextAction(minutes,trigger){  
  var newTime = new GlideDateTime(current.follow_up);   // follow up field in Incident form
newTime.addSeconds(-(minutes*60));
  //gs.info(newTime);
trigger.next_action = newTime.toString();  
trigger.update();
}  


})(current, previous);



Regards,


Shravani


Ian Kirby1
Giga Expert

You are able to reset a workflow. For example, resetting an SLA workflow for a planned task when the due date of the task changes.



Example:


priority5DueDateChanged();



function priority5DueDateChanged() {


    // Fire incident.due_date.changed event


    gs.eventQueue("incident.due_date.changed", current, gs.getUserID(), gs.getUserName());


   


    // Find any active P5 SLAs for this incident


    var sla = new GlideRecord('task_sla');


    sla.addQuery('task', current.sys_id); // sys_id of incident


    sla.addQuery('sla', 'a2be2291f136b080e4ec1c5d6333a366'); // Priority 5


    sla.addQuery('stage', 'in_progress');


    sla.addOrCondition('stage', 'paused');


    sla.query();


   


    if (sla.next()) {


            sla.planned_end_time = current.due_date;


            sla.update();


   


            var activeWorkflows = new Workflow().getRunningFlows(sla);


   


            while (activeWorkflows.next()) {


                var wf_sys_id = activeWorkflows.sys_id;


                var wf_name = activeWorkflows.name;


   


                if (wf_name.indexOf('Priority 5 SLA workflow') != -1) {


                    var wf_id = GlideRecord("wf_workflow");


                    wf_id.addQuery("name", wf_name);


                    wf_id.query();


   


                    if ( wf_id.next() ) {


                        var w = new Workflow();


                        var context = new GlideRecord("wf_context");


                        context.addQuery('sys_id', wf_sys_id);


                        context.query();


   


                        if (context.next()) {


                            w.cancelContext(context);


                        }


   


                        var vars = {endTime:"",realStartTime:"",retroactiveSecsLeft:0};


                        vars.endTime = sla.planned_end_time.getDisplayValue();


                        vars.realStartTime = sla.start_time.getDisplayValue();


                        vars.retroactiveSecsLeft = 0;


   


                        var new_context = w.startFlow( wf_id.sys_id, sla, current.operation(), vars);


                  }


              }


          }


  }


}