Approval overrides and approvers

Introduction

For the purposes of this documentation, organisations and positions (both types of hierarchy items) are functionally the same.

Every approval workflow has a default assignment, which makes it available to applicants who match a hierarchy item through one of their job assignments, or are a member of an audience.

The default assignment also defines who the approvers are for each approval level in every approval stage of a workflow. Because there was a need to provide the same workflow to many different hierarchy items or audiences, but sometimes with different approvers and workflow managers, we also created assignment approval overrides. These are additional mod_approval instances within the workflow course container, each associated with its own hierarchy item or audience. Approvers may be defined for any approval level on an override assignment, or if they are not defined, they will be inherited from a higher assignment.

See also Application assignment resolution, which deals with how approval overrides are matched to users at application time.

Audience overrides

Audience overrides are simply other assignments that belong to an audience that is different from the default assignment.

If an audience assignment inherits approvers, it does so from the default assignment.

Hierarchical overrides

Hierarchical overrides are other assignments that belong to a hierarchy item.

Because of the nature of hierarchical frameworks, hierarchical overrides can go many levels deep, and inherit from their parents, as well as from the default assignment.

Hierarchical overrides do not need to match the default assignment in either framework type or relative depth.

Inheritance, and approver role assignment

When a workflow is in draft, creating an assignment for a hierarchy item just creates assignee records for the approvers defined in the assignment. Inherited approvers are not filled in.

When a workflow is published, the inherited approvers are filled in, first from any parent hierarchy item assignments, and then from the default assignment. Inherited approvers have their ancestor_id property set to the declared approver they inherit from.

Approvers are given a Workflow Approver role for every assignment where they can approve applications, either directly or via inheritance.

Changes to approvers (or the creation or deactivation of assignments) must necessarily cause adjustments to inherited approvers and their role assignments. Inherited approvers are deleted and recreated as necessary to maintain the desired role assignments.

Details of approver inheritance in overrides

In assignment overrides, no approvers are required at any level; all approvers may be inherited. However, any approvers explicitly defined at any of the levels override all of the inherited approvers for that level. We call these defined approvers 'direct approvers', as opposed to the descendent or 'inherited approvers' that come from either the default assignment, or a hierarchical ancestor assignment.

When resolving who the approvers should be for an assignment, we do it level by level. This is because you might get your level 2 approver from a different assignment than your level 1 approvers. For example, the default assignment might define the manager relationship as approver for level 1, but have individuals at level 2. Each override assignment might specify different individuals for level 2, but level 1 inherits.

The assignment_approver_level class can determine, for any assignment and approval level pair, a number of useful things about who the approvers are and which level they are inherited from (or would be inherited from, if there were no direct approvers). It can also deactivate all inherited approvers at the current level, and at any descendent levels. Inherited approvers can safely be deactivated and rebuilt, as they are system-managed objects. But as with all other workflow objects, do not delete inactive objects unless you are also deleting all of the applications that might reference them. 

On draft workflows, only direct approvers are created, and they are all inactive.

When the workflow is published, every existing direct approver is activated. From then on, when new approvers are added, they are activated immediately.

When a direct approver is activated, the following happens:

  1. The direct approver is marked as active in the database.
  2. The Workflow Approver role is assigned to them in the context of the assignment.
  3. Descendent approvers are created:
    1. Approver is saved in the database, with ancestor_id set to the direct approver's ID.
    2. Approver is activated:
      1. Marked as active.
      2. The workflow approver role is assigned to them in the context of the assignment override.
      3. There is no recursion, all descendants are created from the direct approver at step 3.

Troubleshooting

The system attempts to keep the approver inheritance tree in sync with reality, but if something goes wrong it can be useful to be able to rebuild the tree. Rebuilding removes all inherited approver records, and then rebuilds them from the bottom up. The script that does this can be found at dev/approval/rebuild_approvers_tree.php:

Rebuild an approval workflow approvers tree.

The approvers tree is an index of who the approvers are at each level, for each assignment.

Usage: php dev/approval/sf182/rebuild_approvers_tree.php [options]

Options:
  -h, --help            Show help screen
  -w, --workflow_id     Workflow ID to rebuild approvers tree for, required
  -a, --assignment_id   Assignment ID of the root of the tree, defaults to workflow's default assignment

Example:
    php dev/approval/sf182/rebuild_approvers_tree.php -w=<workflow_id> -a=<assignment_id>