[FIX] email_template : Cleaning mailbox send_mail
[odoo/odoo.git] / addons / email_template / email_template_mailbox.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2009 Sharoon Thomas
6 #    Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>
20 #
21 ##############################################################################
22
23 from osv import osv, fields
24 import time
25 import netsvc
26 from tools.translate import _
27 import tools
28 import base64
29
30 LOGGER = netsvc.Logger()
31
32 class email_template_mailbox(osv.osv):
33     _name = "email_template.mailbox"
34     _description = 'Email Mailbox'
35     _rec_name = "subject"
36     _order = "date_mail desc"
37     
38     def run_mail_scheduler(self, cursor, user, context=None):
39         """
40         This method is called by OpenERP Scheduler
41         to periodically send emails
42         """
43         try:
44             self.send_all_mail(cursor, user, context=context)
45         except Exception, e:
46             LOGGER.notifyChannel(
47                                  "Email Template",
48                                  netsvc.LOG_ERROR,
49                                  _("Error sending mail: %s") % e)
50         
51     def send_all_mail(self, cr, uid, ids=None, context=None):
52         if ids is None:
53             ids = []
54         if context is None:
55             context = {}
56         filters = [('folder', '=', 'outbox'), ('state', '!=', 'sending')]
57         if 'filters' in context.keys():
58             for each_filter in context['filters']:
59                 filters.append(each_filter)
60         ids = self.search(cr, uid, filters, context=context)
61         self.write(cr, uid, ids, {'state':'sending'}, context)
62         self.send_this_mail(cr, uid, ids, context)
63         return True
64     
65     def send_this_mail(self, cr, uid, ids=None, context=None):
66         result = True
67         attachment_pool = self.pool.get('ir.attachment')
68         for id in (ids or []):
69             try:
70                 account_obj = self.pool.get('email_template.account')
71                 values = self.read(cr, uid, id, [], context) 
72                 attach_to_send = None
73                 
74                 if values['attachments_ids']:
75                     attach_to_send = self.pool.get('ir.attachment').read(cr, uid, values['attachments_ids'], ['datas_fname','datas', 'name'])
76                     attach_to_send = map(lambda x: (x['datas_fname'] or x['name'], base64.decodestring(x['datas'])), attach_to_send)
77                 
78                 if values.get('body_html'):
79                     body = values.get('body_html')
80                     subtype = "html"
81                 else :
82                     body = values.get('body_text')
83                     subtype = "plain"
84                     
85                 result = tools.email_send(
86                     values.get('email_from') or u'',
87                     [values.get('email_to')],
88                     values['subject'] or u'', 
89                     body or u'',
90                     reply_to=values.get('reply_to') or u'',
91                     email_bcc=values.get('email_bcc') or u'',
92                     email_cc=values.get('email_cc') or u'',
93                     subtype=subtype,
94                     attach=attach_to_send,
95                     openobject_id=values['message_id']
96                 )
97                 
98
99                 if result == True:
100                     account = account_obj.browse(cr, uid, values['account_id'][0], context=context)
101                     if account.auto_delete:
102                         self.write(cr, uid, id, {'folder': 'trash'}, context=context)
103                         self.unlink(cr, uid, [id], context=context)
104                         # Remove attachments for this mail
105                         attachment_pool.unlink(cr, uid, values['attachments_ids'], context=context)
106                     else:
107                         self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context)
108                         self.historise(cr, uid, [id], "Email sent successfully", context)
109                 else:
110                     error = result['error_msg']
111                     self.historise(cr, uid, [id], error, context)
112                     
113             except Exception, error:
114                 logger = netsvc.Logger()
115                 logger.notifyChannel("email-template", netsvc.LOG_ERROR, _("Sending of Mail %s failed. Probable Reason:Could not login to server\nError: %s") % (id, error))
116                 self.historise(cr, uid, [id], error, context)
117             self.write(cr, uid, id, {'state':'na'}, context)
118         return result
119     
120     def historise(self, cr, uid, ids, message='', context=None):
121         for id in ids:
122             history = self.read(cr, uid, id, ['history'], context).get('history', '')
123             self.write(cr, uid, id, {'history': (history or '' )+ "\n" + time.strftime("%Y-%m-%d %H:%M:%S") + ": " + tools.ustr(message)}, context)
124     
125     _columns = {
126             'email_from':fields.char(
127                             'From', 
128                             size=64),
129             'email_to':fields.char(
130                             'Recipient (To)', 
131                             size=250,),
132             'email_cc':fields.char(
133                             'CC', 
134                             size=250),
135             'email_bcc':fields.char(
136                             'BCC', 
137                             size=250),
138             'reply_to':fields.char(
139                             'Reply-To', 
140                             size=250),
141             'message_id':fields.char(
142                             'Message-ID', 
143                             size=250),
144             'subject':fields.char(
145                             'Subject', 
146                             size=200,),
147             'body_text':fields.text(
148                             'Standard Body (Text)'),
149             'body_html':fields.text(
150                             'Body (Rich Text Clients Only)'),
151             'attachments_ids':fields.many2many(
152                             'ir.attachment', 
153                             'mail_attachments_rel', 
154                             'mail_id', 
155                             'att_id', 
156                             'Attachments'),
157             'account_id' :fields.many2one(
158                             'email_template.account',
159                             'User account', 
160                             required=True),
161             'user':fields.related(
162                             'account_id', 
163                             'user', 
164                             type="many2one", 
165                             relation="res.users", 
166                             string="User"),
167             'server_ref':fields.integer(
168                             'Server Reference of mail', 
169                             help="Applicable for inward items only"),
170             'mail_type':fields.selection([
171                             ('multipart/mixed', 
172                              'Has Attachments'),
173                             ('multipart/alternative', 
174                              'Plain Text & HTML with no attachments'),
175                             ('multipart/related', 
176                              'Intermixed content'),
177                             ('text/plain', 
178                              'Plain Text'),
179                             ('text/html', 
180                              'HTML Body'),
181                             ], 'Mail Contents'),
182             #I like GMAIL which allows putting same mail in many folders
183             #Lets plan it for 0.9
184             'folder':fields.selection([
185                             ('drafts', 'Drafts'),
186                             ('outbox', 'Outbox'),
187                             ('trash', 'Trash'),
188                             ('sent', 'Sent Items'),
189                             ], 'Folder', required=True),
190             'state':fields.selection([
191                             ('na', 'Not Applicable'),
192                             ('sending', 'Sending'),
193                             ], 'Status', required=True),
194             'date_mail':fields.datetime('Rec/Sent Date', help="Date on which Email Sent or Received"),
195             'history':fields.text(
196                             'History', 
197                             readonly=True, 
198                             store=True)
199         }
200
201     _defaults = {
202         'state': lambda * a: 'na',
203         'folder': lambda * a: 'outbox',
204     } 
205
206     def unlink(self, cr, uid, ids, context=None):
207         """
208         It just changes the folder of the item to "Trash", if it is no in Trash folder yet, 
209         or completely deletes it if it is already in Trash.
210         """
211         to_update = []
212         to_remove = []
213         for mail in self.browse(cr, uid, ids, context=context):
214             if mail.folder == 'trash':
215                 to_remove.append(mail.id)
216             else:
217                 to_update.append(mail.id)
218         # Changes the folder to trash
219         self.write(cr, uid, to_update, {'folder': 'trash'}, context=context)
220         return super(email_template_mailbox, self).unlink(cr, uid, to_remove, context=context)
221
222 email_template_mailbox()
223
224 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: