[IMP] email_template: review + many improvements:
- Support for specifying Reply-To and Message-ID headers in templates - Restored the proper GPLv3 copyright from Sharoon Thomas (mistakenly switched to AGPL) - Minor refactoring/cleanup/renaming - Support for multipart/alternative format when sending emails, including wrapped inside multipart/mixed if attachments are present - Support for plain attachments (existing files) in addition to reports - Support for specifying "From" email in "Name <email>" format in addition to using the label on the Email Account bzr revid: odo@openerp.com-20100818152227-i823jbspioqwr1kk
This commit is contained in:
parent
195ac98256
commit
84aea26e88
|
@ -2,21 +2,21 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
|
|
@ -2,21 +2,21 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
|
|
@ -2,29 +2,28 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import base64
|
||||
import random
|
||||
import time
|
||||
import types
|
||||
import netsvc
|
||||
import re
|
||||
|
||||
LOGGER = netsvc.Logger()
|
||||
|
||||
|
@ -58,9 +57,7 @@ except:
|
|||
_("Django templates not installed")
|
||||
)
|
||||
|
||||
import email_template_engines
|
||||
import tools
|
||||
import report
|
||||
import pooler
|
||||
import logging
|
||||
|
||||
|
@ -128,29 +125,38 @@ class email_template(osv.osv):
|
|||
'name' : fields.char('Name', size=100, required=True),
|
||||
'object_name':fields.many2one('ir.model', 'Model'),
|
||||
'model_int_name':fields.char('Model Internal Name', size=200,),
|
||||
'enforce_from_account':fields.many2one(
|
||||
'from_account':fields.many2one(
|
||||
'email_template.account',
|
||||
string="Enforce From Account",
|
||||
help="Emails will be sent only from this account(which are approved)."),
|
||||
'from_email' : fields.related('enforce_from_account', 'email_id',
|
||||
type='char', string='From',
|
||||
help='From Email (select mail account)',
|
||||
readonly=True),
|
||||
string="Email Account",
|
||||
help="Emails will be sent from this approved account."),
|
||||
'def_to':fields.char(
|
||||
'Recipient (To)',
|
||||
size=250,
|
||||
help="The default recipient of email."
|
||||
"Placeholders can be used here."),
|
||||
'def_cc':fields.char(
|
||||
'Default CC',
|
||||
'CC',
|
||||
size=250,
|
||||
help="The default CC for the email."
|
||||
help="Carbon Copy address(es), comma-separated."
|
||||
" Placeholders can be used here."),
|
||||
'def_bcc':fields.char(
|
||||
'Default BCC',
|
||||
'BCC',
|
||||
size=250,
|
||||
help="The default BCC for the email."
|
||||
help="Blind Carbon Copy address(es), comma-separated."
|
||||
" Placeholders can be used here."),
|
||||
'reply_to':fields.char('Reply-To',
|
||||
size=250,
|
||||
help="The address recipients should reply to,"
|
||||
" if different from the From address."
|
||||
" Placeholders can be used here."),
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
help="The Message-ID header value, if you need to"
|
||||
"specify it, for example to automatically recognize the replies later."
|
||||
" Placeholders can be used here."),
|
||||
'track_campaign_item':fields.boolean('Track campaign items',
|
||||
help="Enable this if you want the outgoing e-mails to include a tracking"
|
||||
" marker that makes it possible to identify the replies an link them back to the campaign item"),
|
||||
'lang':fields.char(
|
||||
'Language',
|
||||
size=250,
|
||||
|
@ -184,6 +190,14 @@ class email_template(osv.osv):
|
|||
'report_template':fields.many2one(
|
||||
'ir.actions.report.xml',
|
||||
'Report to send'),
|
||||
'attachment_ids': fields.many2many(
|
||||
'ir.attachment',
|
||||
'email_template_attachment_rel',
|
||||
'email_template_id',
|
||||
'attachment_id',
|
||||
'Attached Files',
|
||||
help="You may attach existing files to this template, "
|
||||
"so they will be added in all emails created from this template"),
|
||||
'ref_ir_act_window':fields.many2one(
|
||||
'ir.actions.act_window',
|
||||
'Window Action',
|
||||
|
@ -430,7 +444,37 @@ class email_template(osv.osv):
|
|||
result['sub_model_object_field'] = False
|
||||
result['null_value'] = null_value
|
||||
return {'value':result}
|
||||
|
||||
|
||||
def _add_attachment(self, cursor, user, mailbox_id, name, data, filename, context=None):
|
||||
"""
|
||||
Add an attachment to a given mailbox entry.
|
||||
|
||||
:param data: base64 encoded attachment data to store
|
||||
"""
|
||||
attachment_obj = self.pool.get('ir.attachment')
|
||||
attachment_data = {
|
||||
'name': (name or '') + _(' (Email Attachment)'),
|
||||
'datas': data,
|
||||
'datas_fname': filename,
|
||||
'description': name or _('No Description'),
|
||||
'res_model':'email_template.mailbox',
|
||||
'res_id': mailbox_id,
|
||||
}
|
||||
attachment_id = attachment_obj.create(cursor,
|
||||
user,
|
||||
attachment_data,
|
||||
context)
|
||||
if attachment_id:
|
||||
self.pool.get('email_template.mailbox').write(
|
||||
cursor,
|
||||
user,
|
||||
mailbox_id,
|
||||
{
|
||||
'attachments_ids':[(4, attachment_id)],
|
||||
'mail_type':'multipart/mixed'
|
||||
},
|
||||
context)
|
||||
|
||||
def generate_attach_reports(self,
|
||||
cursor,
|
||||
user,
|
||||
|
@ -440,7 +484,7 @@ class email_template(osv.osv):
|
|||
context=None):
|
||||
"""
|
||||
Generate report to be attached and attach it
|
||||
to the email
|
||||
to the email, and add any directly attached files as well.
|
||||
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of User
|
||||
|
@ -452,54 +496,34 @@ class email_template(osv.osv):
|
|||
@param mail: Browse record of email object
|
||||
@return: True
|
||||
"""
|
||||
reportname = 'report.' + \
|
||||
self.pool.get('ir.actions.report.xml').read(
|
||||
cursor,
|
||||
user,
|
||||
template.report_template.id,
|
||||
['report_name'],
|
||||
context)['report_name']
|
||||
service = netsvc.LocalService(reportname)
|
||||
data = {}
|
||||
data['model'] = template.model_int_name
|
||||
(result, format) = service.create(cursor,
|
||||
user,
|
||||
[record_id],
|
||||
data,
|
||||
context)
|
||||
attachment_obj = self.pool.get('ir.attachment')
|
||||
|
||||
fname = tools.ustr(get_value(cursor, user, record_id,
|
||||
template.file_name, template, context)
|
||||
or 'Report')
|
||||
ext = '.' + format
|
||||
if not fname.endswith(ext):
|
||||
fname += ext
|
||||
|
||||
new_att_vals = {
|
||||
'name':mail.subject + ' (Email Attachment)',
|
||||
'datas':base64.b64encode(result),
|
||||
'datas_fname': fname,
|
||||
'description':mail.subject or "No Description",
|
||||
'res_model':'email_template.mailbox',
|
||||
'res_id':mail.id
|
||||
}
|
||||
attachment_id = attachment_obj.create(cursor,
|
||||
if template.report_template:
|
||||
reportname = 'report.' + \
|
||||
self.pool.get('ir.actions.report.xml').read(
|
||||
cursor,
|
||||
user,
|
||||
template.report_template.id,
|
||||
['report_name'],
|
||||
context)['report_name']
|
||||
service = netsvc.LocalService(reportname)
|
||||
data = {}
|
||||
data['model'] = template.model_int_name
|
||||
(result, format) = service.create(cursor,
|
||||
user,
|
||||
new_att_vals,
|
||||
context)
|
||||
if attachment_id:
|
||||
self.pool.get('email_template.mailbox').write(
|
||||
cursor,
|
||||
user,
|
||||
mail.id,
|
||||
{
|
||||
'attachments_ids':[
|
||||
[6, 0, [attachment_id]]
|
||||
],
|
||||
'mail_type':'multipart/mixed'
|
||||
},
|
||||
context)
|
||||
[record_id],
|
||||
data,
|
||||
context)
|
||||
fname = tools.ustr(get_value(cursor, user, record_id,
|
||||
template.file_name, template, context)
|
||||
or 'Report')
|
||||
ext = '.' + format
|
||||
if not fname.endswith(ext):
|
||||
fname += ext
|
||||
self._add_attachment(cursor, user, mail.id, mail.subject, base64.b64encode(result), fname, context)
|
||||
|
||||
if template.attachment_ids:
|
||||
for attachment in template.attachment_ids:
|
||||
self._add_attachment(cursor, user, mail.id, attachment.name, attachment.datas, attachment.datas_fname, context)
|
||||
|
||||
return True
|
||||
|
||||
def _generate_mailbox_item_from_template(self,
|
||||
|
@ -534,9 +558,9 @@ class email_template(osv.osv):
|
|||
)
|
||||
else:
|
||||
from_account = {
|
||||
'id':template.enforce_from_account.id,
|
||||
'name':template.enforce_from_account.name,
|
||||
'email_id':template.enforce_from_account.email_id
|
||||
'id':template.from_account.id,
|
||||
'name':template.from_account.name,
|
||||
'email_id':template.from_account.email_id
|
||||
}
|
||||
lang = get_value(cursor,
|
||||
user,
|
||||
|
@ -548,9 +572,21 @@ class email_template(osv.osv):
|
|||
ctx = context.copy()
|
||||
ctx.update({'lang':lang})
|
||||
template = self.browse(cursor, user, template.id, context=ctx)
|
||||
|
||||
# determine name of sender, either it is specified in email_id or we
|
||||
# use the account name
|
||||
email_id = from_account['email_id'].strip()
|
||||
email_from = re.findall(r'([^ ,<@]+@[^> ,]+)', email_id)[0]
|
||||
if email_from != email_id:
|
||||
# we should keep it all, name is probably specified in the address
|
||||
email_from = from_account['email_id']
|
||||
else:
|
||||
email_from = tools.ustr(from_account['name']) + "<" + tools.ustr('email_id') + ">",
|
||||
|
||||
# FIXME: should do this in a loop and rename template fields to the corresponding
|
||||
# mailbox fields. (makes no sense to have different names I think.
|
||||
mailbox_values = {
|
||||
'email_from': tools.ustr(from_account['name']) + \
|
||||
"<" + tools.ustr(from_account['email_id']) + ">",
|
||||
'email_from': email_from,
|
||||
'email_to':get_value(cursor,
|
||||
user,
|
||||
record_id,
|
||||
|
@ -569,6 +605,12 @@ class email_template(osv.osv):
|
|||
template.def_bcc,
|
||||
template,
|
||||
context),
|
||||
'reply_to':get_value(cursor,
|
||||
user,
|
||||
record_id,
|
||||
template.reply_to,
|
||||
template,
|
||||
context),
|
||||
'subject':get_value(cursor,
|
||||
user,
|
||||
record_id,
|
||||
|
@ -591,8 +633,13 @@ class email_template(osv.osv):
|
|||
#This is a mandatory field when automatic emails are sent
|
||||
'state':'na',
|
||||
'folder':'drafts',
|
||||
'mail_type':'multipart/alternative'
|
||||
'mail_type':'multipart/alternative',
|
||||
}
|
||||
|
||||
if template['track_campaign_item']:
|
||||
# get appropriate message-id
|
||||
mailbox_values.update(message_id=tools.misc.generate_tracking_message_id(record_id))
|
||||
|
||||
if not mailbox_values['account_id']:
|
||||
raise Exception("Unable to send the mail. No account linked to the template.")
|
||||
#Use signatures if allowed
|
||||
|
@ -627,6 +674,7 @@ class email_template(osv.osv):
|
|||
if not template:
|
||||
raise Exception("The requested template could not be loaded")
|
||||
result = True
|
||||
mailbox_obj = self.pool.get('email_template.mailbox')
|
||||
for record_id in record_ids:
|
||||
mailbox_id = self._generate_mailbox_item_from_template(
|
||||
cursor,
|
||||
|
@ -634,13 +682,13 @@ class email_template(osv.osv):
|
|||
template,
|
||||
record_id,
|
||||
context)
|
||||
mail = self.pool.get('email_template.mailbox').browse(
|
||||
cursor,
|
||||
user,
|
||||
mailbox_id,
|
||||
context=context
|
||||
)
|
||||
if template.report_template:
|
||||
mail = mailbox_obj.browse(
|
||||
cursor,
|
||||
user,
|
||||
mailbox_id,
|
||||
context=context
|
||||
)
|
||||
if template.report_template or template.attachment_ids:
|
||||
self.generate_attach_reports(
|
||||
cursor,
|
||||
user,
|
||||
|
@ -649,6 +697,7 @@ class email_template(osv.osv):
|
|||
mail,
|
||||
context
|
||||
)
|
||||
|
||||
self.pool.get('email_template.mailbox').write(
|
||||
cursor,
|
||||
user,
|
||||
|
@ -662,6 +711,10 @@ class email_template(osv.osv):
|
|||
|
||||
email_template()
|
||||
|
||||
|
||||
## FIXME: this class duplicates a lot of features of the email template send wizard,
|
||||
## one of the 2 should inherit from the other!
|
||||
|
||||
class email_template_preview(osv.osv_memory):
|
||||
_name = "email_template.preview"
|
||||
_description = "Email Template Preview"
|
||||
|
@ -674,10 +727,15 @@ class email_template_preview(osv.osv_memory):
|
|||
if 'template_id' in context.keys():
|
||||
ref_obj_id = self.pool.get('email.template').read(cr, uid, context['template_id'], ['object_name'], context)
|
||||
ref_obj_name = self.pool.get('ir.model').read(cr, uid, ref_obj_id['object_name'][0], ['model'], context)['model']
|
||||
ref_obj_ids = self.pool.get(ref_obj_name).search(cr, uid, [], 0, 20, 'id desc', context=context)
|
||||
ref_obj_recs = self.pool.get(ref_obj_name).name_get(cr, uid, ref_obj_ids, context)
|
||||
return ref_obj_recs
|
||||
|
||||
model_obj = self.pool.get(ref_obj_name)
|
||||
ref_obj_ids = model_obj.search(cr, uid, [], 0, 20, 'id desc', context=context)
|
||||
|
||||
# also add the default one if requested, otherwise it won't be available for selection:
|
||||
default_id = context.get('default_rel_model_ref')
|
||||
if default_id and default_id not in ref_obj_ids:
|
||||
ref_obj_ids.insert(0, default_id)
|
||||
return model_obj.name_get(cr, uid, ref_obj_ids, context)
|
||||
|
||||
def _default_model(self, cursor, user, context=None):
|
||||
"""
|
||||
Returns the default value for model field
|
||||
|
@ -701,6 +759,16 @@ class email_template_preview(osv.osv_memory):
|
|||
'to':fields.char('To', size=250, readonly=True),
|
||||
'cc':fields.char('CC', size=250, readonly=True),
|
||||
'bcc':fields.char('BCC', size=250, readonly=True),
|
||||
'reply_to':fields.char('Reply-To',
|
||||
size=250,
|
||||
help="The address recipients should reply to,"
|
||||
" if different from the From address."
|
||||
" Placeholders can be used here."),
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
help="The Message-ID header value, if you need to"
|
||||
"specify it, for example to automatically recognize the replies later."
|
||||
" Placeholders can be used here."),
|
||||
'subject':fields.char('Subject', size=200, readonly=True),
|
||||
'body_text':fields.text('Body', readonly=True),
|
||||
'body_html':fields.text('Body', readonly=True),
|
||||
|
@ -728,6 +796,11 @@ class email_template_preview(osv.osv_memory):
|
|||
vals['to'] = get_value(cr, uid, rel_model_ref, template.def_to, template, context)
|
||||
vals['cc'] = get_value(cr, uid, rel_model_ref, template.def_cc, template, context)
|
||||
vals['bcc'] = get_value(cr, uid, rel_model_ref, template.def_bcc, template, context)
|
||||
vals['reply_to'] = get_value(cr, uid, rel_model_ref, template.reply_to, template, context)
|
||||
if template.message_id:
|
||||
vals['message_id'] = get_value(cr, uid, rel_model_ref, template.message_id, template, context)
|
||||
elif template.track_campaign_item:
|
||||
vals['message_id'] = tools.misc.generate_tracking_message_id(rel_model_ref)
|
||||
vals['subject'] = get_value(cr, uid, rel_model_ref, template.def_subject, template, context)
|
||||
vals['body_text'] = get_value(cr, uid, rel_model_ref, template.def_body_text, template, context)
|
||||
vals['body_html'] = get_value(cr, uid, rel_model_ref, template.def_body_html, template, context)
|
||||
|
|
|
@ -2,26 +2,25 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
from html2text import html2text
|
||||
import re
|
||||
import smtplib
|
||||
import base64
|
||||
|
@ -31,12 +30,8 @@ from email.mime.multipart import MIMEMultipart
|
|||
from email.mime.text import MIMEText
|
||||
from email.header import decode_header, Header
|
||||
from email.utils import formatdate
|
||||
import re
|
||||
import netsvc
|
||||
import string
|
||||
import email
|
||||
import time, datetime
|
||||
import email_template_engines
|
||||
import datetime
|
||||
from tools.translate import _
|
||||
import tools
|
||||
|
||||
|
@ -86,9 +81,10 @@ class email_template_account(osv.osv):
|
|||
'smtpssl':fields.boolean('SSL/TLS (only in python 2.6)',
|
||||
states={'draft':[('readonly', False)]}, readonly=True),
|
||||
'send_pref':fields.selection([
|
||||
('html', 'HTML otherwise Text'),
|
||||
('text', 'Text otherwise HTML'),
|
||||
('both', 'Both HTML & Text')
|
||||
('html', 'HTML, otherwise Text'),
|
||||
('text', 'Text, otherwise HTML'),
|
||||
('alternative', 'Both HTML & Text (Alternative)'),
|
||||
('mixed', 'Both HTML & Text (Mixed)')
|
||||
], 'Mail Format', required=True),
|
||||
'company':fields.selection([
|
||||
('yes', 'Yes'),
|
||||
|
@ -135,7 +131,10 @@ class email_template_account(osv.osv):
|
|||
'unique (email_id)',
|
||||
'Another setting already exists with this email ID !')
|
||||
]
|
||||
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
return dict([(a["id"], "%s (%s)" % (a['email_id'], a['name'])) for a in self.read(cr, uid, ids, ['name', 'email_id'], context=context)])
|
||||
|
||||
def _constraint_unique(self, cursor, user, ids):
|
||||
"""
|
||||
This makes sure that you dont give personal
|
||||
|
@ -283,7 +282,7 @@ class email_template_account(osv.osv):
|
|||
TODO: Doc this
|
||||
"""
|
||||
result = {'all':[]}
|
||||
keys = ['To', 'CC', 'BCC']
|
||||
keys = ['To', 'CC', 'BCC', 'Reply-To']
|
||||
for each in keys:
|
||||
ids_as_list = self.split_to_ids(addresses.get(each, u''))
|
||||
while u'' in ids_as_list:
|
||||
|
@ -292,7 +291,7 @@ class email_template_account(osv.osv):
|
|||
result['all'].extend(ids_as_list)
|
||||
return result
|
||||
|
||||
def send_mail(self, cr, uid, ids, addresses, subject='', body=None, payload=None, context=None):
|
||||
def send_mail(self, cr, uid, ids, addresses, subject='', body=None, payload=None, message_id=None, context=None):
|
||||
#TODO: Replace all this with a single email object
|
||||
if body is None:
|
||||
body = {}
|
||||
|
@ -306,18 +305,38 @@ class email_template_account(osv.osv):
|
|||
serv = self.smtp_connection(cr, uid, id)
|
||||
if serv:
|
||||
try:
|
||||
msg = MIMEMultipart()
|
||||
# Prepare multipart containers depending on data
|
||||
text_subtype = (core_obj.send_pref == 'alternative') and 'alternative' or 'mixed'
|
||||
# Need a multipart/mixed wrapper for attachments if content is alternative
|
||||
if payload and text_subtype == 'alternative':
|
||||
payload_part = MIMEMultipart(_subtype='mixed')
|
||||
text_part = MIMEMultipart(_subtype=text_subtype)
|
||||
payload_part.attach(text_part)
|
||||
else:
|
||||
# otherwise a single multipart/mixed will do the whole job
|
||||
payload_part = text_part = MIMEMultipart(_subtype=text_subtype)
|
||||
|
||||
if subject:
|
||||
msg['Subject'] = subject
|
||||
sender_name = Header(core_obj.name, 'utf-8').encode()
|
||||
msg['From'] = sender_name + " <" + core_obj.email_id + ">"
|
||||
msg['Organization'] = tools.ustr(core_obj.user.company_id.name)
|
||||
msg['Date'] = formatdate()
|
||||
payload_part['Subject'] = subject
|
||||
from_email = core_obj.email_id
|
||||
if '<' in from_email:
|
||||
# We have a structured email address, keep it untouched
|
||||
payload_part['From'] = Header(core_obj.email_id, 'utf-8').encode()
|
||||
else:
|
||||
# Plain email address, construct a structured one based on the name:
|
||||
sender_name = Header(core_obj.name, 'utf-8').encode()
|
||||
payload_part['From'] = sender_name + " <" + core_obj.email_id + ">"
|
||||
payload_part['Organization'] = tools.ustr(core_obj.user.company_id.name)
|
||||
payload_part['Date'] = formatdate()
|
||||
addresses_l = self.get_ids_from_dict(addresses)
|
||||
if addresses_l['To']:
|
||||
msg['To'] = u','.join(addresses_l['To'])
|
||||
payload_part['To'] = u','.join(addresses_l['To'])
|
||||
if addresses_l['CC']:
|
||||
msg['CC'] = u','.join(addresses_l['CC'])
|
||||
payload_part['CC'] = u','.join(addresses_l['CC'])
|
||||
if addresses_l['Reply-To']:
|
||||
payload_part['Reply-To'] = addresses_l['Reply-To'][0]
|
||||
if message_id:
|
||||
payload_part['Message-ID'] = message_id
|
||||
if body.get('text', False):
|
||||
temp_body_text = body.get('text', '')
|
||||
l = len(temp_body_text.replace(' ', '').replace('\r', '').replace('\n', ''))
|
||||
|
@ -326,28 +345,30 @@ class email_template_account(osv.osv):
|
|||
# Attach parts into message container.
|
||||
# According to RFC 2046, the last part of a multipart message, in this case
|
||||
# the HTML message, is best and preferred.
|
||||
if core_obj.send_pref == 'text' or core_obj.send_pref == 'both':
|
||||
body_text = body.get('text', u'No Mail Message')
|
||||
if core_obj.send_pref in ('text', 'mixed', 'alternative'):
|
||||
body_text = body.get('text', u'<Empty Message>')
|
||||
body_text = tools.ustr(body_text)
|
||||
msg.attach(MIMEText(body_text.encode("utf-8"), _charset='UTF-8'))
|
||||
if core_obj.send_pref == 'html' or core_obj.send_pref == 'both':
|
||||
text_part.attach(MIMEText(body_text.encode("utf-8"), _charset='UTF-8'))
|
||||
if core_obj.send_pref in ('html', 'mixed', 'alternative'):
|
||||
html_body = body.get('html', u'')
|
||||
if len(html_body) == 0 or html_body == u'':
|
||||
html_body = body.get('text', u'<p>No Mail Message</p>').replace('\n', '<br/>').replace('\r', '<br/>')
|
||||
html_body = body.get('text', u'<p><Empty Message></p>').replace('\n', '<br/>').replace('\r', '<br/>')
|
||||
html_body = tools.ustr(html_body)
|
||||
msg.attach(MIMEText(html_body.encode("utf-8"), _subtype='html', _charset='UTF-8'))
|
||||
#Now add attachments if any
|
||||
for file in payload.keys():
|
||||
part = MIMEBase('application', "octet-stream")
|
||||
part.set_payload(base64.decodestring(payload[file]))
|
||||
part.add_header('Content-Disposition', 'attachment; filename="%s"' % file)
|
||||
Encoders.encode_base64(part)
|
||||
msg.attach(part)
|
||||
text_part.attach(MIMEText(html_body.encode("utf-8"), _subtype='html', _charset='UTF-8'))
|
||||
|
||||
#Now add attachments if any, wrapping into a container multipart/mixed if needed
|
||||
if payload:
|
||||
for file in payload:
|
||||
part = MIMEBase('application', "octet-stream")
|
||||
part.set_payload(base64.decodestring(payload[file]))
|
||||
part.add_header('Content-Disposition', 'attachment; filename="%s"' % file)
|
||||
Encoders.encode_base64(part)
|
||||
payload_part.attach(part)
|
||||
except Exception, error:
|
||||
logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:MIME Error\nDescription: %s") % (id, error))
|
||||
return {'error_msg': "Server Send Error\nDescription: %s"%error}
|
||||
try:
|
||||
serv.sendmail(msg['From'], addresses_l['all'], msg.as_string())
|
||||
serv.sendmail(payload_part['From'], addresses_l['all'], payload_part.as_string())
|
||||
except Exception, error:
|
||||
logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:Server Send Error\nDescription: %s") % (id, error))
|
||||
return {'error_msg': "Server Send Error\nDescription: %s"%error}
|
||||
|
@ -358,7 +379,7 @@ class email_template_account(osv.osv):
|
|||
else:
|
||||
logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:Account not approved") % id)
|
||||
return {'error_msg':"Mail from Account %s failed. Probable Reason:Account not approved"% id}
|
||||
|
||||
|
||||
def extracttime(self, time_as_string):
|
||||
"""
|
||||
TODO: DOC THis
|
||||
|
|
|
@ -2,29 +2,25 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# To change this template, choose Tools | Templates
|
||||
# and open the template in the editor.
|
||||
from osv import fields,osv
|
||||
import pooler
|
||||
import netsvc
|
||||
from osv import osv
|
||||
import re
|
||||
|
||||
class email_template_engines(osv.osv):
|
||||
|
@ -35,7 +31,7 @@ class email_template_engines(osv.osv):
|
|||
pass
|
||||
|
||||
def strip_html(self,text):
|
||||
#Removes HTML, Have to check if still relevent
|
||||
#Removes HTML, Have to check if still relevant
|
||||
if text:
|
||||
def fixup(m):
|
||||
text = m.group(0)
|
||||
|
@ -69,7 +65,6 @@ class email_template_engines(osv.osv):
|
|||
#templateid: the template id of the template
|
||||
#context: TODO
|
||||
if message:
|
||||
logger = netsvc.Logger()
|
||||
def merge(match):
|
||||
template = self.pool.get("email.template").browse(cr,uid,templateid,context)
|
||||
obj_pool = self.pool.get(template.object_name.model)
|
||||
|
|
|
@ -2,27 +2,26 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
import time
|
||||
import email_template_engines
|
||||
import netsvc
|
||||
from tools.translate import _
|
||||
import tools
|
||||
|
@ -75,10 +74,15 @@ class email_template_mailbox(osv.osv):
|
|||
payload[attachment.datas_fname] = attachment.datas
|
||||
result = account_obj.send_mail(cr, uid,
|
||||
[values['account_id'][0]],
|
||||
{'To':values.get('email_to', u'') or u'', 'CC':values.get('email_cc', u'') or u'', 'BCC':values.get('email_bcc', u'') or u''},
|
||||
{'To':values.get('email_to') or u'',
|
||||
'CC':values.get('email_cc') or u'',
|
||||
'BCC':values.get('email_bcc') or u'',
|
||||
'Reply-To':values.get('reply_to') or u''},
|
||||
values['subject'] or u'',
|
||||
{'text':values.get('body_text', u'') or u'', 'html':values.get('body_html', u'') or u''},
|
||||
payload=payload, context=context)
|
||||
{'text':values.get('body_text') or u'', 'html':values.get('body_html') or u''},
|
||||
payload=payload,
|
||||
message_id=values['message_id'],
|
||||
context=context)
|
||||
if result == True:
|
||||
self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context)
|
||||
self.historise(cr, uid, [id], "Email sent successfully", context)
|
||||
|
@ -88,7 +92,7 @@ class email_template_mailbox(osv.osv):
|
|||
|
||||
except Exception, error:
|
||||
logger = netsvc.Logger()
|
||||
logger.notifyChannel(_("Power Email"), netsvc.LOG_ERROR, _("Sending of Mail %s failed. Probable Reason:Could not login to server\nError: %s") % (id, error))
|
||||
logger.notifyChannel("email-template", netsvc.LOG_ERROR, _("Sending of Mail %s failed. Probable Reason:Could not login to server\nError: %s") % (id, error))
|
||||
self.historise(cr, uid, [id], error, context)
|
||||
self.write(cr, uid, id, {'state':'na'}, context)
|
||||
return result
|
||||
|
@ -103,21 +107,27 @@ class email_template_mailbox(osv.osv):
|
|||
'From',
|
||||
size=64),
|
||||
'email_to':fields.char(
|
||||
'Recepient (To)',
|
||||
'Recipient (To)',
|
||||
size=250,),
|
||||
'email_cc':fields.char(
|
||||
' CC',
|
||||
'CC',
|
||||
size=250),
|
||||
'email_bcc':fields.char(
|
||||
' BCC',
|
||||
'BCC',
|
||||
size=250),
|
||||
'reply_to':fields.char(
|
||||
'Reply-To',
|
||||
size=250),
|
||||
'message_id':fields.char(
|
||||
'Message-ID',
|
||||
size=250),
|
||||
'subject':fields.char(
|
||||
' Subject',
|
||||
'Subject',
|
||||
size=200,),
|
||||
'body_text':fields.text(
|
||||
'Standard Body (Text)'),
|
||||
'body_html':fields.text(
|
||||
'Body (Text-Web Client Only)'),
|
||||
'Body (Rich Text Clients Only)'),
|
||||
'attachments_ids':fields.many2many(
|
||||
'ir.attachment',
|
||||
'mail_attachments_rel',
|
||||
|
|
|
@ -8,14 +8,13 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Outbox">
|
||||
<group col="4" colspan="2">
|
||||
<field name="email_from" colspan="4" select="1"/>
|
||||
<field name="email_cc" colspan="4" select="1"/>
|
||||
<field name="date_mail" colspan="4" select="2"/>
|
||||
</group>
|
||||
<group col="4" colspan="2">
|
||||
<field name="email_to" colspan="4" required="1" select="1" />
|
||||
<field name="email_bcc" colspan="4" select="2"/>
|
||||
<group col="4" colspan="4" name="headers">
|
||||
<field name="email_from" select="1"/>
|
||||
<field name="email_to" required="1" select="1" />
|
||||
<field name="reply_to" select="2"/>
|
||||
<field name="email_cc" select="1"/>
|
||||
<field name="email_bcc" select="2"/>
|
||||
<field name="date_mail" select="2"/>
|
||||
<field name="subject" colspan="4" select="1"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
|
@ -46,6 +45,7 @@
|
|||
<field name="server_ref" colspan="2" />
|
||||
<field name="mail_type" colspan="2" />
|
||||
<field name="folder" colspan="2" select="2"/>
|
||||
<field name="message_id" select="2"/>
|
||||
<separator string="History" colspan="4" />
|
||||
<field name="history" nolabel="1" colspan="4"/>
|
||||
</group>
|
||||
|
@ -83,7 +83,7 @@
|
|||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Mailboxes">
|
||||
<filter icon="terp-mail-message-new" string="Drafts" name="draft" domain="[('folder','=','drafts']"/>
|
||||
<filter icon="terp-mail-message-new" string="Drafts" name="draft" domain="[('folder','=','drafts')]"/>
|
||||
<filter icon="terp-mail-" string="Outbox" name="outbox" domain="[('folder','=','outbox')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-gtk-jump-to-ltr" string="Sent" domain="[('folder','=','sent')]"/>
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
<field name="to" />
|
||||
<field name="cc" />
|
||||
<field name="bcc" />
|
||||
<field name="subject" />
|
||||
<field name="reply_to" />
|
||||
<field name="message_id" attrs="{'invisible':[('message_id','=',False)]}" groups="base.group_extended"/>
|
||||
<field name="subject" colspan="8"/>
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<separator string= "Body(Text)" colspan="2"/>
|
||||
|
@ -58,17 +60,18 @@
|
|||
<page string="Mail Details">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Addresses" colspan="2"/>
|
||||
<field name="from_email"/>
|
||||
<field name="from_account" required="1"/>
|
||||
<field name="def_to" required="1"/>
|
||||
<field name="def_cc"/>
|
||||
<field name="def_bcc"/>
|
||||
<field name="reply_to"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Email Data" colspan="2"/>
|
||||
<field name="enforce_from_account" required= "1"/>
|
||||
<field name="def_subject" colspan="4" required="1" />
|
||||
<field name="use_sign" colspan="4" />
|
||||
<field name="lang" colspan="4" />
|
||||
<field name="track_campaign_item" colspan="4"/>
|
||||
</group>
|
||||
<separator colspan="3" string="Standard Body" />
|
||||
<separator colspan="1" string="Expression Builder" />
|
||||
|
@ -116,10 +119,17 @@
|
|||
<button name="delete_action" string="Delete Action" type="object" colspan="2" attrs="{'invisible':[('ref_ir_act_window','=',False), ('ref_ir_value','=',False)]}"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Attachments (Report to attach)" colspan="4"/>
|
||||
<field name="file_name" colspan="2" />
|
||||
<field name="report_template" colspan="2"
|
||||
domain="[('model','=',model_int_name)]" />
|
||||
<separator string="Attachments" colspan="2"/>
|
||||
<notebook>
|
||||
<page string="Existing files">
|
||||
<field name="attachment_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Report">
|
||||
<field name="file_name" colspan="4" />
|
||||
<field name="report_template" colspan="4"
|
||||
domain="[('model','=',model_int_name)]" />
|
||||
</page>
|
||||
</notebook>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
|
@ -141,7 +151,7 @@
|
|||
<field name="def_subject" colspan="4" select="2" />
|
||||
<field name="use_sign" colspan="4" select="2" />
|
||||
<field name="file_name" colspan="4" />
|
||||
<field name="enforce_from_account" />
|
||||
<field name="from_account" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -9,7 +9,7 @@ __contributors__ = ["Martin 'Joey' Schulze", "Ricardo Reyes", "Kevin Jay North"]
|
|||
# Support decoded entities with unifiable.
|
||||
|
||||
if not hasattr(__builtins__, 'True'): True, False = 1, 0
|
||||
import re, sys, urllib, htmlentitydefs, codecs, StringIO, types
|
||||
import re, sys, urllib, htmlentitydefs, codecs
|
||||
import sgmllib
|
||||
import urlparse
|
||||
sgmllib.charref = re.compile('&#([xX]?[0-9a-fA-F]+)[^0-9a-fA-F]')
|
||||
|
|
|
@ -1 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import email_template_send_wizard
|
||||
|
|
|
@ -1,13 +1,38 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
from mako.template import Template
|
||||
from mako import exceptions
|
||||
import netsvc
|
||||
import base64
|
||||
import time
|
||||
from tools.translate import _
|
||||
import tools
|
||||
from email_template.email_template import get_value
|
||||
|
||||
|
||||
## FIXME: this wizard duplicates a lot of features of the email template preview,
|
||||
## one of the 2 should inherit from the other!
|
||||
|
||||
class email_template_send_wizard(osv.osv_memory):
|
||||
_name = 'email_template.send.wizard'
|
||||
_description = 'This is the wizard for sending mail'
|
||||
|
@ -23,16 +48,16 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
|
||||
logger = netsvc.Logger()
|
||||
|
||||
if template.enforce_from_account:
|
||||
return [(template.enforce_from_account.id, '%s (%s)' % (template.enforce_from_account.name, template.enforce_from_account.email_id))]
|
||||
if template.from_account:
|
||||
return [(template.from_account.id, '%s (%s)' % (template.from_account.name, template.from_account.email_id))]
|
||||
else:
|
||||
account_id = self.pool.get('email_template.account').search(cr,uid,[('company','=','no'),('user','=',uid)], context=context)
|
||||
if account_id:
|
||||
account = self.pool.get('email_template.account').browse(cr,uid,account_id, context)
|
||||
return [(r.id,r.name + " (" + r.email_id + ")") for r in account]
|
||||
else:
|
||||
logger.notifyChannel(_("Power Email"), netsvc.LOG_ERROR, _("No personal email accounts are configured for you. \nEither ask admin to enforce an account for this template or get yourself a personal power email account."))
|
||||
raise osv.except_osv(_("Power Email"),_("No personal email accounts are configured for you. \nEither ask admin to enforce an account for this template or get yourself a personal power email account."))
|
||||
logger.notifyChannel(_("email-template"), netsvc.LOG_ERROR, _("No personal email accounts are configured for you. \nEither ask admin to enforce an account for this template or get yourself a personal email account."))
|
||||
raise osv.except_osv(_("Missing mail account"),_("No personal email accounts are configured for you. \nEither ask admin to enforce an account for this template or get yourself a personal email account."))
|
||||
|
||||
def get_value(self, cursor, user, template, message, context=None, id=None):
|
||||
"""Gets the value of the message parsed with the content of object id (or the first 'src_rec_ids' if id is not given)"""
|
||||
|
@ -91,6 +116,16 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
'to':fields.char('To',size=250,required=True),
|
||||
'cc':fields.char('CC',size=250,),
|
||||
'bcc':fields.char('BCC',size=250,),
|
||||
'reply_to':fields.char('Reply-To',
|
||||
size=250,
|
||||
help="The address recipients should reply to,"
|
||||
" if different from the From address."
|
||||
" Placeholders can be used here."),
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
help="The Message-ID header value, if you need to"
|
||||
"specify it, for example to automatically recognize the replies later."
|
||||
" Placeholders can be used here."),
|
||||
'subject':fields.char('Subject',size=200),
|
||||
'body_text':fields.text('Body',),
|
||||
'body_html':fields.text('Body',),
|
||||
|
@ -103,6 +138,7 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
'attachment_ids': fields.many2many('ir.attachment','send_wizard_attachment_rel', 'wizard_id', 'attachment_id', 'Attachments'),
|
||||
}
|
||||
|
||||
#FIXME: probably better by overriding default_get directly
|
||||
_defaults = {
|
||||
'state': lambda self,cr,uid,ctx: len(ctx['src_rec_ids']) > 1 and 'multi' or 'single',
|
||||
'rel_model': lambda self,cr,uid,ctx: self.pool.get('ir.model').search(cr,uid,[('model','=',ctx['src_model'])],context=ctx)[0],
|
||||
|
@ -116,8 +152,11 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
'report': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'file_name', ctx),
|
||||
'signature': lambda self,cr,uid,ctx: self._get_template(cr, uid, ctx).use_sign,
|
||||
'ref_template':lambda self,cr,uid,ctx: self._get_template(cr, uid, ctx).id,
|
||||
'reply_to': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'reply_to', ctx),
|
||||
'reply_to': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'reply_to', ctx),
|
||||
'requested':lambda self,cr,uid,ctx: len(ctx['src_rec_ids']),
|
||||
'full_success': lambda *a: False
|
||||
'full_success': False,
|
||||
'attachment_ids': [],
|
||||
}
|
||||
|
||||
def fields_get(self, cr, uid, fields=None, context=None, write_access=True):
|
||||
|
@ -153,13 +192,13 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
mail_ids = self.save_to_mailbox(cr, uid, ids, context)
|
||||
if mail_ids:
|
||||
self.pool.get('email_template.mailbox').write(cr, uid, mail_ids, {'folder':'outbox'}, context)
|
||||
logger.notifyChannel(_("Power Email"), netsvc.LOG_INFO, _("Emails for multiple items saved in outbox."))
|
||||
logger.notifyChannel("email-template", netsvc.LOG_INFO, _("Emails for multiple items saved in outbox."))
|
||||
self.write(cr, uid, ids, {
|
||||
'generated':len(mail_ids),
|
||||
'state':'done'
|
||||
}, context)
|
||||
else:
|
||||
raise osv.except_osv(_("Power Email"),_("Email sending failed for one or more objects."))
|
||||
raise osv.except_osv(_("Email Template"),_("Email sending failed for one or more objects."))
|
||||
return True
|
||||
|
||||
def save_to_mailbox(self, cr, uid, ids, context=None):
|
||||
|
|
Loading…
Reference in New Issue