[MERGE] merge from trunk addons
[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         #previous method to send email (link with email account can be found at the revision 4172 and below
67         result = True
68         attachment_pool = self.pool.get('ir.attachment')
69         for id in (ids or []):
70             try:
71                 account_obj = self.pool.get('email_template.account')
72                 values = self.read(cr, uid, id, [], context) 
73                 attach_to_send = None
74                 
75                 if values['attachments_ids']:
76                     attach_to_send = self.pool.get('ir.attachment').read(cr, uid, values['attachments_ids'], ['datas_fname','datas', 'name'])
77                     attach_to_send = map(lambda x: (x['datas_fname'] or x['name'], base64.decodestring(x['datas'])), attach_to_send)
78                 
79                 if values.get('body_html'):
80                     body = values.get('body_html')
81                     subtype = "html"
82                 else :
83                     body = values.get('body_text')
84                     subtype = "plain"
85                     
86                 result = tools.email_send(
87                     values.get('email_from') or u'',
88                     [values.get('email_to')],
89                     values['subject'] or u'', 
90                     body or u'',
91                     reply_to=values.get('reply_to') or u'',
92                     email_bcc=values.get('email_bcc') or u'',
93                     email_cc=values.get('email_cc') or u'',
94                     subtype=subtype,
95                     attach=attach_to_send,
96                     openobject_id=values['message_id']
97                 )
98                 
99
100                 if result == True:
101                     account = account_obj.browse(cr, uid, values['account_id'][0], context=context)
102                     if account.auto_delete:
103                         self.write(cr, uid, id, {'folder': 'trash'}, context=context)
104                         self.unlink(cr, uid, [id], context=context)
105                         # Remove attachments for this mail
106                         attachment_pool.unlink(cr, uid, values['attachments_ids'], context=context)
107                     else:
108                         self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context)
109                         self.historise(cr, uid, [id], "Email sent successfully", context)
110                 else:
111                     error = result['error_msg']
112                     self.historise(cr, uid, [id], error, context)
113                     
114             except Exception, error:
115                 logger = netsvc.Logger()
116                 logger.notifyChannel("email-template", netsvc.LOG_ERROR, _("Sending of Mail %s failed. Probable Reason:Could not login to server\nError: %s") % (id, error))
117                 self.historise(cr, uid, [id], error, context)
118             self.write(cr, uid, id, {'state':'na'}, context)
119         return result
120     
121     def historise(self, cr, uid, ids, message='', context=None):
122         for id in ids:
123             history = self.read(cr, uid, id, ['history'], context).get('history', '')
124             self.write(cr, uid, id, {'history': (history or '' )+ "\n" + time.strftime("%Y-%m-%d %H:%M:%S") + ": " + tools.ustr(message)}, context)
125     
126     _columns = {
127             'email_from':fields.char(
128                             'From', 
129                             size=64),
130             'email_to':fields.char(
131                             'Recipient (To)', 
132                             size=250,),
133             'email_cc':fields.char(
134                             'CC', 
135                             size=250),
136             'email_bcc':fields.char(
137                             'BCC', 
138                             size=250),
139             'reply_to':fields.char(
140                             'Reply-To', 
141                             size=250),
142             'message_id':fields.char(
143                             'Message-ID', 
144                             size=250),
145             'subject':fields.char(
146                             'Subject', 
147                             size=200,),
148             'body_text':fields.text(
149                             'Standard Body (Text)'),
150             'body_html':fields.text(
151                             'Body (Rich Text Clients Only)'),
152             'attachments_ids':fields.many2many(
153                             'ir.attachment', 
154                             'mail_attachments_rel', 
155                             'mail_id', 
156                             'att_id', 
157                             'Attachments'),
158             'account_id' :fields.many2one(
159                             'email_template.account',
160                             'User account', 
161                             required=True),
162             'user':fields.related(
163                             'account_id', 
164                             'user', 
165                             type="many2one", 
166                             relation="res.users", 
167                             string="User"),
168             'server_ref':fields.integer(
169                             'Server Reference of mail', 
170                             help="Applicable for inward items only"),
171             'mail_type':fields.selection([
172                             ('multipart/mixed', 
173                              'Has Attachments'),
174                             ('multipart/alternative', 
175                              'Plain Text & HTML with no attachments'),
176                             ('multipart/related', 
177                              'Intermixed content'),
178                             ('text/plain', 
179                              'Plain Text'),
180                             ('text/html', 
181                              'HTML Body'),
182                             ], 'Mail Contents'),
183             #I like GMAIL which allows putting same mail in many folders
184             #Lets plan it for 0.9
185             'folder':fields.selection([
186                             ('drafts', 'Drafts'),
187                             ('outbox', 'Outbox'),
188                             ('trash', 'Trash'),
189                             ('sent', 'Sent Items'),
190                             ], 'Folder', required=True),
191             'state':fields.selection([
192                             ('na', 'Not Applicable'),
193                             ('sending', 'Sending'),
194                             ], 'Status', required=True),
195             'date_mail':fields.datetime('Rec/Sent Date', help="Date on which Email Sent or Received"),
196             'history':fields.text(
197                             'History', 
198                             readonly=True, 
199                             store=True)
200         }
201
202     _defaults = {
203         'state': lambda * a: 'na',
204         'folder': lambda * a: 'outbox',
205     } 
206
207     def unlink(self, cr, uid, ids, context=None):
208         """
209         It just changes the folder of the item to "Trash", if it is no in Trash folder yet, 
210         or completely deletes it if it is already in Trash.
211         """
212         to_update = []
213         to_remove = []
214         for mail in self.browse(cr, uid, ids, context=context):
215             if mail.folder == 'trash':
216                 to_remove.append(mail.id)
217             else:
218                 to_update.append(mail.id)
219         # Changes the folder to trash
220         self.write(cr, uid, to_update, {'folder': 'trash'}, context=context)
221         return super(email_template_mailbox, self).unlink(cr, uid, to_remove, context=context)
222
223 email_template_mailbox()
224
225 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: