Commit d8d4a723 authored by Nicolas Delaby's avatar Nicolas Delaby

Add extra method on DCWorkflow _executeMetaTransition to jump from workflow state to another.

This will ignore transitions and Scripts.

This meta_transition will be used to migrate documents from portal_type to another.
Because we can not expect that associated workflows will be identical.
The best we can do is pushing the new document to same state of previous
document if exists and this no matter id of workflows.

This feature will be also used by SynchronisationTool to synchronise workflows status.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@40958 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent a69f6d09
......@@ -425,6 +425,71 @@ def DCWorkflowDefinition_executeTransition(self, ob, tdef=None, kwargs=None):
DCWorkflowDefinition._executeTransition = DCWorkflowDefinition_executeTransition
from Products.DCWorkflow.utils import modifyRolesForPermission
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)
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
DCWorkflowDefinition._executeMetaTransition = _executeMetaTransition
def DCWorkflowDefinition_wrapWorkflowMethod(self, ob, method_id, func, args, kw):
'''
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
......@@ -851,3 +852,43 @@ except ImportError:
# We're on CMF 2, where WorkflowMethod has been removed from CMFCore
#WorkflowCore.WorkflowMethod = WorkflowMethod
WorkflowCore.WorkflowAction = WorkflowMethod
def _jumpToStateFor(self, ob, state_id, wf_id=None, *args, **kw):
"""Inspired from doActionFor.
This is public method to allow passing meta transition (Jump form
any state to another in same workflow)
"""
from Products.ERP5.InteractionWorkflow import InteractionWorkflowDefinition
workflow_list = self.getWorkflowsFor(ob)
if wf_id is None:
if not workflow_list:
raise WorkflowException('No workflows found.')
found = False
for workflow in workflow_list:
if not isinstance(workflow, InteractionWorkflowDefinition) and\
state_id in workflow.states._mapping:
found = True
break
if not found:
raise WorkflowException('No workflow provides the destination state %r'\
% state_id)
else:
workflow = self.getWorkflowById(wf_id)
if workflow is None:
raise WorkflowException('Requested workflow definition not found.')
workflow._executeMetaTransition(ob, state_id)
def _isJumpToStatePossibleFor(self, ob, state_id, wf_id=None):
"""Test if given state_id is available for ob
in at least one associated workflow
"""
from Products.ERP5.InteractionWorkflow import InteractionWorkflowDefinition
for workflow in (wf_id and (self[wf_id],) or self.getWorkflowsFor(ob)):
if not isinstance(workflow, InteractionWorkflowDefinition) and\
state_id in workflow.states._mapping:
return True
return False
WorkflowTool._jumpToStateFor = _jumpToStateFor
WorkflowTool._isJumpToStatePossibleFor = _isJumpToStatePossibleFor
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment