[MERGE] Merge with lp:openobject-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
29 LOGGER = netsvc.Logger()
30
31 class email_template_mailbox(osv.osv):
32     _name = "email_template.mailbox"
33     _description = 'Email Mailbox'
34     _rec_name = "subject"
35     _order = "date_mail desc"
36     
37     def run_mail_scheduler(self, cursor, user, context=None):
38         """
39         This method is called by OpenERP Scheduler
40         to periodically send emails
41         """
42         try:
43             self.send_all_mail(cursor, user, context=context)
44         except Exception, e:
45             LOGGER.notifyChannel(
46                                  "Email Template",
47                                  netsvc.LOG_ERROR,
48                                  _("Error sending mail: %s") % e)
49         
50     def send_all_mail(self, cr, uid, ids=None, context=None):
51         if ids is None:
52             ids = []
53         if context is None:
54             context = {}
55         filters = [('folder', '=', 'outbox'), ('state', '!=', 'sending')]
56         if 'filters' in context.keys():
57             for each_filter in context['filters']:
58                 filters.append(each_filter)
59         ids = self.search(cr, uid, filters, context=context)
60         self.write(cr, uid, ids, {'state':'sending'}, context)
61         self.send_this_mail(cr, uid, ids, context)
62         return True
63
64     def send_this_mail(self, cr, uid, ids=None, context=None):
65         #previous method to send email (link with email account can be found at the revision 4172 and below
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                 payload = {}
73                 if values['attachments_ids']:
74                     for attid in values['attachments_ids']:
75                         attachment = attachment_pool.browse(cr, uid, attid, context)#,['datas_fname','datas'])
76                         payload[attachment.datas_fname] = attachment.datas
77                 result = account_obj.send_mail(cr, uid,
78                               [values['account_id'][0]],
79                               {'To':values.get('email_to') or u'',
80                                'CC':values.get('email_cc') or u'',
81                                'BCC':values.get('email_bcc') or u'',
82                                'Reply-To':values.get('reply_to') or u''},
83                               values['subject'] or u'',
84                               {'text':values.get('body_text') or u'', 'html':values.get('body_html') or u''},
85                               payload=payload,
86                               message_id=values['message_id'],
87                               context=context)
88                 if result == True:
89                     account = account_obj.browse(cr, uid, values['account_id'][0], context=context)
90                     if account.auto_delete:
91                         self.write(cr, uid, id, {'folder': 'trash'}, context=context)
92                         self.unlink(cr, uid, [id], context=context)
93                         # Remove attachments for this mail
94                         attachment_pool.unlink(cr, uid, values['attachments_ids'], context=context)
95                     else:
96                         self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context)
97                         self.historise(cr, uid, [id], "Email sent successfully", context)
98                 else:
99                     error = result['error_msg']
100                     self.historise(cr, uid, [id], error, context)
101                     
102             except Exception, error:
103                 logger = netsvc.Logger()
104                 logger.notifyChannel("email-template", netsvc.LOG_ERROR, _("Sending of Mail %s failed. Probable Reason:Could not login to server\nError: %s") % (id, error))
105                 self.historise(cr, uid, [id], error, context)
106             self.write(cr, uid, id, {'state':'na'}, context)
107         return result
108     
109     def historise(self, cr, uid, ids, message='', context=None):
110         for id in ids:
111             history = self.read(cr, uid, id, ['history'], context).get('history', '')
112             self.write(cr, uid, id, {'history': (history or '' )+ "\n" + time.strftime("%Y-%m-%d %H:%M:%S") + ": " + tools.ustr(message)}, context)
113     
114     _columns = {
115             'email_from':fields.char(
116                             'From', 
117                             size=64),
118             'email_to':fields.char(
119                             'Recipient (To)', 
120                             size=250,),
121             'email_cc':fields.char(
122                             'CC', 
123                             size=250),
124             'email_bcc':fields.char(
125                             'BCC', 
126                             size=250),
127             'reply_to':fields.char(
128                             'Reply-To', 
129                             size=250),
130             'message_id':fields.char(
131                             'Message-ID', 
132                             size=250),
133             'subject':fields.char(
134                             'Subject', 
135                             size=200,),
136             'body_text':fields.text(
137                             'Standard Body (Text)'),
138             'body_html':fields.text(
139                             'Body (Rich Text Clients Only)'),
140             'attachments_ids':fields.many2many(
141                             'ir.attachment', 
142                             'mail_attachments_rel', 
143                             'mail_id', 
144                             'att_id', 
145                             'Attachments'),
146             'account_id' :fields.many2one(
147                             'email_template.account',
148                             'User account', 
149                             required=True),
150             'user':fields.related(
151                             'account_id', 
152                             'user', 
153                             type="many2one", 
154                             relation="res.users", 
155                             string="User"),
156             'server_ref':fields.integer(
157                             'Server Reference of mail', 
158                             help="Applicable for inward items only"),
159             'mail_type':fields.selection([
160                             ('multipart/mixed', 
161                              'Has Attachments'),
162                             ('multipart/alternative', 
163                              'Plain Text & HTML with no attachments'),
164                             ('multipart/related', 
165                              'Intermixed content'),
166                             ('text/plain', 
167                              'Plain Text'),
168                             ('text/html', 
169                              'HTML Body'),
170                             ], 'Mail Contents'),
171             #I like GMAIL which allows putting same mail in many folders
172             #Lets plan it for 0.9
173             'folder':fields.selection([
174                             ('drafts', 'Drafts'),
175                             ('outbox', 'Outbox'),
176                             ('trash', 'Trash'),
177                             ('sent', 'Sent Items'),
178                             ], 'Folder', required=True),
179             'state':fields.selection([
180                             ('na', 'Not Applicable'),
181                             ('sending', 'Sending'),
182                             ], 'Status', required=True),
183             'date_mail':fields.datetime('Rec/Sent Date', help="Date on which Email Sent or Received"),
184             'history':fields.text(
185                             'History', 
186                             readonly=True, 
187                             store=True)
188         }
189
190     _defaults = {
191         'state': lambda * a: 'na',
192         'folder': lambda * a: 'outbox',
193     } 
194
195     def unlink(self, cr, uid, ids, context=None):
196         """
197         It just changes the folder of the item to "Trash", if it is no in Trash folder yet, 
198         or completely deletes it if it is already in Trash.
199         """
200         to_update = []
201         to_remove = []
202         for mail in self.browse(cr, uid, ids, context=context):
203             if mail.folder == 'trash':
204                 to_remove.append(mail.id)
205             else:
206                 to_update.append(mail.id)
207         # Changes the folder to trash
208         self.write(cr, uid, to_update, {'folder': 'trash'}, context=context)
209         return super(email_template_mailbox, self).unlink(cr, uid, to_remove, context=context)
210
211 email_template_mailbox()
212
213 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: