Esempio n. 1
0
 def trg_validate(self, uid, res_type, res_id, signal, cr):
     result = False
     ident = (uid,res_type,res_id)
     # ids of all active workflow instances for a corresponding resource (id, model_nam)
     cr.execute('select id from wkf_instance where res_id=%s and res_type=%s and state=%s', (res_id, res_type, 'active'))
     for (id,) in cr.fetchall():
         res2 = instance.validate(cr, id, ident, signal)
         result = result or res2
     return result
Esempio n. 2
0
    def trg_validate(self, uid, res_type, res_id, signal, cr):
        """
        Fire a signal on a given workflow instance

        :param res_type: the model name
        :param res_id: the model instance id the workflow belongs to
        :signal: the signal name to be fired
        :param cr: a database cursor
        """
        result = False
        ident = (uid,res_type,res_id)
        # ids of all active workflow instances for a corresponding resource (id, model_nam)
        cr.execute('select id from wkf_instance where res_id=%s and res_type=%s and state=%s', (res_id, res_type, 'active'))
        for (id,) in cr.fetchall():
            res2 = instance.validate(cr, id, ident, signal)
            result = result or res2
        return result
Esempio n. 3
0
    def trg_validate(self, uid, res_type, res_id, signal, cr):
        """
        Fire a signal on a given workflow instance

        :param res_type: the model name
        :param res_id: the model instance id the workflow belongs to
        :signal: the signal name to be fired
        :param cr: a database cursor
        """
        result = False
        ident = (uid,res_type,res_id)
        # ids of all active workflow instances for a corresponding resource (id, model_nam)
        cr.execute('select id from wkf_instance where res_id=%s and res_type=%s and state=%s', (res_id, res_type, 'active'))
        for (id,) in cr.fetchall():
            res2 = instance.validate(cr, id, ident, signal)
            result = result or res2
        return result
Esempio n. 4
0
def _execute(cr, workitem, activity, ident, stack):
    result = True
    #
    # send a signal to parent workflow (signal: subflow.signal_name)
    #
    signal_todo = []
    if (workitem['state']=='active') and activity['signal_send']:
        cr.execute("select i.id,w.osv,i.res_id from wkf_instance i left join wkf w on (i.wkf_id=w.id) where i.id IN (select inst_id from wkf_workitem where subflow_id=%s)", (workitem['inst_id'],))
        for i in cr.fetchall():
            signal_todo.append((i[0], (ident[0],i[1],i[2]), activity['signal_send']))

    if activity['kind']=='dummy':
        if workitem['state']=='active':
            _state_set(cr, workitem, activity, 'complete', ident)
            if activity['action_id']:
                res2 = wkf_expr.execute_action(cr, ident, workitem, activity)
                if res2:
                    stack.append(res2)
                    result=res2
    elif activity['kind']=='function':
        if workitem['state']=='active':
            _state_set(cr, workitem, activity, 'running', ident)
            returned_action = wkf_expr.execute(cr, ident, workitem, activity)
            if type(returned_action) in (dict,):
                stack.append(returned_action)
            if activity['action_id']:
                res2 = wkf_expr.execute_action(cr, ident, workitem, activity)
                # A client action has been returned
                if res2:
                    stack.append(res2)
                    result=res2
            _state_set(cr, workitem, activity, 'complete', ident)
    elif activity['kind']=='stopall':
        if workitem['state']=='active':
            _state_set(cr, workitem, activity, 'running', ident)
            cr.execute('delete from wkf_workitem where inst_id=%s and id<>%s', (workitem['inst_id'], workitem['id']))
            if activity['action']:
                wkf_expr.execute(cr, ident, workitem, activity)
            _state_set(cr, workitem, activity, 'complete', ident)
    elif activity['kind']=='subflow':
        if workitem['state']=='active':
            _state_set(cr, workitem, activity, 'running', ident)
            if activity.get('action', False):
                id_new = wkf_expr.execute(cr, ident, workitem, activity)
                if not id_new:
                    cr.execute('delete from wkf_workitem where id=%s', (workitem['id'],))
                    return False
                assert type(id_new)==type(1) or type(id_new)==type(1L), 'Wrong return value: '+str(id_new)+' '+str(type(id_new))
                cr.execute('select id from wkf_instance where res_id=%s and wkf_id=%s', (id_new,activity['subflow_id']))
                id_new = cr.fetchone()[0]
            else:
                id_new = instance.create(cr, ident, activity['subflow_id'])
            cr.execute('update wkf_workitem set subflow_id=%s where id=%s', (id_new, workitem['id']))
            workitem['subflow_id'] = id_new
        if workitem['state']=='running':
            cr.execute("select state from wkf_instance where id=%s", (workitem['subflow_id'],))
            state= cr.fetchone()[0]
            if state=='complete':
                _state_set(cr, workitem, activity, 'complete', ident)
    for t in signal_todo:
        instance.validate(cr, t[0], t[1], t[2], force_running=True)

    return result
Esempio n. 5
0
def _execute(cr, workitem, activity, ident, stack):
    result = True
    #
    # send a signal to parent workflow (signal: subflow.signal_name)
    #
    signal_todo = []
    if (workitem['state']=='active') and activity['signal_send']:
        cr.execute("select i.id,w.osv,i.res_id from wkf_instance i left join wkf w on (i.wkf_id=w.id) where i.id IN (select inst_id from wkf_workitem where subflow_id=%s)", (workitem['inst_id'],))
        for i in cr.fetchall():
            signal_todo.append((i[0], (ident[0],i[1],i[2]), activity['signal_send']))

    if activity['kind']=='dummy':
        if workitem['state']=='active':
            _state_set(cr, workitem, activity, 'complete', ident)
            if activity['action_id']:
                res2 = wkf_expr.execute_action(cr, ident, workitem, activity)
                if res2:
                    stack.append(res2)
                    result=res2
    elif activity['kind']=='function':
        if workitem['state']=='active':
            _state_set(cr, workitem, activity, 'running', ident)
            returned_action = wkf_expr.execute(cr, ident, workitem, activity)
            if type(returned_action) in (dict,):
                stack.append(returned_action)
            if activity['action_id']:
                res2 = wkf_expr.execute_action(cr, ident, workitem, activity)
                # A client action has been returned
                if res2:
                    stack.append(res2)
                    result=res2
            _state_set(cr, workitem, activity, 'complete', ident)
    elif activity['kind']=='stopall':
        if workitem['state']=='active':
            _state_set(cr, workitem, activity, 'running', ident)
            cr.execute('delete from wkf_workitem where inst_id=%s and id<>%s', (workitem['inst_id'], workitem['id']))
            if activity['action']:
                wkf_expr.execute(cr, ident, workitem, activity)
            _state_set(cr, workitem, activity, 'complete', ident)
    elif activity['kind']=='subflow':
        if workitem['state']=='active':
            _state_set(cr, workitem, activity, 'running', ident)
            if activity.get('action', False):
                id_new = wkf_expr.execute(cr, ident, workitem, activity)
                if not id_new:
                    cr.execute('delete from wkf_workitem where id=%s', (workitem['id'],))
                    return False
                assert type(id_new)==type(1) or type(id_new)==type(1L), 'Wrong return value: '+str(id_new)+' '+str(type(id_new))
                cr.execute('select id from wkf_instance where res_id=%s and wkf_id=%s', (id_new,activity['subflow_id']))
                id_new = cr.fetchone()[0]
            else:
                id_new = instance.create(cr, ident, activity['subflow_id'])
            cr.execute('update wkf_workitem set subflow_id=%s where id=%s', (id_new, workitem['id']))
            workitem['subflow_id'] = id_new
        if workitem['state']=='running':
            cr.execute("select state from wkf_instance where id=%s", (workitem['subflow_id'],))
            state= cr.fetchone()[0]
            if state=='complete':
                _state_set(cr, workitem, activity, 'complete', ident)
    for t in signal_todo:
        instance.validate(cr, t[0], t[1], t[2], force_running=True)

    return result
Esempio n. 6
0
def _execute(cr, workitem, activity, ident, stack):
    """ Execute wkf_activity's action on a given workitem

    @param cr: database handle
    @param workitem: dict of the wkf_workitem to process
    @param activity: dict of the wkf_activity
    @param ident: tuple of (uid, dotted model name, resource id )
    @param stack: ???

    There are 4 different types of activities:

    * dummy: blank state, no processing required
             stack is used to return data from an ir.act.server function call 
                if action_id is set
    * function: executes a particular function on a workitem
                note that while the function is executing the system will
                mark the wkf_workitem's state as 'running' to prevent
                doubled up work
    * stopall: deletes the current workitem from the database
    * subflow: creates a new subflow if required 

    """
    result = True
    #
    # send a signal to parent workflow (signal: subflow.signal_name)
    #
    signal_todo = []
    if (workitem['state'] == 'active') and activity['signal_send']:
        cr.execute(
            "select i.id,w.osv,i.res_id from wkf_instance i left join wkf w on (i.wkf_id=w.id) where i.id IN (select inst_id from wkf_workitem where subflow_id=%s)",
            (workitem['inst_id'], ))
        for i in cr.fetchall():
            signal_todo.append(
                (i[0], (ident[0], i[1], i[2]), activity['signal_send']))

    if config['debug_workflow']:
        exec_started = datetime.datetime.now()
        _logger.debug("  execute {a[kind]} {i[1]},{i[2]} {d}".format(
            i=ident, w=workitem, a=activity, d=exec_started))

    # ACTIVITY: dummy
    if activity['kind'] == 'dummy':
        if workitem['state'] == 'active':
            _state_set(cr, workitem, activity, 'complete', ident)
            if activity['action_id']:
                res2 = wkf_expr.execute_action(cr, ident, workitem, activity)
                if res2:
                    stack.append(res2)
                    result = res2

    # ACTIVITY: function
    elif activity['kind'] == 'function':
        if workitem['state'] == 'active':

            if config['debug_workflow']:
                _logger.debug("  function {i[1]},{i[2]}: {a[action]}".format(
                    i=ident, w=workitem, a=activity))

            _state_set(cr, workitem, activity, 'running', ident)
            returned_action = wkf_expr.execute(cr, ident, workitem, activity)
            if type(returned_action) in (dict, ):
                stack.append(returned_action)
            if activity['action_id']:
                res2 = wkf_expr.execute_action(cr, ident, workitem, activity)
                # A client action has been returned
                if res2:
                    stack.append(res2)
                    result = res2
            _state_set(cr, workitem, activity, 'complete', ident)

    # ACTIVITY: stopall
    elif activity['kind'] == 'stopall':
        if workitem['state'] == 'active':
            _state_set(cr, workitem, activity, 'running', ident)
            cr.execute('delete from wkf_workitem where inst_id=%s and id<>%s',
                       (workitem['inst_id'], workitem['id']))
            if activity['action']:
                wkf_expr.execute(cr, ident, workitem, activity)
            _state_set(cr, workitem, activity, 'complete', ident)

    # ACTIVITY: subflow
    elif activity['kind'] == 'subflow':

        # If the state is currently marked as 'active' it means that the node
        # has yet to start the subflow. So let's create it.
        if workitem['state'] == 'active':
            _state_set(cr, workitem, activity, 'running', ident)

            # action will be a python function on the wkf_instance's res_type model
            # What we expect from this function is the new target record's ID
            # As we expect that the new record will have its own workflow, we just
            # need to know what workflow this object will be launched into. We know
            # the new record's workflow id because the current wkf_activity has
            # wkf_activity.subflow_id references the target sub-object's wkf record
            if activity.get('action', False):
                id_new = wkf_expr.execute(cr, ident, workitem, activity)
                # If we don't get a new record id, stop the workflow and drop out
                if not (id_new):
                    cr.execute('delete from wkf_workitem where id=%s',
                               (workitem['id'], ))
                    return False
                assert type(id_new) == type(1) or type(id_new) == type(
                    1L), 'Wrong return value: ' + str(id_new) + ' ' + str(
                        type(id_new))
                cr.execute(
                    'select id from wkf_instance where res_id=%s and wkf_id=%s',
                    (id_new, activity['subflow_id']))
                id_new = cr.fetchone()[0]

            # If there is no function, we just put the current object on the subflow.
            # TODO: this seems a little perilous if the workflow references some other model
            else:
                id_new = instance.create(cr, ident, activity['subflow_id'])
            cr.execute('update wkf_workitem set subflow_id=%s where id=%s',
                       (id_new, workitem['id']))
            workitem['subflow_id'] = id_new

        # If the state is running, we're waiting for the subflow to complete. Check the subflow
        # to see what the status it happens to be and if the subflow is marked 'complete', we can
        # finally mark this activity as complete as well
        if workitem['state'] == 'running':
            cr.execute("select state from wkf_instance where id=%s",
                       (workitem['subflow_id'], ))
            state = cr.fetchone()[0]
            if state == 'complete':
                _state_set(cr, workitem, activity, 'complete', ident)

    for t in signal_todo:
        instance.validate(cr, t[0], t[1], t[2], force_running=True)

    if config['debug_workflow']:
        _logger.debug("  /execute {a[kind]} {i[1]},{i[2]} started {d}".format(
            i=ident, w=workitem, a=activity, d=exec_started))

    return result
Esempio n. 7
0
def _execute(cr, workitem, activity, ident, stack):
    result = True
    #
    # send a signal to parent workflow (signal: subflow.signal_name)
    #
    signal_todo = []
    if (workitem["state"] == "active") and activity["signal_send"]:
        cr.execute(
            "select i.id,w.osv,i.res_id from wkf_instance i left join wkf w on (i.wkf_id=w.id) where i.id IN (select inst_id from wkf_workitem where subflow_id=%s)",
            (workitem["inst_id"],),
        )
        for i in cr.fetchall():
            signal_todo.append((i[0], (ident[0], i[1], i[2]), activity["signal_send"]))

    if activity["kind"] == "dummy":
        if workitem["state"] == "active":
            _state_set(cr, workitem, activity, "complete", ident)
            if activity["action_id"]:
                res2 = wkf_expr.execute_action(cr, ident, workitem, activity)
                if res2:
                    stack.append(res2)
                    result = res2
    elif activity["kind"] == "function":
        if workitem["state"] == "active":
            _state_set(cr, workitem, activity, "running", ident)
            returned_action = wkf_expr.execute(cr, ident, workitem, activity)
            if type(returned_action) in (dict,):
                stack.append(returned_action)
            if activity["action_id"]:
                res2 = wkf_expr.execute_action(cr, ident, workitem, activity)
                # A client action has been returned
                if res2:
                    stack.append(res2)
                    result = res2
            _state_set(cr, workitem, activity, "complete", ident)
    elif activity["kind"] == "stopall":
        if workitem["state"] == "active":
            _state_set(cr, workitem, activity, "running", ident)
            cr.execute("delete from wkf_workitem where inst_id=%s and id<>%s", (workitem["inst_id"], workitem["id"]))
            if activity["action"]:
                wkf_expr.execute(cr, ident, workitem, activity)
            _state_set(cr, workitem, activity, "complete", ident)
    elif activity["kind"] == "subflow":
        if workitem["state"] == "active":
            _state_set(cr, workitem, activity, "running", ident)
            if activity.get("action", False):
                id_new = wkf_expr.execute(cr, ident, workitem, activity)
                if not (id_new):
                    cr.execute("delete from wkf_workitem where id=%s", (workitem["id"],))
                    return False
                assert type(id_new) == type(1) or type(id_new) == type(1L), (
                    "Wrong return value: " + str(id_new) + " " + str(type(id_new))
                )
                cr.execute(
                    "select id from wkf_instance where res_id=%s and wkf_id=%s", (id_new, activity["subflow_id"])
                )
                id_new = cr.fetchone()[0]
            else:
                id_new = instance.create(cr, ident, activity["subflow_id"])
            cr.execute("update wkf_workitem set subflow_id=%s where id=%s", (id_new, workitem["id"]))
            workitem["subflow_id"] = id_new
        if workitem["state"] == "running":
            cr.execute("select state from wkf_instance where id=%s", (workitem["subflow_id"],))
            state = cr.fetchone()[0]
            if state == "complete":
                _state_set(cr, workitem, activity, "complete", ident)
    for t in signal_todo:
        instance.validate(cr, t[0], t[1], t[2], force_running=True)

    return result