[IMP] simplified views
[odoo/odoo.git] / addons / crm / crm_action_rule.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 import time
23 import re
24 import os
25 import base64
26 import tools
27 import mx.DateTime
28
29 from tools.translate import _
30 from osv import fields
31 from osv import osv
32 from osv import orm
33 from osv.orm import except_orm
34
35 import crm
36
37 class case(osv.osv):
38     """ Case """
39
40     _inherit = 'crm.case'
41     _description = 'case'
42
43     _columns = {
44         'date_action_last': fields.datetime('Last Action', readonly=1),
45         'date_action_next': fields.datetime('Next Action', readonly=1),
46     }
47
48     def remind_partner(self, cr, uid, ids, context={}, attach=False):
49
50         """
51         @param self: The object pointer
52         @param cr: the current row, from the database cursor,
53         @param uid: the current user’s ID for security checks,
54         @param ids: List of Remind Partner's IDs
55         @param context: A standard dictionary for contextual values
56
57         """
58         return self.remind_user(cr, uid, ids, context, attach,
59                 destination=False)
60
61     def remind_user(self, cr, uid, ids, context={}, attach=False,destination=True):
62
63         """
64         @param self: The object pointer
65         @param cr: the current row, from the database cursor,
66         @param uid: the current user’s ID for security checks,
67         @param ids: List of Remind user's IDs
68         @param context: A standard dictionary for contextual values
69
70         """
71         for case in self.browse(cr, uid, ids):
72             if not case.section_id.reply_to:
73                 raise osv.except_osv(_('Error!'), ("Reply To is not specified in the sales team"))
74             if not case.email_from:
75                 raise osv.except_osv(_('Error!'), ("Partner Email is not specified in Case"))
76             if case.section_id.reply_to and case.email_from:
77                 src = case.email_from
78                 dest = case.section_id.reply_to
79                 body = ""
80                 body = case.email_last or case.description               
81                 if not destination:
82                     src, dest = dest, src
83                     if body and case.user_id.signature:
84                         body += '\n\n%s' % (case.user_id.signature)
85
86                 body = self.format_body(body)
87                 dest = [dest]
88
89                 attach_to_send = None
90
91                 if attach:
92                     attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model', '=', 'crm.case'), ('res_id', '=', case.id)])
93                     attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname','datas'])
94                     attach_to_send = map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), attach_to_send)
95
96                 # Send an email
97                 flag = tools.email_send(
98                     src,
99                     dest,
100                     "Reminder: [%s] %s" % (str(case.id), case.name, ),
101                     body,
102                     reply_to=case.section_id.reply_to,
103                     openobject_id=str(case.id),
104                     attach=attach_to_send
105                 )
106                 self._history(cr, uid, [case], _('Send'), history=True, email=dest, details=body, email_from=src)
107                 #if flag:
108                 #    raise osv.except_osv(_('Email!'),("Email Successfully Sent"))
109                 #else:
110                 #    raise osv.except_osv(_('Email Fail!'),("Email is not sent successfully"))
111         return True    
112
113     def _check(self, cr, uid, ids=False, context={}):
114         """
115         Function called by the scheduler to process cases for date actions
116         Only works on not done and cancelled cases
117
118         @param self: The object pointer
119         @param cr: the current row, from the database cursor,
120         @param uid: the current user’s ID for security checks,
121         @param context: A standard dictionary for contextual values
122         """
123         cr.execute('select * from crm_case \
124                 where (date_action_last<%s or date_action_last is null) \
125                 and (date_action_next<=%s or date_action_next is null) \
126                 and state not in (\'cancel\',\'done\')',
127                 (time.strftime("%Y-%m-%d %H:%M:%S"),
128                     time.strftime('%Y-%m-%d %H:%M:%S')))
129
130         ids2 = map(lambda x: x[0], cr.fetchall() or [])
131         cases = self.browse(cr, uid, ids2, context)
132         return self._action(cr, uid, cases, False, context=context)
133
134     def _action(self, cr, uid, cases, state_to, scrit=None, context={}):
135         if not context:
136             context = {}
137         context['state_to'] = state_to
138         rule_obj = self.pool.get('base.action.rule')
139         model_obj = self.pool.get('ir.model')
140         model_ids = model_obj.search(cr, uid, [('model','=',self._name)])
141         rule_ids = rule_obj.search(cr, uid, [('name','=',model_ids[0])])
142         return rule_obj._action(cr, uid, rule_ids, cases, scrit=scrit, context=context)
143
144     def format_body(self, body):
145         return self.pool.get('base.action.rule').format_body(body)
146
147     def format_mail(self, obj, body):
148         return self.pool.get('base.action.rule').format_mail(obj, body)
149 case()
150
151 class base_action_rule(osv.osv):
152     """ Base Action Rule """
153     _inherit = 'base.action.rule'
154     _description = 'Action Rules'
155
156     def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from',False), context={}):
157         body = self.format_mail(obj, body)
158         if not emailfrom:
159             if hasattr(obj, 'user_id')  and obj.user_id and obj.user_id.address_id and obj.user_id.address_id.email:
160                 emailfrom = obj.user_id.address_id.email
161             
162         name = '[%d] %s' % (obj.id, tools.ustr(obj.name))
163         emailfrom = tools.ustr(emailfrom)
164         if hasattr(obj, 'section_id') and obj.section_id and obj.section_id.reply_to:
165             reply_to = obj.section_id.reply_to
166         else:
167             reply_to = emailfrom
168         if not emailfrom:
169             raise osv.except_osv(_('Error!'),
170                     _("No E-Mail ID Found for your Company address!"))
171         return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id))
172     
173     def do_check(self, cr, uid, action, obj, context={}):
174
175         """ @param self: The object pointer
176         @param cr: the current row, from the database cursor,
177         @param uid: the current user’s ID for security checks,
178         @param context: A standard dictionary for contextual values"""
179
180         ok = super(base_action_rule, self).do_check(cr, uid, action, obj, context=context)
181
182         if hasattr(obj, 'section_id'):
183             ok = ok and (not action.trg_section_id or action.trg_section_id.id==obj.section_id.id)
184         if hasattr(obj, 'categ_id'):
185             ok = ok and (not action.trg_categ_id or action.trg_categ_id.id==obj.categ_id.id)
186         if hasattr(obj, 'history_line'):
187             ok = ok and (not action.trg_max_history or action.trg_max_history<=(len(obj.history_line)+1))
188             reg_history = action.regex_history
189             result_history = True
190             if reg_history:
191                 ptrn = re.compile(str(reg_history))
192                 if obj.history_line:
193                     _result = ptrn.search(str(obj.history_line[0].description))
194                     if not _result:
195                         result_history = False
196             regex_h = not reg_history or result_history
197             ok = ok and regex_h
198         return ok
199
200     def do_action(self, cr, uid, action, model_obj, obj, context={}):
201
202         """ @param self: The object pointer
203         @param cr: the current row, from the database cursor,
204         @param uid: the current user’s ID for security checks,
205         @param context: A standard dictionary for contextual values """
206
207         res = super(base_action_rule, self).do_action(cr, uid, action, model_obj, obj, context=context)
208         write = {}
209         
210         if hasattr(action, act_section_id) and action.act_section_id:
211             obj.section_id = action.act_section_id
212             write['section_id'] = action.act_section_id.id
213
214         if hasattr(obj, 'email_cc') and action.act_email_cc:
215             if '@' in (obj.email_cc or ''):
216                 emails = obj.email_cc.split(",")
217                 if  obj.act_email_cc not in emails:# and '<'+str(action.act_email_cc)+">" not in emails:
218                     write['email_cc'] = obj.email_cc+','+obj.act_email_cc
219             else:
220                 write['email_cc'] = obj.act_email_cc
221
222         model_obj.write(cr, uid, [obj.id], write, context)
223         emails = []
224
225         if hasattr(obj, 'email_from') and action.act_mail_to_partner:
226             emails.append(obj.email_from)
227         emails = filter(None, emails)
228         if len(emails) and action.act_mail_body:
229             emails = list(set(emails))
230             self.email_send(cr, uid, obj, emails, action.act_mail_body)
231         return True
232
233
234 base_action_rule()
235
236 class base_action_rule_line(osv.osv):
237     """ Base Action Rule Line """
238     _inherit = 'base.action.rule.line'
239     _description = 'Base Action Rule Line'
240
241     def state_get(self, cr, uid, context={}):
242
243         """@param self: The object pointer
244         @param cr: the current row, from the database cursor,
245         @param uid: the current user’s ID for security checks,
246         @param context: A standard dictionary for contextual values """
247
248         res = super(base_action_rule_line, self).state_get(cr, uid, context=context)
249         return res + [('escalate','Escalate')] + crm.AVAILABLE_STATES
250
251     def priority_get(self, cr, uid, context={}):
252
253         """@param self: The object pointer
254         @param cr: the current row, from the database cursor,
255         @param uid: the current user’s ID for security checks,
256         @param context: A standard dictionary for contextual values """
257
258         res = super(base_action_rule_line, self).priority_get(cr, uid, context=context)
259         return res + crm.AVAILABLE_PRIORITIES
260
261     _columns = {
262         'trg_section_id': fields.many2one('crm.case.section', 'Sales Team'),
263         'trg_max_history': fields.integer('Maximum Communication History'),
264         'trg_categ_id':  fields.many2one('crm.case.categ', 'Category'),
265         'regex_history' : fields.char('Regular Expression on Case History', size=128),
266         'act_section_id': fields.many2one('crm.case.section', 'Set Team to'),
267         'act_categ_id': fields.many2one('crm.case.categ', 'Set Category to'),
268         'act_mail_to_partner': fields.boolean('Mail to partner',help="Check this \
269                                 if you want the rule to send an email to the partner."),
270     }
271
272 base_action_rule_line()