Skip to content

Workflow API

Eric Patrick edited this page Mar 29, 2021 · 15 revisions

The Workflow module handles the coordinate of activity in a system, executing of a flow chart of steps. Power users implement a flow chart as a DecisionTemplate, after which individual workflows can be created based on the template for specific work. Real-world examples of workflows implemented include:

  • Foreclosure timeline tracking used by Freddie Mac
  • Foreclosure management used by trustees (including generation of NOD/NOS, pub and post integrations, mailings, etc.)
  • Equity analysis for both senior and subordinate mortgages (including pulling AVMs, credit reports, and property inspection data)
  • Loan Modification analysis and execution (including servicing system integration to execute term changes)
  • Short sale processing
  • Bankruptcy processing
  • Debt collections (credit card, auto) processing

What Can a Workflow Do?

A workflow can orchestrate the executing anything QBO can do. When creating a workflow, many power users start with a flow chart representing their current workflows. Given a flow chart, a rule of thumb is:

  • Each flow chart is a "Decision Template"
  • Each shape on the flow chart is a "Step" in the workflow
  • Each line on the flow chart is a "Dependency" in the workflow

Workflow steps are powerful. Examples includes:

  • Creating a task: tasks are human-based steps, and cause users to be assigned to complete them
  • Generate a document: mail merge a document, and deliver the document to imaging, a print vendor, or a third party
  • Calculate a score: run an analysis model on a parent record
  • Send a mesasge: create a note, send an email, or SMS text message
  • Create a process: create a new processes
  • If/Then statement: evaluate data to arrive at a true or false condition, on which other steps can depend
  • Polling step: cause the workflow to wait for some data condition
  • Launch a workflow: one workflow can launch a child workflow, and wait for the child to complete
  • Advanced step: catch-all functionality to call any QBO method signature

Classes

Class Description
Decision Represents a single workflow as applied to a single parent object.
DecisionStep An instance of a step in a workflow as applied to a single parent object.
DecisionTemplate Template that defines the behavior of a Decision.
DecisionStepTemplate Template that defines the behavior of a DecisionStep.
DecisionDependency Defines a dependency relationship between 2 DecisionStepTemplate rows.
DecisionDelay Represents a delay or hold put on a single Decision (workflow).
DecisionDelayTemplate Defines the types of delays or holds that may be applied to a DecisionTemplate.

Decision Processing

Normally, simply saving a Decision will cause the workflow to be 'processed'. Technically, the Decision class includes a Inserted event handler that calls Decision/Process, which in turn will process a workflow.

The Decision/Process method queries the database to insert eligible steps, and for each step, either processes the step (if the step is defined as synchronous), or queues the step for processing (if the step is asynchronous). In both cases, ultimately the DecisionStep/Start method signature is being called.

Parameter Substitution

Parameter substitution patterns allow power users to data-drive method signatures. For example, the Attachment/CopyFile method expects two parameters: and ID and a FileObject. When designing the workflow you cannot know in advance the values to be passed, so instead you represent the values as XPath expressions wrapped in curly braces. For example:

Attachment/CopyFile?ID={//AttachmentID[1]}&FileObject=MailingVendorFTPSite
Contact/SCRASearch?SSN={//USSSN[1]}

The XPath expressions in the curly braces are evaluated against the Decision.Parent Summary statement, which essentially returns all data associated with an object.

If the data containing in the parent object's Summary method is insufficient, a custom query may be used to feed parameters instead. By checking the 'data from a query' checkbox, the UI changes, and you may specify a method signature to run prior to evaluating the Action to take.

In the example above, the query being run is Attachment/Search?InDecisionID={DecisionID}. The InDecisionID is a useful filter that limits search results to objects created by a Decision. Note that in this case parameter substitution is being used for the custom query! In this case, the parameters available are limited to the columns associated with the Decision table.

If a step uses a Query to feed parameters to an Action, the action is invoked for every row returned by the query. In the example above, this means that all attachments created by the workflow would be transmitted to the Mailing Vendor's FTP site.

Date Calcuations

Each workflow step can be dependent on zero or more predecessor steps, and each can be configured with an estimated duration. Normally:

EstimatedCompletion = ActualStart + EstimatedDuration

Each workflow step includes six dates:

  • EstimatedStart: the computer-determined start date of a step, determined as the completion date of the last predecessor to be completed
  • ProjectedStart: a human override of the estimated start
  • ActualStart: the date the step was actually started (DecisionStep/Start was called)
  • EstimatedCompletion: the computer-determined completion date of a step, based on a 'ReferenceDate'. If no ReferenceDate is defined, ActualStart is used.
  • Projected Completion: a human override of the EstimatedCompletion
  • Actual Completion: the date the step was actually completed (DecisionStep/Complete was called)

Note: reference date calculations do not occur until DecisionStep/Start is called. Thus, if you have asynchronous steps, they will initially have an estimated completion date based on the step's start date. Once the step's Start method has been called, the EstimatedCompletion date will be recalculated in relation to the reference date. This is because step completion dates are initially calculated in bulk in the data tier, but the reference date calculations rely on XPath expression evaluation done in the application tier.

Polling Delays

A Polling step can be used to cause the workflow to wait. Add a polling step, and in the if/then definition area, use:

Formatting:dateDiff(//ActualStart, today, d) >= 3

This XPath expression leverages QBO's Formatting extension's dateDiff function, where:

  • ActualStart is the start date of the polling step,
  • today is a string that QBO interprets to DateTime.Now, and
  • d specifies that we want the number of days difference between the two dates

Step Repeatability

Typically, a step in a workflow occurs once per workflow. This can be overridden, however, to handle different use cases:

  • Multiple: this option is used for workflow steps where a user may need to trigger a workflow step manually. For example, a workflow may include an "Interim Bill" task that occurs at a certain point of the workflow, and users are allowed to inject such a step whenever they deem it appropriate.

  • Ad-hoc: this option is used for workflow steps that only occur when a user chooses to add them manually. For example, a foreclosure workflow might have a Sale Adjournment step. One would not plan a sale adjournment for a standard workflow, but wish to allow a user to add them to a workflow when real-world situations dictate.

While a task can be added at any time to a record, it is often used to "bind" a task to a specific workflow within a record. This is where multiple or ad-hoc steps become useful.

Changing Templates with Existing Workflows

As workflow template evolve, power users will need to weigh the impact of changing existing workflow templates versus creating entirely new templates. Assume we have a simple workflow comprising the following steps:

Original Workflow Template New Workflow Template
* Referred to Vendor
* Important Step 1
* Unimportant Step 2
* Notification Step 3
* Case Closed*
* Vendor Paid
* Referred to Vendor
* Important Step 1
* Notification Step 3
* Notification Step 4
* Case Closed
* Vendor Paid

In short, we've decided that Unimportant Step 2 no longer needs to be tracked, but we wish to start tracking a Notification Step 4.

Further assume we have existing sample workflows based on this template:

Workflow 1
(closed)
Workflow 2
(recently opened)
Workflow 3
(in progress)
Workflow 4
(in progress)
* Referred to Vendor
* Important Step 1
* Unimportant Step 2
* Notification Step 3
* Case Closed
* Vendor Paid
* Referred to Vendor
* Important Step 1
* Referred to Vendor
* Important Step 1
* Unimportant Step 2
* Notification Step 3
* Referred to Vendor
* Important Step 1
* Unimportant Step 2
* Notification Step 3
* Case Closed

When adding a new step to a workflow template:

  • if an existing workflow is closed, calling Decision/Process will do nothing, so the new step will not be added to an existing closed workflow
  • if an existing workflow is open, but the new step's dependencies have not been met, the new step will not be added until it's dependencies have been met
  • if an existing workflow is open, and the new step's dependencies have been met, the new step will be added the next time Decision/Process is called

When deleting a step from a workflow template:

  • existing workflows that already have the step completed will retain the step
  • existing workflows that do not yet have the step will never get the step
  • existing workflows that already have the step, but the step is not yet completed, will retain the step, and the step must be manually completed

Thus, deleting Unimportant Step 2 and adding Notification Step 4 will affect the existing sample workflows as follows:

Workflow 1
(closed)
Workflow 2
(recently opened)
Workflow 3
(in progress)
Workflow 4
(in progress)
* Referred to Vendor
* Important Step 1
* Unimportant Step 2
* Notification Step 3
* Case Closed
* Vendor Paid

Unchanged: since it is closed.
* Referred to Vendor
* Important Step 1

Unchanged: it will never have the Unimportant Step 2 added, and it will have Notification Step 4 added after Notification Step 3 is complete.
* Referred to Vendor
* Important Step 1
* Unimportant Step 2
* Notification Step 3

Unchanged: Unimportant Step 2 has already been completed, and will be left alone. Notification Step 4 will be added when Notification Step 3 is completed.
* Referred to Vendor
* Important Step 1
* Unimportant Step 2
* Notification Step 3
* Notification Step 4
* Case Closed

Changed: Unimportant Step 2 has already been completed, and will be left alone. Notification Step 4 was added (by calling Decision/Process), and needs to be 'back filled', if appropriate.

In the Workflow 4 example, a business question arises: should Notification Step 4 be "back filled" or not? Note that the number of workflows affected by this question are limited:

  • Already closed workflows are not affected, so no back fill consideration needs to be made
  • Open workflows that have not yet progressed to the new step have no back fill consideration; the vendor will complete Notification Step 4 in the "normal course of business"
  • Thus, open workflows that have progressed "past" Notification Step 4 are subject to back fill consideration

There are three possible answers to the back fill question:

  • They do not need to be back-filled (don't make the vendor do the work): in this case, update the Notification Step 4 steps to be complete via a query
  • They must all be back-filled (vendor needs to do the work for in-process workflows): in this case, leave the Notification Step 4 alone, and it will appear in Smart Worklists, task lists, etc.
  • The answer depends on the individual workflow: in this case, instruct the vendor to use their "best judgement"

If the changes to the workflow template include many new steps, many deleted steps, or a significant change in dependencies between steps, the back fill question tends toward the "it depends" scenario. In such cases, consider creating a new workflow template and deprecating the old workflow template instead of tasking the vendor (or power user) to try to think through all the "it depends" business scenarios.

Tracking Stalled Steps

In some circumstances, improper configuration can result in 'stalled' decision. A stalled decision is one where:

  • There is one or more pending step(s) where all predecessors have been completed, and
  • There is no queued call to Decision/Process
  • All steps are complete, but the Decision has not progressed

These steps can be managed by:

  • View all stalled steps: Decision/DecisionStep.ashx/StalledSteps?Output=Xml
  • Requeue all stalled steps: Decision/DecisionStep.ashx/StalledStepsRequeue
  • View stalled decisions: Decision/DecisionStep.ashx/PendingDecisionList

Restarting a Decision

A restart can be performed on a decision whereby the user can choose which step they want the decision to restart at. A new Decision is created and all steps prior to and including the restart step get copied over to the new workflow. The current Decision gets cancelled and the decision status gets set to Restart. A message is created on the object represented by the Decision.Object/ObjectID indicating a restart has occurred.

A restart can be performed from the front-end or by calling this method signature:

Decision/Restart?ID={some DecisionID}

Front-end performed from:

  • Decision/Summary page options menu on the summary panel
  • DecisionStep/Search panel options menu

Parameters for performing a restart:

  • ID: DecisionID for the workflow that you are restarting
  • ActualStart: The start date being used for the restart
  • BodyText: The message content that will get added to the Decision.Object/ObjectID showing what was restarted
  • DecisionStepID: (optional) The DecisionStepID for the step you want to restart your workflow after. All prior steps will get copied over to the new workflow inclusive of the current step. If this is not passed in then none of the steps from the previous Decision are copied over to the new Decision.

Example:

Decision/Restart?ID={DecisionID}&DecisionStepID={//DecisionStepItem[DecisionStep='StepA']/DecisionStepID}&ActualStart={StartDate}&BodyText=Workflow Step Restart
Clone this wiki locally