[IMP] models: add check for common conversion error in field definitions
[odoo/odoo.git] / openerp / workflow / service.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-TODAY OpenERP S.A. (<http://openerp.com>).
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 from helpers import Session
22 from helpers import Record
23
24 from openerp.workflow.instance import WorkflowInstance
25 # import instance
26
27
28 class WorkflowService(object):
29     CACHE = {}
30
31     @classmethod
32     def clear_cache(cls, dbname):
33         cls.CACHE[dbname] = {}
34
35     @classmethod
36     def new(cls, cr, uid, model_name, record_id):
37         return cls(Session(cr, uid), Record(model_name, record_id))
38
39     def __init__(self, session, record):
40         assert isinstance(session, Session)
41         assert isinstance(record, Record)
42
43         self.session = session
44         self.record = record
45
46         self.cr = self.session.cr
47
48     def write(self):
49         self.cr.execute('select id from wkf_instance where res_id=%s and res_type=%s and state=%s',
50             (self.record.id or None, self.record.model or None, 'active')
51         )
52         for (instance_id,) in self.cr.fetchall():
53             WorkflowInstance(self.session, self.record, {'id': instance_id}).update()
54
55     def trigger(self):
56         self.cr.execute('select instance_id from wkf_triggers where res_id=%s and model=%s', (self.record.id, self.record.model))
57         res = self.cr.fetchall()
58         for (instance_id,) in res:
59             self.cr.execute('select %s,res_type,res_id from wkf_instance where id=%s', (self.session.uid, instance_id,))
60             current_uid, current_model_name, current_record_id = self.cr.fetchone()
61
62             current_session = Session(self.session.cr, current_uid)
63             current_record = Record(current_model_name, current_record_id)
64
65             WorkflowInstance(current_session, current_record, {'id': instance_id}).update()
66
67     def delete(self):
68         WorkflowInstance(self.session, self.record, {}).delete()
69
70     def create(self):
71         WorkflowService.CACHE.setdefault(self.cr.dbname, {})
72
73         wkf_ids = WorkflowService.CACHE[self.cr.dbname].get(self.record.model, None)
74
75         if not wkf_ids:
76             self.cr.execute('select id from wkf where osv=%s and on_create=True', (self.record.model,))
77             wkf_ids = self.cr.fetchall()
78             WorkflowService.CACHE[self.cr.dbname][self.record.model] = wkf_ids
79
80         for (wkf_id, ) in wkf_ids:
81             WorkflowInstance.create(self.session, self.record, wkf_id)
82
83     def validate(self, signal):
84         result = False
85         # ids of all active workflow instances for a corresponding resource (id, model_nam)
86         self.cr.execute('select id from wkf_instance where res_id=%s and res_type=%s and state=%s', (self.record.id, self.record.model, 'active'))
87         # TODO: Refactor the workflow instance object
88         for (instance_id,) in self.cr.fetchall():
89             wi = WorkflowInstance(self.session, self.record, {'id': instance_id})
90
91             res2 = wi.validate(signal)
92
93             result = result or res2
94         return result
95
96     def redirect(self, new_rid):
97         # get ids of wkf instances for the old resource (res_id)
98         # CHECKME: shouldn't we get only active instances?
99         self.cr.execute('select id, wkf_id from wkf_instance where res_id=%s and res_type=%s', (self.record.id, self.record.model))
100
101         for old_inst_id, workflow_id in self.cr.fetchall():
102             # first active instance for new resource (new_rid), using same wkf
103             self.cr.execute(
104                 'SELECT id '\
105                 'FROM wkf_instance '\
106                 'WHERE res_id=%s AND res_type=%s AND wkf_id=%s AND state=%s',
107                 (new_rid, self.record.model, workflow_id, 'active'))
108             new_id = self.cr.fetchone()
109             if new_id:
110                 # select all workitems which "wait" for the old instance
111                 self.cr.execute('select id from wkf_workitem where subflow_id=%s', (old_inst_id,))
112                 for (item_id,) in self.cr.fetchall():
113                     # redirect all those workitems to the wkf instance of the new resource
114                     self.cr.execute('update wkf_workitem set subflow_id=%s where id=%s', (new_id[0], item_id))
115