Wait action during process running, how to update the timeout attribute to another

Hi,

I plan to use the Wait action in workflow, set the default Timeout to 60 mins; when someone click on 'Pause' button, Timeout countdown would pause, and resume when click on 'Resume' button, or end the Wait process directly when someone click on the 'End' button. 

How can I achieve this?

Solution

Qiuyan -

Great question! It's not obvious how to do this, but it is very possible!

  1. Create an entity with the fields of ProcessId and TimeRemaning (as an integer) and WaitStarted (as DateTime) and IsEndRequested and IsPauseRequested (both as Boolean) (let's call it ProcessWait) and WaitActivityId (as ActivityId). Process and Activity can be referenced from System to get their Identifier types. You will also want an ID for whatever record this process is dealing with (so if you are working on a Case, have a CaseId in there).
  2. In your process flow, add an automated activity right before the Wait. In this activity, look up ProcessWait where ProcessWait.ProcessId = ProcessId (the ID of the currently running process). If none is found, create one where ProcessWait.ProcessId = ProcessId, ProcessWait.TimeRemaining = 360 and ProcessWait.WaitStarted as CurrDateTime() and ProcessWait.IsEndRequested and ProcessWait.IsPauseRequested = False.Also set the Record Id (in our example, CaseId) to whatever the record Id is. If one is found, update it with ProcessWait.WaitStarted = CurrDateTime().
  3. For the "Timeout" value of the Wait, set its value to AddSeconds(CurrDateTime(), GetProcessWait(ProcessId).ProcessWait.TimeRemaining).
  4. Right-click the Wait, add an "On Ready". In the OnReady, do a query for ProcessWait where ProcessWait.ProcessId = ProcessId. ForEach over that query result, set ProcessWait.ActivityId = ActivityId and update the record.
  5. Right-click the Wait, add an "On Close". In the OnClose, do a query for ProcessWait where ProcessWait.ProcessId = ProcessId. ForEach over that query result, delete each found ProcessWait record.
  6. After the Wait, add an If called "WaitOutcome" with three paths ("Expired", "Ended", and "Paused"). Inside the If, check the Wait's Expired property. If it's true, go to the "Expired" exit. If false, look up the ProcessWait where ProcessWait.ActivityId = the ActivityId property from the wait. If that record's "IsEndRequested" value = True, exit to the "Ended" path, if the "IsPaused" = True, exit to the "Paused" path, if neither is true, throw and Exception (this should NEVER happen).
  7. On the "Ended" path, do whatever you need to do when the 60 minutes are up.
  8. On the "Ended" path, do whatever you need to do when someone "ends" the timer.
  9. On the "Paused" path, go to another Wait, where the "Closed On" is set to Update ProcessWait where ProcessId = ProcessId, and IsPaused = False.
  10. In your "End" action, query ProcessWait, where that "Record Id" is equal to the record id (say, ProcessWait.CaseId = CaseId), ForEach over the query results, set ProcessWait.IsEndRequested = True, and update the ProcessWait record.
  11. In your "Pause" action, query ProcessWait, where that "Record Id" is equal to the record id (say, ProcessWait.CaseId = CaseId), ForEach over the query results, set ProcessWait.IsPaused = True, and update the ProcessWait record.
  12. In your "Resume" action, query ProcessWait, where that "Record Id" is equal to the record id (say, ProcessWait.CaseId = CaseId), ForEach over the query results, set ProcessWait.IsPaused = False, and update the ProcessWait record.

That should be the whole thing from top to bottom.

J.Ja

Solution