hooks/workflow.py
brancholdstable
changeset 7074 e4580e5f0703
parent 6757 bc878ec35794
child 7294 2af1a4cecda5
equal deleted inserted replaced
6749:48f468f33704 7074:e4580e5f0703
   133         if wftr is None:
   133         if wftr is None:
   134             # inconsistency detected
   134             # inconsistency detected
   135             qname = role_name('to_state', 'subject')
   135             qname = role_name('to_state', 'subject')
   136             msg = session._("state doesn't belong to entity's current workflow")
   136             msg = session._("state doesn't belong to entity's current workflow")
   137             raise ValidationError(self.trinfo.eid, {'to_state': msg})
   137             raise ValidationError(self.trinfo.eid, {'to_state': msg})
   138         tostate = wftr.get_exit_point(forentity, trinfo['to_state'])
   138         tostate = wftr.get_exit_point(forentity, trinfo.cw_attr_cache['to_state'])
   139         if tostate is not None:
   139         if tostate is not None:
   140             # reached an exit point
   140             # reached an exit point
   141             msg = session._('exiting from subworkflow %s')
   141             msg = session._('exiting from subworkflow %s')
   142             msg %= session._(iworkflowable.current_workflow.name)
   142             msg %= session._(iworkflowable.current_workflow.name)
   143             session.transaction_data[(forentity.eid, 'subwfentrytr')] = True
   143             session.transaction_data[(forentity.eid, 'subwfentrytr')] = True
   183     def __call__(self):
   183     def __call__(self):
   184         session = self._cw
   184         session = self._cw
   185         entity = self.entity
   185         entity = self.entity
   186         # first retreive entity to which the state change apply
   186         # first retreive entity to which the state change apply
   187         try:
   187         try:
   188             foreid = entity['wf_info_for']
   188             foreid = entity.cw_attr_cache['wf_info_for']
   189         except KeyError:
   189         except KeyError:
   190             qname = role_name('wf_info_for', 'subject')
   190             qname = role_name('wf_info_for', 'subject')
   191             msg = session._('mandatory relation')
   191             msg = session._('mandatory relation')
   192             raise ValidationError(entity.eid, {qname: msg})
   192             raise ValidationError(entity.eid, {qname: msg})
   193         forentity = session.entity_from_eid(foreid)
   193         forentity = session.entity_from_eid(foreid)
       
   194         # see comment in the TrInfo entity definition
       
   195         entity.cw_edited['tr_count']=len(forentity.reverse_wf_info_for)
   194         iworkflowable = forentity.cw_adapt_to('IWorkflowable')
   196         iworkflowable = forentity.cw_adapt_to('IWorkflowable')
   195         # then check it has a workflow set, unless we're in the process of changing
   197         # then check it has a workflow set, unless we're in the process of changing
   196         # entity's workflow
   198         # entity's workflow
   197         if session.transaction_data.get((forentity.eid, 'customwf')):
   199         if session.transaction_data.get((forentity.eid, 'customwf')):
   198             wfeid = session.transaction_data[(forentity.eid, 'customwf')]
   200             wfeid = session.transaction_data[(forentity.eid, 'customwf')]
   211         swtr = session.transaction_data.pop((forentity.eid, 'subwfentrytr'), None)
   213         swtr = session.transaction_data.pop((forentity.eid, 'subwfentrytr'), None)
   212         cowpowers = (session.user.is_in_group('managers')
   214         cowpowers = (session.user.is_in_group('managers')
   213                      or not session.write_security)
   215                      or not session.write_security)
   214         # no investigate the requested state change...
   216         # no investigate the requested state change...
   215         try:
   217         try:
   216             treid = entity['by_transition']
   218             treid = entity.cw_attr_cache['by_transition']
   217         except KeyError:
   219         except KeyError:
   218             # no transition set, check user is a manager and destination state
   220             # no transition set, check user is a manager and destination state
   219             # is specified (and valid)
   221             # is specified (and valid)
   220             if not cowpowers:
   222             if not cowpowers:
   221                 qname = role_name('by_transition', 'subject')
   223                 qname = role_name('by_transition', 'subject')
   222                 msg = session._('mandatory relation')
   224                 msg = session._('mandatory relation')
   223                 raise ValidationError(entity.eid, {qname: msg})
   225                 raise ValidationError(entity.eid, {qname: msg})
   224             deststateeid = entity.get('to_state')
   226             deststateeid = entity.cw_attr_cache.get('to_state')
   225             if not deststateeid:
   227             if not deststateeid:
   226                 qname = role_name('by_transition', 'subject')
   228                 qname = role_name('by_transition', 'subject')
   227                 msg = session._('mandatory relation')
   229                 msg = session._('mandatory relation')
   228                 raise ValidationError(entity.eid, {qname: msg})
   230                 raise ValidationError(entity.eid, {qname: msg})
   229             deststate = wf.state_by_eid(deststateeid)
   231             deststate = wf.state_by_eid(deststateeid)
   245                         'tr': session._(tr.name), 'st': session._(fromstate.name)}
   247                         'tr': session._(tr.name), 'st': session._(fromstate.name)}
   246                     raise ValidationError(entity.eid, {qname: msg})
   248                     raise ValidationError(entity.eid, {qname: msg})
   247                 if not tr.may_be_fired(foreid):
   249                 if not tr.may_be_fired(foreid):
   248                     msg = session._("transition may not be fired")
   250                     msg = session._("transition may not be fired")
   249                     raise ValidationError(entity.eid, {qname: msg})
   251                     raise ValidationError(entity.eid, {qname: msg})
   250             if entity.get('to_state'):
   252             deststateeid = entity.cw_attr_cache.get('to_state')
   251                 deststateeid = entity['to_state']
   253             if deststateeid is not None:
   252                 if not cowpowers and deststateeid != tr.destination(forentity).eid:
   254                 if not cowpowers and deststateeid != tr.destination(forentity).eid:
   253                     qname = role_name('by_transition', 'subject')
   255                     qname = role_name('by_transition', 'subject')
   254                     msg = session._("transition isn't allowed")
   256                     msg = session._("transition isn't allowed")
   255                     raise ValidationError(entity.eid, {qname: msg})
   257                     raise ValidationError(entity.eid, {qname: msg})
   256                 if swtr is None:
   258                 if swtr is None:
   260                         msg = session._("state doesn't belong to entity's workflow")
   262                         msg = session._("state doesn't belong to entity's workflow")
   261                         raise ValidationError(entity.eid, {qname: msg})
   263                         raise ValidationError(entity.eid, {qname: msg})
   262             else:
   264             else:
   263                 deststateeid = tr.destination(forentity).eid
   265                 deststateeid = tr.destination(forentity).eid
   264         # everything is ok, add missing information on the trinfo entity
   266         # everything is ok, add missing information on the trinfo entity
   265         entity['from_state'] = fromstate.eid
   267         entity.cw_edited['from_state'] = fromstate.eid
   266         entity['to_state'] = deststateeid
   268         entity.cw_edited['to_state'] = deststateeid
   267         nocheck = session.transaction_data.setdefault('skip-security', set())
   269         nocheck = session.transaction_data.setdefault('skip-security', set())
   268         nocheck.add((entity.eid, 'from_state', fromstate.eid))
   270         nocheck.add((entity.eid, 'from_state', fromstate.eid))
   269         nocheck.add((entity.eid, 'to_state', deststateeid))
   271         nocheck.add((entity.eid, 'to_state', deststateeid))
   270         _FireAutotransitionOp(session, entity=forentity)
   272         _FireAutotransitionOp(session, entity=forentity)
   271 
   273 
   276     __select__ = WorkflowHook.__select__ & is_instance('TrInfo')
   278     __select__ = WorkflowHook.__select__ & is_instance('TrInfo')
   277     events = ('after_add_entity',)
   279     events = ('after_add_entity',)
   278 
   280 
   279     def __call__(self):
   281     def __call__(self):
   280         trinfo = self.entity
   282         trinfo = self.entity
   281         _change_state(self._cw, trinfo['wf_info_for'],
   283         rcache = trinfo.cw_attr_cache
   282                       trinfo['from_state'], trinfo['to_state'])
   284         _change_state(self._cw, rcache['wf_info_for'], rcache['from_state'],
   283         forentity = self._cw.entity_from_eid(trinfo['wf_info_for'])
   285                       rcache['to_state'])
       
   286         forentity = self._cw.entity_from_eid(rcache['wf_info_for'])
   284         iworkflowable = forentity.cw_adapt_to('IWorkflowable')
   287         iworkflowable = forentity.cw_adapt_to('IWorkflowable')
   285         assert iworkflowable.current_state.eid == trinfo['to_state']
   288         assert iworkflowable.current_state.eid == rcache['to_state']
   286         if iworkflowable.main_workflow.eid != iworkflowable.current_workflow.eid:
   289         if iworkflowable.main_workflow.eid != iworkflowable.current_workflow.eid:
   287             _SubWorkflowExitOp(self._cw, forentity=forentity, trinfo=trinfo)
   290             _SubWorkflowExitOp(self._cw, forentity=forentity, trinfo=trinfo)
   288 
   291 
   289 
   292 
   290 class CheckInStateChangeAllowed(WorkflowHook):
   293 class CheckInStateChangeAllowed(WorkflowHook):