[I18N] Update translation templates for latest changes - ready for 7.0 release
[odoo/odoo.git] / addons / crm_profiling / crm_profiling.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 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 from openerp.osv import fields,osv
23 from openerp.osv import orm
24
25 from openerp.tools.translate import _
26
27 def _get_answers(cr, uid, ids):
28     """
29         @param cr: the current row, from the database cursor,
30         @param uid: the current user’s ID for security checks,
31         @param ids: List of crm profiling’s IDs """
32
33     query = """
34     select distinct(answer)
35     from profile_question_yes_rel
36     where profile IN %s"""
37
38     cr.execute(query, (tuple(ids),))
39     ans_yes = [x[0] for x in cr.fetchall()]
40
41     query = """
42     select distinct(answer)
43     from profile_question_no_rel
44     where profile IN %s"""
45
46     cr.execute(query, (tuple(ids),))
47     ans_no = [x[0] for x in cr.fetchall()]
48
49     return [ans_yes, ans_no]
50
51
52 def _get_parents(cr, uid, ids):
53     """
54         @param cr: the current row, from the database cursor,
55         @param uid: the current user’s ID for security checks,
56         @param ids: List of crm profiling’s IDs
57         @return: Get parents's Id """
58
59     ids_to_check = ids
60     cr.execute("""
61      select distinct(parent_id)
62      from crm_segmentation
63      where parent_id is not null
64      and id IN %s""",(tuple(ids),))
65
66     parent_ids = [x[0] for x in cr.fetchall()]
67
68     trigger = False
69     for x in parent_ids:
70         if x not in ids_to_check:
71             ids_to_check.append(x)
72             trigger = True
73
74     if trigger:
75         ids_to_check = _get_parents(cr, uid, ids_to_check)
76
77     return ids_to_check
78
79
80 def test_prof(cr, uid, seg_id, pid, answers_ids=None):
81
82     """ return True if the partner pid fetch the segmentation rule seg_id
83         @param cr: the current row, from the database cursor,
84         @param uid: the current user’s ID for security checks,
85         @param seg_id: Segmentaion's ID
86         @param pid: partner's ID
87         @param answers_ids: Answers's IDs
88     """
89
90     ids_to_check = _get_parents(cr, uid, [seg_id])
91     [yes_answers, no_answers] = _get_answers(cr, uid, ids_to_check)
92     temp = True
93     for y_ans in yes_answers:
94         if y_ans not in answers_ids:
95             temp = False
96             break
97     if temp:
98         for ans in answers_ids:
99             if ans in no_answers:
100                 temp = False
101                 break
102     if temp:
103         return True
104     return False
105
106
107 def _recompute_categ(self, cr, uid, pid, answers_ids):
108     """ Recompute category
109         @param self: The object pointer
110         @param cr: the current row, from the database cursor,
111         @param uid: the current user’s ID for security checks,
112         @param pid: partner's ID
113         @param answers_ids: Answers's IDs
114     """
115
116     ok =  []
117     cr.execute('''
118         select r.category_id
119         from res_partner_res_partner_category_rel r left join crm_segmentation s on (r.category_id = s.categ_id)
120         where r.partner_id = %s and (s.exclusif = false or s.exclusif is null)
121         ''', (pid,))
122     for x in cr.fetchall():
123         ok.append(x[0])
124
125     query = '''
126         select id, categ_id
127         from crm_segmentation
128         where profiling_active = true'''
129     if ok != []:
130         query = query +''' and categ_id not in(%s)'''% ','.join([str(i) for i in ok ])
131     query = query + ''' order by id '''
132
133     cr.execute(query)
134     segm_cat_ids = cr.fetchall()
135
136     for (segm_id, cat_id) in segm_cat_ids:
137         if test_prof(cr, uid, segm_id, pid, answers_ids):
138             ok.append(cat_id)
139     return ok
140
141
142 class question(osv.osv):
143     """ Question """
144
145     _name="crm_profiling.question"
146     _description= "Question"
147
148     _columns={
149         'name': fields.char("Question",size=128, required=True),
150         'answers_ids': fields.one2many("crm_profiling.answer","question_id","Avalaible Answers",),
151         }
152
153 question()
154
155
156 class questionnaire(osv.osv):
157     """ Questionnaire """
158
159     _name="crm_profiling.questionnaire"
160     _description= "Questionnaire"
161
162     _columns = {
163         'name': fields.char("Questionnaire",size=128, required=True),
164         'description':fields.text("Description", required=True),
165         'questions_ids': fields.many2many('crm_profiling.question','profile_questionnaire_quest_rel',\
166                                 'questionnaire', 'question', "Questions"),
167     }
168
169 questionnaire()
170
171
172 class answer(osv.osv):
173     _name="crm_profiling.answer"
174     _description="Answer"
175     _columns={
176         "name": fields.char("Answer",size=128, required=True),
177         "question_id": fields.many2one('crm_profiling.question',"Question"),
178         }
179 answer()
180
181
182 class partner(osv.osv):
183     _inherit="res.partner"
184     _columns={
185         "answers_ids": fields.many2many("crm_profiling.answer","partner_question_rel",\
186                                 "partner","answer","Answers"),
187         }
188
189     def _questionnaire_compute(self, cr, uid, answers, context=None):
190         """
191             @param self: The object pointer
192             @param cr: the current row, from the database cursor,
193             @param uid: the current user’s ID for security checks,
194             @param data: Get Data
195             @param context: A standard dictionary for contextual values """
196         partner_id = context.get('active_id')
197         query = "select answer from partner_question_rel where partner=%s"
198         cr.execute(query, (partner_id,))
199         for x in cr.fetchall():
200             answers.append(x[0])
201         self.write(cr, uid, [partner_id], {'answers_ids': [[6, 0, answers]]}, context=context)
202         return {}
203
204
205     def write(self, cr, uid, ids, vals, context=None):
206         """
207             @param self: The object pointer
208             @param cr: the current row, from the database cursor,
209             @param uid: the current user’s ID for security checks,
210             @param ids: List of crm profiling’s IDs
211             @param context: A standard dictionary for contextual values """
212
213         if 'answers_ids' in vals:
214             vals['category_id']=[[6, 0, _recompute_categ(self, cr, uid, ids[0], vals['answers_ids'][0][2])]]
215         return super(partner, self).write(cr, uid, ids, vals, context=context)
216
217 partner()
218
219
220 class crm_segmentation(osv.osv):
221     """ CRM Segmentation """
222
223     _inherit="crm.segmentation"
224     _columns={
225         "answer_yes": fields.many2many("crm_profiling.answer","profile_question_yes_rel",\
226                             "profile","answer","Included Answers"),
227         "answer_no": fields.many2many("crm_profiling.answer","profile_question_no_rel",\
228                             "profile","answer","Excluded Answers"),
229         'parent_id': fields.many2one('crm.segmentation', 'Parent Profile'),
230         'child_ids': fields.one2many('crm.segmentation', 'parent_id', 'Child Profiles'),
231         'profiling_active': fields.boolean('Use The Profiling Rules', help='Check\
232                              this box if you want to use this tab as part of the \
233                              segmentation rule. If not checked, the criteria beneath will be ignored')
234         }
235
236     _constraints = [
237         (osv.osv._check_recursion, 'Error ! You cannot create recursive profiles.', ['parent_id'])
238     ]
239
240     def process_continue(self, cr, uid, ids, start=False):
241         """
242             @param self: The object pointer
243             @param cr: the current row, from the database cursor,
244             @param uid: the current user’s ID for security checks,
245             @param ids: List of crm segmentation’s IDs """
246
247         partner_obj = self.pool.get('res.partner')
248         categs = self.read(cr,uid,ids,['categ_id','exclusif','partner_id', \
249                             'sales_purchase_active', 'profiling_active'])
250         for categ in categs:
251             if start:
252                 if categ['exclusif']:
253                     cr.execute('delete from res_partner_res_partner_category_rel where \
254                             category_id=%s', (categ['categ_id'][0],))
255
256             id = categ['id']
257
258             cr.execute('select id from res_partner order by id ')
259             partners = [x[0] for x in cr.fetchall()]
260
261             if categ['sales_purchase_active']:
262                 to_remove_list=[]
263                 cr.execute('select id from crm_segmentation_line where segmentation_id=%s', (id,))
264                 line_ids = [x[0] for x in cr.fetchall()]
265
266                 for pid in partners:
267                     if (not self.pool.get('crm.segmentation.line').test(cr, uid, line_ids, pid)):
268                         to_remove_list.append(pid)
269                 for pid in to_remove_list:
270                     partners.remove(pid)
271
272             if categ['profiling_active']:
273                 to_remove_list = []
274                 for pid in partners:
275
276                     cr.execute('select distinct(answer) from partner_question_rel where partner=%s',(pid,))
277                     answers_ids = [x[0] for x in cr.fetchall()]
278
279                     if (not test_prof(cr, uid, id, pid, answers_ids)):
280                         to_remove_list.append(pid)
281                 for pid in to_remove_list:
282                     partners.remove(pid)
283
284             for partner in partner_obj.browse(cr, uid, partners):
285                 category_ids = [categ_id.id for categ_id in partner.category_id]
286                 if categ['categ_id'][0] not in category_ids:
287                     cr.execute('insert into res_partner_res_partner_category_rel (category_id,partner_id) values (%s,%s)', (categ['categ_id'][0],partner.id))
288
289             self.write(cr, uid, [id], {'state':'not running', 'partner_id':0})
290         return True
291
292 crm_segmentation()
293
294 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
295