[REF] Remove the useless wkf_expr.py file and copy it into workitem.py

bzr revid: stw@openerp.com-20131023130705-k4u7ssba820b7hwi
This commit is contained in:
Stephane Wirtel 2013-10-23 15:07:05 +02:00
parent fad743a978
commit 6a3a2709ef
3 changed files with 105 additions and 129 deletions

View File

@ -19,8 +19,8 @@
# #
############################################################################## ##############################################################################
import workitem import workitem
from helpers import Session from openerp.workflow.helpers import Session
from helpers import Record from openerp.workflow.helpers import Record
def create(session, record, workflow_id): def create(session, record, workflow_id):
assert isinstance(session, Session) assert isinstance(session, Session)

View File

@ -1,111 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
"""
Evaluate workflow code found in activity actions and transition conditions.
"""
import openerp
from openerp.tools.safe_eval import safe_eval as eval
class Env(dict):
"""
Dictionary class used as an environment to evaluate workflow code (such as
the condition on transitions).
This environment provides sybmols for cr, uid, id, model name, model
instance, column names, and all the record (the one obtained by browsing
the provided ID) attributes.
"""
def __init__(self, cr, uid, model, id):
self.cr = cr
self.uid = uid
self.model = model
self.id = id
self.ids = [id]
self.obj = openerp.registry(cr.dbname)[model]
self.columns = self.obj._columns.keys() + self.obj._inherit_fields.keys()
def __getitem__(self, key):
if (key in self.columns) or (key in dir(self.obj)):
res = self.obj.browse(self.cr, self.uid, self.id)
return res[key]
else:
return super(Env, self).__getitem__(key)
def _eval_expr(session, record, workitem, lines):
"""
Evaluate each line of ``lines`` with the ``Env`` environment, returning
the value of the last line.
"""
assert lines, 'You used a NULL action in a workflow, use dummy node instead.'
result = False
for line in lines.split('\n'):
line = line.strip()
if not line:
continue
if line == 'True':
result = True
elif line == 'False':
result = False
else:
env = Env(session.cr, session.uid, record.model, record.id)
result = eval(line, env, nocopy=True)
return result
def execute_action(session, record, workitem, activity):
"""
Evaluate the ir.actions.server action specified in the activity.
"""
ir_actions_server = openerp.registry(session.cr.dbname)['ir.actions.server']
context = { 'active_model': record.model, 'active_id': record.id, 'active_ids': [record.id] }
result = ir_actions_server.run(session.cr, session.uid, [activity['action_id']], context)
return result
def execute(session, record, workitem, activity):
"""
Evaluate the action specified in the activity.
"""
return _eval_expr(session, record, workitem, activity['action'])
def check(session, record, workitem, transition, signal):
"""
Test if a transition can be taken. The transition can be taken if:
- the signal name matches,
- the uid is SUPERUSER_ID or the user groups contains the transition's
group,
- the condition evaluates to a truish value.
"""
if transition['signal'] and signal != transition['signal']:
return False
if session.uid != openerp.SUPERUSER_ID and transition['group_id']:
registry = openerp.registry(session.cr.dbname)
user_groups = registry['res.users'].read(session.cr, session.uid, [session.uid], ['groups_id'])[0]['groups_id']
if transition['group_id'] not in user_groups:
return False
return _eval_expr(session, record, workitem, transition['condition'])
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -2,7 +2,7 @@
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). # Copyright (C) 2004-2009 OpenERP S.A. (<http://openerp.com).
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -24,15 +24,101 @@
# cr.execute('delete from wkf_triggers where model=%s and res_id=%s', (res_type,res_id)) # cr.execute('delete from wkf_triggers where model=%s and res_id=%s', (res_type,res_id))
# #
import logging import logging
import instance import instance
import wkf_expr from openerp.workflow.helpers import Session
from helpers import Session from openerp.workflow.helpers import Record
from helpers import Record
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
import openerp
from openerp.tools.safe_eval import safe_eval as eval
class Env(dict):
"""
Dictionary class used as an environment to evaluate workflow code (such as
the condition on transitions).
This environment provides sybmols for cr, uid, id, model name, model
instance, column names, and all the record (the one obtained by browsing
the provided ID) attributes.
"""
def __init__(self, cr, uid, model, id):
self.cr = cr
self.uid = uid
self.model = model
self.id = id
self.ids = [id]
self.obj = openerp.registry(cr.dbname)[model]
self.columns = self.obj._columns.keys() + self.obj._inherit_fields.keys()
def __getitem__(self, key):
if (key in self.columns) or (key in dir(self.obj)):
res = self.obj.browse(self.cr, self.uid, self.id)
return res[key]
else:
return super(Env, self).__getitem__(key)
def wkf_expr_eval_expr(session, record, workitem, lines):
"""
Evaluate each line of ``lines`` with the ``Env`` environment, returning
the value of the last line.
"""
assert lines, 'You used a NULL action in a workflow, use dummy node instead.'
result = False
for line in lines.split('\n'):
line = line.strip()
if not line:
continue
if line == 'True':
result = True
elif line == 'False':
result = False
else:
env = Env(session.cr, session.uid, record.model, record.id)
result = eval(line, env, nocopy=True)
return result
def wkf_expr_execute_action(session, record, workitem, activity):
"""
Evaluate the ir.actions.server action specified in the activity.
"""
ir_actions_server = openerp.registry(session.cr.dbname)['ir.actions.server']
context = { 'active_model': record.model, 'active_id': record.id, 'active_ids': [record.id] }
result = ir_actions_server.run(session.cr, session.uid, [activity['action_id']], context)
return result
def wkf_expr_execute(session, record, workitem, activity):
"""
Evaluate the action specified in the activity.
"""
return wkf_expr_eval_expr(session, record, workitem, activity['action'])
def wkf_expr_check(session, record, workitem, transition, signal):
"""
Test if a transition can be taken. The transition can be taken if:
- the signal name matches,
- the uid is SUPERUSER_ID or the user groups contains the transition's
group,
- the condition evaluates to a truish value.
"""
if transition['signal'] and signal != transition['signal']:
return False
if session.uid != openerp.SUPERUSER_ID and transition['group_id']:
registry = openerp.registry(session.cr.dbname)
user_groups = registry['res.users'].read(session.cr, session.uid, [session.uid], ['groups_id'])[0]['groups_id']
if transition['group_id'] not in user_groups:
return False
return wkf_expr_eval_expr(session, record, workitem, transition['condition'])
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
def create(session, record, activities, instance_id, stack): def create(session, record, activities, instance_id, stack):
assert isinstance(session, Session) assert isinstance(session, Session)
assert isinstance(record, Record) assert isinstance(record, Record)
@ -79,7 +165,7 @@ def process(session, record, workitem, signal=None, force_running=False, stack=N
cr.execute('select * from wkf_transition where act_from=%s', (workitem['act_id'],)) cr.execute('select * from wkf_transition where act_from=%s', (workitem['act_id'],))
for trans in cr.dictfetchall(): for trans in cr.dictfetchall():
if trans['trigger_model']: if trans['trigger_model']:
ids = wkf_expr._eval_expr(session, record, workitem, trans['trigger_expr_id']) ids = wkf_expr_eval_expr(session, record, workitem, trans['trigger_expr_id'])
for res_id in ids: for res_id in ids:
cr.execute('select nextval(\'wkf_triggers_id_seq\')') cr.execute('select nextval(\'wkf_triggers_id_seq\')')
id =cr.fetchone()[0] id =cr.fetchone()[0]
@ -98,10 +184,8 @@ def _state_set(session, record, workitem, activity, state):
extra={'ident': (session.uid, record.model, record.id)}) extra={'ident': (session.uid, record.model, record.id)})
def _execute(session, record, workitem, activity, stack): def _execute(session, record, workitem, activity, stack):
"""Send a signal to parenrt workflow (signal: subflow.signal_name)"""
result = True result = True
#
# send a signal to parent workflow (signal: subflow.signal_name)
#
cr = session.cr cr = session.cr
signal_todo = [] signal_todo = []
if (workitem['state']=='active') and activity['signal_send']: if (workitem['state']=='active') and activity['signal_send']:
@ -114,35 +198,38 @@ def _execute(session, record, workitem, activity, stack):
if workitem['state']=='active': if workitem['state']=='active':
_state_set(session, record, workitem, activity, 'complete') _state_set(session, record, workitem, activity, 'complete')
if activity['action_id']: if activity['action_id']:
res2 = wkf_expr.execute_action(session, record, workitem, activity) res2 = wkf_expr_execute_action(session, record, workitem, activity)
if res2: if res2:
stack.append(res2) stack.append(res2)
result=res2 result=res2
elif activity['kind']=='function': elif activity['kind']=='function':
if workitem['state']=='active': if workitem['state']=='active':
_state_set(session, record, workitem, activity, 'running') _state_set(session, record, workitem, activity, 'running')
returned_action = wkf_expr.execute(session, record, workitem, activity) returned_action = wkf_expr_execute(session, record, workitem, activity)
if type(returned_action) in (dict,): if type(returned_action) in (dict,):
stack.append(returned_action) stack.append(returned_action)
if activity['action_id']: if activity['action_id']:
res2 = wkf_expr.execute_action(session, record, workitem, activity) res2 = wkf_expr_execute_action(session, record, workitem, activity)
# A client action has been returned # A client action has been returned
if res2: if res2:
stack.append(res2) stack.append(res2)
result=res2 result=res2
_state_set(session, record, workitem, activity, 'complete') _state_set(session, record, workitem, activity, 'complete')
elif activity['kind']=='stopall': elif activity['kind']=='stopall':
if workitem['state']=='active': if workitem['state']=='active':
_state_set(session, record, workitem, activity, 'running') _state_set(session, record, workitem, activity, 'running')
cr.execute('delete from wkf_workitem where inst_id=%s and id<>%s', (workitem['inst_id'], workitem['id'])) cr.execute('delete from wkf_workitem where inst_id=%s and id<>%s', (workitem['inst_id'], workitem['id']))
if activity['action']: if activity['action']:
wkf_expr.execute(session, record, workitem, activity) wkf_expr_execute(session, record, workitem, activity)
_state_set(session, record, workitem, activity, 'complete') _state_set(session, record, workitem, activity, 'complete')
elif activity['kind']=='subflow': elif activity['kind']=='subflow':
if workitem['state']=='active': if workitem['state']=='active':
_state_set(session, record, workitem, activity, 'running') _state_set(session, record, workitem, activity, 'running')
if activity.get('action', False): if activity.get('action', False):
id_new = wkf_expr.execute(session, record, workitem, activity) id_new = wkf_expr_execute(session, record, workitem, activity)
if not id_new: if not id_new:
cr.execute('delete from wkf_workitem where id=%s', (workitem['id'],)) cr.execute('delete from wkf_workitem where id=%s', (workitem['id'],))
return False return False
@ -172,7 +259,7 @@ def _split_test(session, record, workitem, split_mode, signal, stack):
alltrans = cr.dictfetchall() alltrans = cr.dictfetchall()
if split_mode=='XOR' or split_mode=='OR': if split_mode=='XOR' or split_mode=='OR':
for transition in alltrans: for transition in alltrans:
if wkf_expr.check(session, record, workitem, transition,signal): if wkf_expr_check(session, record, workitem, transition,signal):
test = True test = True
transitions.append((transition['id'], workitem['inst_id'])) transitions.append((transition['id'], workitem['inst_id']))
if split_mode=='XOR': if split_mode=='XOR':
@ -180,7 +267,7 @@ def _split_test(session, record, workitem, split_mode, signal, stack):
else: else:
test = True test = True
for transition in alltrans: for transition in alltrans:
if not wkf_expr.check(session, record, workitem, transition,signal): if not wkf_expr_check(session, record, workitem, transition,signal):
test = False test = False
break break
cr.execute('select count(*) from wkf_witm_trans where trans_id=%s and inst_id=%s', (transition['id'], workitem['inst_id'])) cr.execute('select count(*) from wkf_witm_trans where trans_id=%s and inst_id=%s', (transition['id'], workitem['inst_id']))