102 for ep in tr.subworkflow_exit: |
102 for ep in tr.subworkflow_exit: |
103 if ep.subwf_state.eid in outputs: |
103 if ep.subwf_state.eid in outputs: |
104 msg = self.session._("can't have multiple exits on the same state") |
104 msg = self.session._("can't have multiple exits on the same state") |
105 raise ValidationError(self.treid, {'subworkflow_exit': msg}) |
105 raise ValidationError(self.treid, {'subworkflow_exit': msg}) |
106 outputs.add(ep.subwf_state.eid) |
106 outputs.add(ep.subwf_state.eid) |
|
107 |
|
108 |
|
109 class _SubWorkflowExitOp(PreCommitOperation): |
|
110 |
|
111 def precommit_event(self): |
|
112 session = self.session |
|
113 forentity = self.forentity |
|
114 trinfo = self.trinfo |
|
115 # we're in a subworkflow, check if we've reached an exit point |
|
116 wftr = forentity.subworkflow_input_transition() |
|
117 if wftr is None: |
|
118 # inconsistency detected |
|
119 msg = session._("state doesn't belong to entity's current workflow") |
|
120 raise ValidationError(self.trinfo.eid, {'to_state': msg}) |
|
121 tostate = wftr.get_exit_point(forentity, trinfo['to_state']) |
|
122 if tostate is not None: |
|
123 # reached an exit point |
|
124 msg = session._('exiting from subworkflow %s') |
|
125 msg %= session._(forentity.current_workflow.name) |
|
126 session.transaction_data[(forentity.eid, 'subwfentrytr')] = True |
|
127 # XXX iirk |
|
128 req = forentity.req |
|
129 forentity.req = session.super_session |
|
130 try: |
|
131 trinfo = forentity.change_state(tostate, msg, u'text/plain', |
|
132 tr=wftr) |
|
133 finally: |
|
134 forentity.req = req |
107 |
135 |
108 |
136 |
109 # hooks ######################################################################## |
137 # hooks ######################################################################## |
110 |
138 |
111 class WorkflowHook(hook.Hook): |
139 class WorkflowHook(hook.Hook): |
227 __regid__ = 'wffiretransition' |
255 __regid__ = 'wffiretransition' |
228 __select__ = WorkflowHook.__select__ & entity_implements('TrInfo') |
256 __select__ = WorkflowHook.__select__ & entity_implements('TrInfo') |
229 events = ('after_add_entity',) |
257 events = ('after_add_entity',) |
230 |
258 |
231 def __call__(self): |
259 def __call__(self): |
232 session = self._cw |
260 trinfo = self.entity |
233 entity = self.entity |
261 _change_state(self._cw, trinfo['wf_info_for'], |
234 _change_state(session, entity['wf_info_for'], |
262 trinfo['from_state'], trinfo['to_state']) |
235 entity['from_state'], entity['to_state']) |
263 forentity = self._cw.entity_from_eid(trinfo['wf_info_for']) |
236 forentity = session.entity_from_eid(entity['wf_info_for']) |
264 assert forentity.current_state.eid == trinfo['to_state'] |
237 assert forentity.current_state.eid == entity['to_state'] |
|
238 if forentity.main_workflow.eid != forentity.current_workflow.eid: |
265 if forentity.main_workflow.eid != forentity.current_workflow.eid: |
239 # we're in a subworkflow, check if we've reached an exit point |
266 _SubWorkflowExitOp(self._cw, forentity=forentity, trinfo=trinfo) |
240 wftr = forentity.subworkflow_input_transition() |
|
241 if wftr is None: |
|
242 # inconsistency detected |
|
243 msg = session._("state doesn't belong to entity's current workflow") |
|
244 raise ValidationError(entity.eid, {'to_state': msg}) |
|
245 tostate = wftr.get_exit_point(forentity, entity['to_state']) |
|
246 if tostate is not None: |
|
247 # reached an exit point |
|
248 msg = session._('exiting from subworkflow %s') |
|
249 msg %= session._(forentity.current_workflow.name) |
|
250 session.transaction_data[(forentity.eid, 'subwfentrytr')] = True |
|
251 # XXX iirk |
|
252 req = forentity._cw |
|
253 forentity._cw = session.super_session |
|
254 try: |
|
255 trinfo = forentity.change_state(tostate, msg, u'text/plain', |
|
256 tr=wftr) |
|
257 finally: |
|
258 forentity._cw = req |
|
259 |
267 |
260 |
268 |
261 class CheckInStateChangeAllowed(WorkflowHook): |
269 class CheckInStateChangeAllowed(WorkflowHook): |
262 """check state apply, in case of direct in_state change using unsafe_execute |
270 """check state apply, in case of direct in_state change using unsafe_execute |
263 """ |
271 """ |