32 entity type |
32 entity type |
33 """ |
33 """ |
34 return any(et for et in self.reverse_default_workflow |
34 return any(et for et in self.reverse_default_workflow |
35 if et.name == etype) |
35 if et.name == etype) |
36 |
36 |
|
37 # XXX define parent() instead? what if workflow of multiple types? |
37 def after_deletion_path(self): |
38 def after_deletion_path(self): |
38 """return (path, parameters) which should be used as redirect |
39 """return (path, parameters) which should be used as redirect |
39 information when this entity is being deleted |
40 information when this entity is being deleted |
40 """ |
41 """ |
41 if self.workflow_of: |
42 if self.workflow_of: |
99 """add a state to this workflow""" |
100 """add a state to this workflow""" |
100 state = self._cw.create_entity('State', name=unicode(name), **kwargs) |
101 state = self._cw.create_entity('State', name=unicode(name), **kwargs) |
101 self._cw.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s', |
102 self._cw.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s', |
102 {'s': state.eid, 'wf': self.eid}, ('s', 'wf')) |
103 {'s': state.eid, 'wf': self.eid}, ('s', 'wf')) |
103 if initial: |
104 if initial: |
104 assert not self.initial |
105 assert not self.initial, "Initial state already defined as %s" % self.initial |
105 self._cw.execute('SET WF initial_state S ' |
106 self._cw.execute('SET WF initial_state S ' |
106 'WHERE S eid %(s)s, WF eid %(wf)s', |
107 'WHERE S eid %(s)s, WF eid %(wf)s', |
107 {'s': state.eid, 'wf': self.eid}, ('s', 'wf')) |
108 {'s': state.eid, 'wf': self.eid}, ('s', 'wf')) |
108 return state |
109 return state |
109 |
110 |
243 __regid__ = 'Transition' |
244 __regid__ = 'Transition' |
244 |
245 |
245 def destination(self): |
246 def destination(self): |
246 return self.destination_state[0] |
247 return self.destination_state[0] |
247 |
248 |
|
249 def parent(self): |
|
250 return self.workflow |
|
251 |
248 |
252 |
249 class WorkflowTransition(BaseTransition): |
253 class WorkflowTransition(BaseTransition): |
250 """customized class for WorkflowTransition entities""" |
254 """customized class for WorkflowTransition entities""" |
251 __regid__ = 'WorkflowTransition' |
255 __regid__ = 'WorkflowTransition' |
252 |
256 |
308 |
312 |
309 @property |
313 @property |
310 def destination(self): |
314 def destination(self): |
311 return self.destination_state and self.destination_state[0] or None |
315 return self.destination_state and self.destination_state[0] or None |
312 |
316 |
|
317 def parent(self): |
|
318 return self.reverse_subworkflow_exit[0] |
|
319 |
313 |
320 |
314 class State(AnyEntity): |
321 class State(AnyEntity): |
315 """customized class for State entities""" |
322 """customized class for State entities""" |
316 __regid__ = 'State' |
323 __regid__ = 'State' |
317 fetch_attrs, fetch_order = fetch_config(['name']) |
324 fetch_attrs, fetch_order = fetch_config(['name']) |
320 @property |
327 @property |
321 def workflow(self): |
328 def workflow(self): |
322 # take care, may be missing in multi-sources configuration |
329 # take care, may be missing in multi-sources configuration |
323 return self.state_of and self.state_of[0] |
330 return self.state_of and self.state_of[0] |
324 |
331 |
325 def after_deletion_path(self): |
332 def parent(self): |
326 """return (path, parameters) which should be used as redirect |
333 return self.workflow |
327 information when this entity is being deleted |
|
328 """ |
|
329 if self.state_of: |
|
330 return self.state_of[0].rest_path(), {} |
|
331 return super(State, self).after_deletion_path() |
|
332 |
334 |
333 |
335 |
334 class TrInfo(AnyEntity): |
336 class TrInfo(AnyEntity): |
335 """customized class for Transition information entities |
337 """customized class for Transition information entities |
336 """ |
338 """ |
351 |
353 |
352 @property |
354 @property |
353 def transition(self): |
355 def transition(self): |
354 return self.by_transition and self.by_transition[0] or None |
356 return self.by_transition and self.by_transition[0] or None |
355 |
357 |
356 def after_deletion_path(self): |
358 def parent(self): |
357 """return (path, parameters) which should be used as redirect |
359 return self.for_entity |
358 information when this entity is being deleted |
|
359 """ |
|
360 if self.for_entity: |
|
361 return self.for_entity.rest_path(), {} |
|
362 return 'view', {} |
|
363 |
360 |
364 |
361 |
365 class WorkflowableMixIn(object): |
362 class WorkflowableMixIn(object): |
366 """base mixin providing workflow helper methods for workflowable entities. |
363 """base mixin providing workflow helper methods for workflowable entities. |
367 This mixin will be automatically set on class supporting the 'in_state' |
364 This mixin will be automatically set on class supporting the 'in_state' |
429 return None |
426 return None |
430 |
427 |
431 def possible_transitions(self, type='normal'): |
428 def possible_transitions(self, type='normal'): |
432 """generates transition that MAY be fired for the given entity, |
429 """generates transition that MAY be fired for the given entity, |
433 expected to be in this state |
430 expected to be in this state |
|
431 used only by the UI |
434 """ |
432 """ |
435 if self.current_state is None or self.current_workflow is None: |
433 if self.current_state is None or self.current_workflow is None: |
436 return |
434 return |
437 rset = self._cw.execute( |
435 rset = self._cw.execute( |
438 'Any T,TT, TN WHERE S allowed_transition T, S eid %(x)s, ' |
436 'Any T,TT, TN WHERE S allowed_transition T, S eid %(x)s, ' |