Require several signers to promote an object

Description

Currently, it's not possible to require more than one signer to promote an object to its next state. This proposal describes how to require several signer approvals to promote an object.

Behaviour

Only the owner can add/replace/remove a signer. All signers, notified users and owners are notified when a signer is added/removed/replaced.

Signer addition

It's possible to add a signer if no user has approved the promotion.

The new signer must:

  • not already be a signer
  • be contributor
  • be in the object's group

Signer replacement

It's possible to replace a signer if no user has approved the promotion.

The new signer must:

  • not already be a signer
  • be contributor
  • be in the object's group

The previous signer is notified that he is not anymore a signer.

Signer deletion

It's possible to remove a signer if no user has approved the promotion.

The removed signer is notified that he is not anymore a signer.

Promotion

An object is promoted when all signers have approved the promotion.

Demotion

An object is demoted when one of the signer demotes the object. All signers will have to approve the object a second time to promote it.

Approval and delegation

Here be (tiny) dragons!

A delegated signer may approve a promotion. So there are some difficult cases:

  • both the delegatee and the delegator are signers
  • delegatee of several signers

Proposals:

  1. asks who is represented, one user at a time (radio buttons)
  2. asks who are represented (check buttons)
  3. represents all users

Proposal 3. seems easier to implement.

Interface

The "lifecycle" tab must be updated.

List of states, no approval

Current solution (revision [1655]):

Licecycle tab, revision [1655]

May be replaced with:

Lifecycle tab, mock-up

[R] will be replaced by a button, its tooltip is "Replace <user>". Its icon is not yet defined. When it is clicked, it redirects to the Replace user page (page of the current implementation).

[-] will be replaced by a button, its tooltip is "Remove <user>". Its icon is a "minus" symbol. When it is clicked, the signer is removed and it redirects to the lifecycle tab with an informative message. This button is not visible if there is only one signer (case official -> deprecated in the capture above)

The add button redirects to a "Add user" page.

All buttons are visible if:

  • no user has approved the promotion
  • the user is the owner

List of states, one approval

Lifecycle tab, mock-up, one signer has approved the promotion

A check icon is visible near users who have approved the promotion.

Updated messages/buttons

The text of the "Promote" button is replaced with "Approve the promotion" if there are at least two signers who have not yet approved the promotion.

The promote button is disabled if the user has already approved the promotion.

Default signers

The owner may become (by default) a first level signer so that he can easily warn when its work is ready. Its sponsor stays a 1st level signer.

Implementation

Database schema

A new model is required to track users who have approved a promotion.

Proposal 1 (implemented, see [1633]):

PromotionApproval?

  • fields:
    • plmobject (foreign key)
    • user (foreign key)
    • previous state
    • next state

-> useful if lifecycles evolve to a tree/graph of states

  • ctime -> to order users by approval time
  • end_time

-> maybe it will be useful

Migration: nothing is required (except the new model).

Controller

PLMObjectController

Removed methods:

set_signer
Replaced with replace_signer

New methods:

replace_signer(self, new_signer, link)
add_signer(self, new_signer, role)
remove_signer(self, signer, role)
can_edit_signers(self, level)
Returns True if (replace|add|remove)_signer can be called, i.e. the user is the owner and no signer has approved the promotion.
is_last_promoter(self)
True if the user is the last user to approve the promotion
has_approved_promotion(self, user)
True if user has approved the promotion
approve_promotion(self)
approves a promotion (creates the PromotionApproval? object), call promote if is_last_promoter returns true

Modified methods:

promote
If all signers have approved: it promotes the object and deletes all PromotionApproval?.
demote
Deletes all PromotionApproval?.
cancel
Deletes all PromotionApproval?.

Templates

Modified templates::

lifecycle.html

Attachments