Esempio n. 1
0
def DCWorkflowDefinition_executeTransition(self, ob, tdef=None, kwargs=None):
    '''
    Private method.
    Puts object in a new state.
    '''
    sci = None
    econtext = None
    moved_exc = None
    validation_exc = None

    # Figure out the old and new states.
    old_state = self._getWorkflowStateOf(ob, True)
    if tdef is None:
        new_state = self.initial_state
        if not new_state:
            # Do nothing if there is no initial state. We may want to create
            # workflows with no state at all, only for worklists.
            return
        former_status = {}
    else:
        new_state = tdef.new_state_id or old_state
        former_status = self._getStatusOf(ob)
    old_sdef = self.states[old_state]
    try:
        new_sdef = self.states[new_state]
    except KeyError:
        raise WorkflowException('Destination state undefined: ' + new_state)

    # Execute the "before" script.
    before_script_success = 1
    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:
            #LOG('_executeTransition', 0, "script = %s, sci = %s" % (repr(script), repr(sci)))
            script(sci)  # May throw an exception.
        except ValidationFailed, validation_exc:
            before_script_success = 0
            before_script_error_message = deepcopy(validation_exc.msg)
            validation_exc_traceback = sys.exc_traceback
        except ObjectMoved, moved_exc:
            ob = moved_exc.getNewObject()
Esempio n. 2
0
def _executeMetaTransition(self, ob, new_state_id):
    """
  Allow jumping from state to another without triggering any hooks. 
  Must be used only under certain conditions.
  """
    sci = None
    econtext = None
    tdef = None
    kwargs = None
    # Figure out the old and new states.
    old_sdef = self._getWorkflowStateOf(ob)
    if old_sdef is None:
        old_state = self._getWorkflowStateOf(ob, id_only=True)
    else:
        old_state = old_sdef.getId()
    if old_state == new_state_id:
        # Object is already in expected state
        return
    former_status = self._getStatusOf(ob)

    new_sdef = self.states.get(new_state_id, None)
    if new_sdef is None:
        raise WorkflowException, ('Destination state undefined: ' +
                                  new_state_id)

    # Update variables.
    state_values = new_sdef.var_values
    if state_values is None:
        state_values = {}

    tdef_exprs = {}
    status = {}
    for id, vdef in self.variables.items():
        if not vdef.for_status:
            continue
        expr = None
        if state_values.has_key(id):
            value = state_values[id]
        elif tdef_exprs.has_key(id):
            expr = tdef_exprs[id]
        elif not vdef.update_always and former_status.has_key(id):
            # 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

    status['comment'] = 'Jump from %r to %r' % (
        old_state,
        new_state_id,
    )
    status[self.state_var] = new_state_id
    tool = aq_parent(aq_inner(self))
    tool.setStatusOf(self.id, ob, status)

    # Update role to permission assignments.
    self.updateRoleMappingsFor(ob)
    return new_sdef
Esempio n. 3
0
def DCWorkflowDefinition_getWorklistVariableMatchDict(self,
                                                      info,
                                                      check_guard=True):
    """
    Return a dict which has an entry per worklist definition
    (worklist id as key) and which value is a dict composed of
    variable matches.
  """
    if not self.worklists:
        return None

    portal = self.getPortalObject()

    def getPortalTypeListForWorkflow(workflow_id):
        workflow_tool = portal.portal_workflow
        result = []
        append = result.append
        for type_info in workflow_tool._listTypeInfo():
            portal_type = type_info.id
            if workflow_id in workflow_tool.getChainFor(portal_type):
                append(portal_type)
        return result

    _getPortalTypeListForWorkflow = CachingMethod(
        getPortalTypeListForWorkflow,
        id='_getPortalTypeListForWorkflow',
        cache_factory='erp5_ui_long')
    portal_type_list = _getPortalTypeListForWorkflow(self.id)
    if not portal_type_list:
        return None
    variable_match_dict = {}
    security_manager = getSecurityManager()
    workflow_id = self.id
    workflow_title = self.title
    for worklist_id, worklist_definition in self.worklists.items():
        action_box_name = worklist_definition.actbox_name
        guard = worklist_definition.guard
        if action_box_name:
            variable_match = {}
            for key in worklist_definition.getVarMatchKeys():
                var = worklist_definition.getVarMatch(key)
                if isinstance(var, Expression):
                    evaluated_value = var(
                        createExprContext(
                            StateChangeInfo(portal,
                                            self,
                                            kwargs=info.__dict__.copy())))
                    if isinstance(evaluated_value, (str, int, long)):
                        evaluated_value = [str(evaluated_value)]
                else:
                    evaluated_value = [x % info for x in var]
                variable_match[key] = evaluated_value
            if 'portal_type' in variable_match and len(
                    variable_match['portal_type']):
                portal_type_intersection = set(variable_match['portal_type'])\
                    .intersection(portal_type_list)
                # in case the current workflow is not associated with portal_types
                # defined on the worklist, don't display the worklist for this
                # portal_type.
                variable_match['portal_type'] = list(portal_type_intersection)
            variable_match.setdefault('portal_type', portal_type_list)

            if len(variable_match.get('portal_type', [])) == 0:
                continue
            is_permitted_worklist = 0
            if guard is None:
                is_permitted_worklist = 1
            elif (not check_guard) or \
                Guard_checkWithoutRoles(guard, security_manager, self, portal):
                is_permitted_worklist = 1
                variable_match[SECURITY_PARAMETER_ID] = guard.roles

            if is_permitted_worklist:
                format_data = TemplateDict()
                format_data._push(info)
                variable_match.setdefault(SECURITY_PARAMETER_ID, ())
                format_data._push(dict((k, ('&%s:list=' % k).join(v)) for\
                                                   k, v in variable_match.iteritems()))
                variable_match[WORKLIST_METADATA_KEY] = {
                    'format_data': format_data,
                    'worklist_title': action_box_name,
                    'worklist_id': worklist_id,
                    'workflow_title': workflow_title,
                    'workflow_id': workflow_id,
                    'action_box_url': worklist_definition.actbox_url,
                    'action_box_category': worklist_definition.actbox_category
                }
                variable_match_dict[worklist_id] = variable_match

    if len(variable_match_dict) == 0:
        return None
    return variable_match_dict
Esempio n. 4
0
 def _listGlobalActions(user=None, id=None, portal_path=None):
     portal = self._getPortalRoot()
     portal_url = portal.portal_url
     portal_url = portal_url()
     sm = getSecurityManager()
     res = []
     fmt_data = None
     # We want to display some actions depending on the current date
     # So, we can now put this kind of expression : <= "%(now)s"
     # May be this patch should be moved to listFilteredActions in the future
     info.now = DateTime()
     for id, qdef in self.worklists.items():
         if qdef.actbox_name:
             guard = qdef.guard
             # Patch for ERP5 by JP Smets in order
             # to take into account the expression of the guard
             # and nothing else - ERP5Workflow definitely needed some day
             if guard is None or Guard_checkWithoutRoles(
                     guard, sm, self, portal):
                 dict = {}
                 # Patch for ERP5 by JP Smets in order
                 # to implement worklists and search of local roles
                 searchres_len = 0
                 var_match_keys = qdef.getVarMatchKeys()
                 if var_match_keys:
                     # Check the catalog for items in the worklist.
                     catalog = portal.portal_catalog
                     for k in var_match_keys:
                         v = qdef.getVarMatch(k)
                         if isinstance(v, Expression):
                             v_fmt = v(
                                 createExprContext(
                                     StateChangeInfo(
                                         portal,
                                         self,
                                         kwargs=info.__dict__.copy())))
                         else:
                             v_fmt = map(lambda x, info=info: x % info, v)
                         dict[k] = v_fmt
                     # Patch to automatically filter workflists per portal type
                     # so that the same state can be used for different
                     # worklists and they are not merged
                     if not dict.has_key('portal_type'):
                         dict['portal_type'] = portal_type_list
                     # Patch for ERP5 by JP Smets in order
                     # to implement worklists and search of local roles
                     # we do not take into account the guard here
                     if guard is not None and guard.roles:
                         dict['local_roles'] = guard.roles
                     # Patch to use ZSQLCatalog and get high speed
                     # LOG("PatchedDCWorkflowDefinition", 0, dict)
                     searchres_len = int(
                         apply(catalog.countResults, (), dict)[0][0])
                     if searchres_len == 0:
                         continue
                 if fmt_data is None:
                     fmt_data = TemplateDict()
                     fmt_data._push(info)
                 fmt_data._push({'count': searchres_len})
                 # Patch for ERP5 by JP Smets in order to
                 # filter per portal type more easily (ie. without
                 # hardcoding it all)
                 fmt_data._push({
                     'portal_type':
                     '&portal_type='.join(dict['portal_type'])
                 })
                 # Patch for ERP5 by JP Smets in order
                 # to implement worklists and search of local roles
                 if dict.has_key('local_roles'):
                     fmt_data._push({
                         'local_roles':
                         '&local_roles='.join(dict['local_roles'])
                     })
                 else:
                     fmt_data._push({'local_roles': ''})
                 res.append((
                     id,
                     {
                         'name':
                         qdef.actbox_name % fmt_data,
                         'url':
                         '%s/%s' % (portal_url, qdef.actbox_url % fmt_data),
                         'worklist_id':
                         id,
                         'workflow_title':
                         self.title,
                         'workflow_id':
                         self.id,
                         'permissions': (),  # Predetermined.
                         'category':
                         qdef.actbox_category
                     }))
                 fmt_data._pop()
     res.sort()
     return map((lambda (id, val): val), res)
Esempio n. 5
0
        elif tdef_exprs.has_key(id):
            expr = tdef_exprs[id]
        elif not vdef.update_always and former_status.has_key(id):
            # 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

    # Do not proceed in case of failure of before script
    if not before_script_success:
        status[self.state_var] = old_state  # Remain in state
        tool = aq_parent(aq_inner(self))
        tool.setStatusOf(self.id, ob, status)
        sci = StateChangeInfo(ob, self, status, tdef, old_sdef, new_sdef,
                              kwargs)
        # put the error message in the workflow history
        sci.setWorkflowVariable(error_message=before_script_error_message)
        if validation_exc:
            # reraise validation failed exception