entities/wfobjs.py
changeset 0 b97547f5f1fa
child 1154 9b23a6836c32
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 """workflow definition and history related entities
       
     2 
       
     3 :organization: Logilab
       
     4 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     6 """
       
     7 __docformat__ = "restructuredtext en"
       
     8 
       
     9 from cubicweb.entities import AnyEntity, fetch_config
       
    10 
       
    11 
       
    12 class Transition(AnyEntity):
       
    13     """customized class for Transition entities
       
    14 
       
    15     provides a specific may_be_passed method to check if the relation may be
       
    16     passed by the logged user
       
    17     """
       
    18     id = 'Transition'
       
    19     fetch_attrs, fetch_order = fetch_config(['name'])
       
    20     __rtags__ = {('destination_state',  '*', 'subject'):  'create',
       
    21                  ('allowed_transition', '*', 'object') :  'create',
       
    22                   }
       
    23                  
       
    24     def may_be_passed(self, eid, stateeid):
       
    25         """return true if the logged user may pass this transition
       
    26 
       
    27         `eid` is the eid of the object on which we may pass the transition
       
    28         `stateeid` is the eid of the current object'state XXX unused
       
    29         """
       
    30         user = self.req.user
       
    31         # check user is at least in one of the required groups if any
       
    32         groups = frozenset(g.name for g in self.require_group)
       
    33         if groups:
       
    34             matches = user.matching_groups(groups)
       
    35             if matches:
       
    36                 return matches
       
    37             if 'owners' in groups and user.owns(eid):
       
    38                 return True
       
    39         # check one of the rql expression conditions matches if any
       
    40         if self.condition:
       
    41             for rqlexpr in self.condition:
       
    42                 if rqlexpr.check_expression(self.req, eid):
       
    43                     return True
       
    44         if self.condition or groups:
       
    45             return False
       
    46         return True
       
    47 
       
    48     def destination(self):
       
    49         return self.destination_state[0]
       
    50     
       
    51     def after_deletion_path(self):
       
    52         """return (path, parameters) which should be used as redirect
       
    53         information when this entity is being deleted
       
    54         """
       
    55         if self.transition_of:
       
    56             return self.transition_of[0].rest_path(), {'vid': 'workflow'}
       
    57         return super(Transition, self).after_deletion_path()
       
    58 
       
    59     
       
    60 class State(AnyEntity):
       
    61     """customized class for State entities
       
    62 
       
    63     provides a specific transitions method returning transitions that may be
       
    64     passed by the current user for the given entity
       
    65     """
       
    66     id = 'State'
       
    67     fetch_attrs, fetch_order = fetch_config(['name'])
       
    68     rest_attr = 'eid'
       
    69     
       
    70     __rtags__ = {'destination_state' : 'create',
       
    71                  'allowed_transition' : 'create'
       
    72                  }
       
    73     
       
    74     def transitions(self, entity, desteid=None):
       
    75         rql = ('Any T,N,DS where S allowed_transition T, S eid %(x)s, '
       
    76                'T name N, T destination_state DS, '
       
    77                'T transition_of ET, ET name %(et)s')
       
    78         if desteid is not None:
       
    79             rql += ', DS eid %(ds)s'
       
    80         rset = self.req.execute(rql, {'x': self.eid, 'et': str(entity.e_schema),
       
    81                                          'ds': desteid}, 'x')
       
    82         for tr in rset.entities():
       
    83             if tr.may_be_passed(entity.eid, self.eid):
       
    84                 yield tr
       
    85                 
       
    86     def after_deletion_path(self):
       
    87         """return (path, parameters) which should be used as redirect
       
    88         information when this entity is being deleted
       
    89         """
       
    90         if self.state_of:
       
    91             return self.state_of[0].rest_path(), {'vid': 'workflow'}
       
    92         return super(State, self).after_deletion_path()
       
    93 
       
    94     
       
    95 class TrInfo(AnyEntity):
       
    96     """customized class for Transition information entities
       
    97     """
       
    98     id = 'TrInfo'
       
    99     fetch_attrs, fetch_order = fetch_config(['creation_date', 'comment'],
       
   100                                             pclass=None) # don't want modification_date
       
   101     @property
       
   102     def for_entity(self):
       
   103         return self.wf_info_for and self.wf_info_for[0]
       
   104     @property
       
   105     def previous_state(self):
       
   106         return self.from_state and self.from_state[0]
       
   107     
       
   108     @property
       
   109     def new_state(self):
       
   110         return self.to_state[0]
       
   111 
       
   112     def after_deletion_path(self):
       
   113         """return (path, parameters) which should be used as redirect
       
   114         information when this entity is being deleted
       
   115         """
       
   116         if self.for_entity:
       
   117             return self.for_entity.rest_path(), {}
       
   118         return 'view', {}