-- -- workflow_case__fire_transition_internal/2 -- create or replace function workflow_case__fire_transition_internal( integer, integer ) returns int4 as $$ declare fire_transition_internal__task_id alias for $1; fire_transition_internal__journal_id alias for $2; v_case_id integer; v_state varchar; v_transition_key varchar; v_workflow_key varchar; v_place_key varchar; v_direction varchar; v_guard_happy_p boolean; v_fire_callback varchar; v_fire_custom_arg text; v_found_happy_guard boolean; v_locked_task_id integer; place_rec record; begin select t.case_id, t.state, t.workflow_key, t.transition_key, ti.fire_callback, ti.fire_custom_arg into v_case_id, v_state, v_workflow_key, v_transition_key, v_fire_callback, v_fire_custom_arg from wf_tasks t, wf_cases c, wf_transition_info ti where t.task_id = fire_transition_internal__task_id and c.case_id = t.case_id and ti.context_key = c.context_key and ti.workflow_key = c.workflow_key and ti.transition_key = t.transition_key; /* Check that the state is either started or enabled */ if v_state = 'enabled' then v_locked_task_id := null; else if v_state = 'started' then v_locked_task_id := fire_transition_internal__task_id; else raise EXCEPTION '-20000: Can''t fire the transition if it''s not in state enabled or started'; end if; end if; /* Mark the task finished */ update wf_tasks set state = 'finished', finished_date = now() where task_id = fire_transition_internal__task_id; /* Consume the tokens */ for place_rec in select * from wf_transition_places tp where tp.workflow_key = v_workflow_key and tp.transition_key = v_transition_key LOOP PERFORM workflow_case__consume_token ( v_case_id, place_rec.place_key, fire_transition_internal__journal_id, v_locked_task_id ); end loop; /* Spit out new tokens in the output places */ v_found_happy_guard := 'f'; for place_rec in select * from wf_transition_places tp where tp.workflow_key = v_workflow_key and tp.transition_key = v_transition_key and direction = 'out' LOOP v_place_key := place_rec.place_key; v_direction := place_rec.direction; v_guard_happy_p := workflow_case__evaluate_guard( place_rec.guard_callback, place_rec.guard_custom_arg, v_case_id, v_workflow_key, v_transition_key, v_place_key, v_direction ); if v_guard_happy_p = 't' then v_found_happy_guard := 't'; PERFORM workflow_case__add_token ( v_case_id, place_rec.place_key, fire_transition_internal__journal_id ); end if; end loop; /* If we did not find any happy guards, look for arcs with the special hash (#) guard */ if v_found_happy_guard = 'f' then for place_rec in select place_key from wf_transition_places tp where tp.workflow_key = v_workflow_key and tp.transition_key = v_transition_key and tp.direction = 'out' and tp.guard_callback = '#' loop PERFORM workflow_case__add_token ( v_case_id, place_rec.place_key, fire_transition_internal__journal_id ); end loop; end if; /* Execute the transition fire callback */ PERFORM workflow_case__execute_transition_callback ( v_fire_callback, v_fire_custom_arg, v_case_id, v_transition_key ); return 0; end;$$ language plpgsql;