restore the original gevent detection
[odoo/odoo.git] / openerp / workflow / wkf_expr.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #    
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
19 #
20 ##############################################################################
21
22 """
23 Evaluate workflow code found in activity actions and transition conditions.
24 """
25
26 import openerp
27 from openerp.tools.safe_eval import safe_eval as eval
28
29 class Env(dict):
30     """
31     Dictionary class used as an environment to evaluate workflow code (such as
32     the condition on transitions).
33
34     This environment provides sybmols for cr, uid, id, model name, model
35     instance, column names, and all the record (the one obtained by browsing
36     the provided ID) attributes.
37     """
38     def __init__(self, cr, uid, model, id):
39         self.cr = cr
40         self.uid = uid
41         self.model = model
42         self.id = id
43         self.ids = [id]
44         self.obj = openerp.registry(cr.dbname)[model]
45         self.columns = self.obj._columns.keys() + self.obj._inherit_fields.keys()
46
47     def __getitem__(self, key):
48         if (key in self.columns) or (key in dir(self.obj)):
49             res = self.obj.browse(self.cr, self.uid, self.id)
50             return res[key]
51         else:
52             return super(Env, self).__getitem__(key)
53
54 def _eval_expr(cr, ident, workitem, lines):
55     """
56     Evaluate each line of ``lines`` with the ``Env`` environment, returning
57     the value of the last line.
58     """
59     assert lines, 'You used a NULL action in a workflow, use dummy node instead.'
60     uid, model, id = ident
61     result = False
62     for line in lines.split('\n'):
63         line = line.strip()
64         if not line:
65             continue
66         if line == 'True':
67             result = True
68         elif line == 'False':
69             result = False
70         else:
71             env = Env(cr, uid, model, id)
72             result = eval(line, env, nocopy=True)
73     return result
74
75 def execute_action(cr, ident, workitem, activity):
76     """
77     Evaluate the ir.actions.server action specified in the activity.
78     """
79     uid, model, id = ident
80     ir_actions_server = openerp.registry(cr.dbname)['ir.actions.server']
81     context = { 'active_model': model, 'active_id': id, 'active_ids': [id] }
82     result = ir_actions_server.run(cr, uid, [activity['action_id']], context)
83     return result
84
85 def execute(cr, ident, workitem, activity):
86     """
87     Evaluate the action specified in the activity.
88     """
89     return _eval_expr(cr, ident, workitem, activity['action'])
90
91 def check(cr, workitem, ident, transition, signal):
92     """
93     Test if a transition can be taken. The transition can be taken if:
94     
95     - the signal name matches,
96     - the uid is SUPERUSER_ID or the user groups contains the transition's
97       group,
98     - the condition evaluates to a truish value.
99     """
100     if transition['signal'] and signal != transition['signal']:
101         return False
102
103     uid = ident[0]
104     if uid != openerp.SUPERUSER_ID and transition['group_id']:
105         registry = openerp.registry(cr.dbname)
106         user_groups = registry['res.users'].read(cr, uid, [uid], ['groups_id'])[0]['groups_id']
107         if transition['group_id'] not in user_groups:
108             return False
109
110     return _eval_expr(cr, ident, workitem, transition['condition'])
111
112
113 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
114