introduce 'go back' transition: transition without destination state will go to the state we were coming from
--- a/entities/test/unittest_wfobjs.py Fri Feb 19 09:34:14 2010 +0100
+++ b/entities/test/unittest_wfobjs.py Fri Feb 19 09:36:26 2010 +0100
@@ -98,7 +98,7 @@
trs = list(user.possible_transitions())
self.assertEquals(len(trs), 1)
self.assertEquals(trs[0].name, u'deactivate')
- self.assertEquals(trs[0].destination().name, u'deactivated')
+ self.assertEquals(trs[0].destination(None).name, u'deactivated')
# test a std user get no possible transition
cnx = self.login('member')
# fetch the entity using the new session
@@ -141,6 +141,27 @@
trinfo = self._test_manager_deactivate(user)
self.assertEquals(trinfo.transition.name, 'deactivate')
+ def test_goback_transition(self):
+ wf = self.session.user.current_workflow
+ asleep = wf.add_state('asleep')
+ wf.add_transition('rest', (wf.state_by_name('activated'), wf.state_by_name('deactivated')),
+ asleep)
+ wf.add_transition('wake up', asleep)
+ user = self.create_user('stduser')
+ user.fire_transition('rest')
+ self.commit()
+ user.fire_transition('wake up')
+ self.commit()
+ self.assertEquals(user.state, 'activated')
+ user.fire_transition('deactivate')
+ self.commit()
+ user.fire_transition('rest')
+ self.commit()
+ user.fire_transition('wake up')
+ self.commit()
+ user.clear_all_caches()
+ self.assertEquals(user.state, 'deactivated')
+
# XXX test managers can change state without matching transition
def _test_stduser_deactivate(self):
@@ -207,7 +228,7 @@
state3 = mwf.add_state(u'state3')
swftr1 = mwf.add_wftransition(u'swftr1', swf, state1,
[(swfstate2, state2), (swfstate3, state3)])
- self.assertEquals(swftr1.destination().eid, swfstate1.eid)
+ self.assertEquals(swftr1.destination(None).eid, swfstate1.eid)
# workflows built, begin test
self.group = self.request().create_entity('CWGroup', name=u'grp1')
self.commit()
--- a/entities/wfobjs.py Fri Feb 19 09:34:14 2010 +0100
+++ b/entities/wfobjs.py Fri Feb 19 09:36:26 2010 +0100
@@ -256,8 +256,12 @@
"""customized class for Transition entities"""
__regid__ = 'Transition'
- def destination(self):
- return self.destination_state[0]
+ def destination(self, entity):
+ try:
+ return self.destination_state[0]
+ except IndexError:
+ return entity.latest_trinfo().previous_state
+
def parent(self):
return self.workflow
--- a/hooks/workflow.py Fri Feb 19 09:34:14 2010 +0100
+++ b/hooks/workflow.py Fri Feb 19 09:36:26 2010 +0100
@@ -232,7 +232,7 @@
raise ValidationError(entity.eid, {'by_transition': msg})
if entity.get('to_state'):
deststateeid = entity['to_state']
- if not cowpowers and deststateeid != tr.destination().eid:
+ if not cowpowers and deststateeid != tr.destination(forentity).eid:
msg = session._("transition isn't allowed")
raise ValidationError(entity.eid, {'by_transition': msg})
if swtr is None:
@@ -241,7 +241,7 @@
msg = session._("state doesn't belong to entity's workflow")
raise ValidationError(entity.eid, {'to_state': msg})
else:
- deststateeid = tr.destination().eid
+ deststateeid = tr.destination(forentity).eid
# everything is ok, add missing information on the trinfo entity
entity['from_state'] = fromstate.eid
entity['to_state'] = deststateeid
--- a/misc/migration/3.6.1_Any.py Fri Feb 19 09:34:14 2010 +0100
+++ b/misc/migration/3.6.1_Any.py Fri Feb 19 09:36:26 2010 +0100
@@ -1,1 +1,2 @@
sync_schema_props_perms(syncprops=False)
+sync_schema_props_perms('destination_state', syncperms=False)
--- a/schemas/workflow.py Fri Feb 19 09:34:14 2010 +0100
+++ b/schemas/workflow.py Fri Feb 19 09:36:26 2010 +0100
@@ -97,12 +97,13 @@
class Transition(BaseTransition):
"""use to define a transition from one or multiple states to a destination
- states in workflow's definitions.
+ states in workflow's definitions. Transition without destination state will
+ go back to the state from which we arrived to the current state.
"""
__specializes_schema__ = True
destination_state = SubjectRelation(
- 'State', cardinality='1*',
+ 'State', cardinality='?*',
constraints=[RQLConstraint('S transition_of WF, O state_of WF',
msg=_('state and transition don\'t belong the the same workflow'))],
description=_('destination state for this transition'))