After reading the Introduction to Plone workflows I started to think about how to implement workflows in Lino.

There would be a new lino.models.Rule model and corresponding tables (Rules, RulesByActor,…). A Rule represents a possibility to get permission to execute a given action of a given actor. The model would have the following fields:

  • actor (CharField) : the actor
  • action (CharField) : the action
  • state (CharField,blank=True) with state_choices
  • groups (CharField,blank=True) : a space-separated list of required user groups (same meaning as lino.core.actors.Actor.required_user_groups)
  • user_level : required user level lino.core.actors.Actor.required_user_level .

It is a “system” model (defined in lino.models). If ever it turns out that we need a hook to select between different implementations for defining rules, we could move it to a separate module lino.modlib.workflows.

lino.core.actors.Actor would get a new class variable state_field which, if not None, would be the name of a field which must be defined on the Actor’s model and which must have a list of choices (either a hard-coded choicelist or a by being a ForeignKey). Only actors with a state_field can have Rules.

lino.core.actions.Action would get a new attribute ruled, a boolean that says whether or not permission on this action is governed by Rules or not. If an action is not ruled, Lino will not consult the Rules table.

I could write an action decorator to quickly create actions without the need for a special Action subclass:

def cancel(self,obj,ar):
    ar.confirm(_("Are you sure?"))
    self.sent = None
    return RequestStatus.new

(This would add a “Cancel” button for some users to cancel a failed CBSS request.)

CBSS connection

Continued to write live tests in the test suite lino.modlib.cbss.tests. Startet first retrieveTIGroups requests. Continued with error handling.