def canDoActionFor(self, ob, action, wf_id=None, guard_kw={}): """ Check we can perform the given workflow action on 'ob'. """ if wf_id is None: workflow_list = self.getWorkflowsFor(ob) or () else: workflow = self.getWorkflowById(wf_id) if workflow: workflow_list = (workflow, ) else: workflow_list = () for workflow in workflow_list: state_definition = workflow._getWorkflowStateOf(ob) if state_definition is not None: if action in state_definition.transitions: transition_definition = workflow.transitions.get(action, None) if transition_definition is not None and \ transition_definition.trigger_type == TRIGGER_USER_ACTION: return workflow._checkTransitionGuard( transition_definition, ob, **guard_kw) raise WorkflowException( _(u"No workflow provides the '${action_id}' action.", mapping={'action_id': action}))
def doActionFor(self, ob, action, comment='', **kw): ''' Allows the user to request a workflow action. This method must perform its own security checks. ''' kw['comment'] = comment sdef = self._getWorkflowStateOf(ob) if sdef is None: raise WorkflowException(_(u'Object is in an undefined state.')) if action not in sdef.transitions: raise Unauthorized(action) tdef = self.transitions.get(action, None) if tdef is None or tdef.trigger_type != TRIGGER_USER_ACTION: msg = _(u"Transition '${action_id}' is not triggered by a user " u"action.", mapping={'action_id': action}) raise WorkflowException(msg) if not self._checkTransitionGuard(tdef, ob, **kw): raise Unauthorized(action) self._changeStateOf(ob, tdef, kw)
def _executeTransition(self, ob, tdef=None, kwargs=None): ''' Private method. Puts object in a new state. ''' sci = None econtext = None moved_exc = None # Figure out the old and new states. old_sdef = self._getWorkflowStateOf(ob) old_state = old_sdef.getId() if tdef is None: new_state = self.initial_state former_status = {} else: new_state = tdef.new_state_id if not new_state: # Stay in same state. new_state = old_state former_status = self._getStatusOf(ob) new_sdef = self.states.get(new_state, None) if new_sdef is None: msg = _(u'Destination state undefined: ${state_id}', mapping={'state_id': new_state}) raise WorkflowException(msg) # Fire "before" event notify( BeforeTransitionEvent(ob, self, old_sdef, new_sdef, tdef, former_status, kwargs)) # Execute the "before" script. if tdef is not None and tdef.script_name: script = self.scripts[tdef.script_name] # Pass lots of info to the script in a single parameter. sci = StateChangeInfo(ob, self, former_status, tdef, old_sdef, new_sdef, kwargs) try: script(sci) # May throw an exception. except ObjectMoved, moved_exc: ob = moved_exc.getNewObject()
def _executeTransition(self, ob, tdef=None, kwargs=None): ''' Private method. Puts object in a new state. ''' sci = None econtext = None moved_exc = None # Figure out the old and new states. old_sdef = self._getWorkflowStateOf(ob) old_state = old_sdef.getId() if tdef is None: new_state = self.initial_state former_status = {} else: new_state = tdef.new_state_id if not new_state: # Stay in same state. new_state = old_state former_status = self._getStatusOf(ob) new_sdef = self.states.get(new_state, None) if new_sdef is None: msg = _(u'Destination state undefined: ${state_id}', mapping={'state_id': new_state}) raise WorkflowException(msg) # Fire "before" event notify(BeforeTransitionEvent(ob, self, old_sdef, new_sdef, tdef, former_status, kwargs)) # Execute the "before" script. if tdef is not None and tdef.script_name: script = self.scripts[tdef.script_name] # Pass lots of info to the script in a single parameter. sci = StateChangeInfo( ob, self, former_status, tdef, old_sdef, new_sdef, kwargs) try: script(sci) # May throw an exception. except ObjectMoved, moved_exc: ob = moved_exc.getNewObject()
def canDoActionFor(self, ob, action, wf_id=None, guard_kw={}): """ Check we can perform the given workflow action on 'ob'. """ if wf_id is None: workflow_list = self.getWorkflowsFor(ob) or () else: workflow = self.getWorkflowById(wf_id) if workflow: workflow_list = (workflow,) else: workflow_list = () for workflow in workflow_list: state_definition = workflow._getWorkflowStateOf(ob) if state_definition is not None: if action in state_definition.transitions: transition_definition = workflow.transitions.get(action, None) if transition_definition is not None and transition_definition.trigger_type == TRIGGER_USER_ACTION: return workflow._checkTransitionGuard(transition_definition, ob, **guard_kw) raise WorkflowException(_(u"No workflow provides the '${action_id}' action.", mapping={"action_id": action}))
def _executeTransition(self, ob, tdef=None, kwargs=None): ''' Private method. Puts object in a new state. ''' sci = None econtext = None moved_exc = None # Figure out the old and new states. old_sdef = self._getWorkflowStateOf(ob) old_state = old_sdef.getId() if tdef is None: new_state = self.initial_state former_status = {} else: new_state = tdef.new_state_id if not new_state: # Stay in same state. new_state = old_state former_status = self._getStatusOf(ob) new_sdef = self.states.get(new_state, None) if new_sdef is None: msg = _(u'Destination state undefined: ${state_id}', mapping={'state_id': new_state}) raise WorkflowException(msg) # Fire "before" event notify(BeforeTransitionEvent(ob, self, old_sdef, new_sdef, tdef, former_status, kwargs)) # Execute the "before" script. if tdef is not None and tdef.script_name: script = self.scripts[tdef.script_name] # Pass lots of info to the script in a single parameter. sci = StateChangeInfo( ob, self, former_status, tdef, old_sdef, new_sdef, kwargs) try: script(sci) # May throw an exception. except ObjectMoved as moved_exc: ob = moved_exc.getNewObject() # Re-raise after transition # Update variables. state_values = new_sdef.var_values if state_values is None: state_values = {} tdef_exprs = None if tdef is not None: tdef_exprs = tdef.var_exprs if tdef_exprs is None: tdef_exprs = {} status = {} for id, vdef in self.variables.items(): if not vdef.for_status: continue expr = None if id in state_values: value = state_values[id] elif id in tdef_exprs: expr = tdef_exprs[id] elif not vdef.update_always and id in former_status: # Preserve former value value = former_status[id] else: if vdef.default_expr is not None: expr = vdef.default_expr else: value = vdef.default_value if expr is not None: # Evaluate an expression. if econtext is None: # Lazily create the expression context. if sci is None: sci = StateChangeInfo( ob, self, former_status, tdef, old_sdef, new_sdef, kwargs) econtext = createExprContext(sci) value = expr(econtext) status[id] = value # Update state. status[self.state_var] = new_state tool = aq_parent(aq_inner(self)) tool.setStatusOf(self.id, ob, status) # Update role to permission assignments. self.updateRoleMappingsFor(ob) # Execute the "after" script. if tdef is not None and tdef.after_script_name: script = self.scripts[tdef.after_script_name] # Pass lots of info to the script in a single parameter. sci = StateChangeInfo( ob, self, status, tdef, old_sdef, new_sdef, kwargs) script(sci) # May throw an exception. # Fire "after" event notify(AfterTransitionEvent(ob, self, old_sdef, new_sdef, tdef, status, kwargs)) # Return the new state object. if moved_exc is not None: # Propagate the notification that the object has moved. raise moved_exc else: return new_sdef