[REVIEW+IMP] email_template: inherit related improvement
bzr revid: hmo@tinyerp.com-20110214194936-92himmpn80ytmjim
This commit is contained in:
parent
824c7f56c9
commit
72220cb09b
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2010-Today 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
|
||||
|
@ -19,9 +19,8 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import mako_template
|
||||
import email_template
|
||||
import wizard
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2011 OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2010-Today 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
|
||||
|
@ -31,90 +31,46 @@ from tools.translate import _
|
|||
import tools
|
||||
import pooler
|
||||
|
||||
try:
|
||||
from mako.template import Template as MakoTemplate
|
||||
except ImportError:
|
||||
logging.getLogger('init').warning("module email_template: Mako templates not installed")
|
||||
|
||||
def get_value(cursor, user, recid, message=None, template=None, context=None):
|
||||
"""
|
||||
Evaluates an expression and returns its value
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of current user
|
||||
@param recid: ID of the target record under evaluation
|
||||
@param message: The expression to be evaluated
|
||||
@param template: BrowseRecord object of the current template
|
||||
@param context: OpenERP Context
|
||||
@return: Computed message (unicode) or u""
|
||||
"""
|
||||
pool = pooler.get_pool(cursor.dbname)
|
||||
if message is None:
|
||||
message = {}
|
||||
#Returns the computed expression
|
||||
if message:
|
||||
try:
|
||||
message = tools.ustr(message)
|
||||
object = pool.get(template.model_int_name).browse(cursor, user, recid, context=context)
|
||||
env = {
|
||||
'user':pool.get('res.users').browse(cursor, user, user, context=context),
|
||||
'db':cursor.dbname
|
||||
}
|
||||
templ = MakoTemplate(message, input_encoding='utf-8')
|
||||
reply = MakoTemplate(message).render_unicode(object=object, peobject=object, env=env, format_exceptions=True)
|
||||
return reply or False
|
||||
except Exception:
|
||||
logging.exception("can't render %r", message)
|
||||
return u""
|
||||
else:
|
||||
return message
|
||||
|
||||
class email_template(osv.osv):
|
||||
"Templates for sending Email"
|
||||
|
||||
_inherit = 'email.message'
|
||||
_name = "email.template"
|
||||
_description = 'Email Templates for Models'
|
||||
|
||||
def change_model(self, cursor, user, ids, object_name, context=None):
|
||||
def get_template_value(self, cr, uid, message=None, model=None, record_id=None, context=None):
|
||||
import mako_template
|
||||
return mako_template.get_value(cr, uid, message=message, model=model, record_id=record_id, context=context)
|
||||
|
||||
def get_email_template(self, cr, uid, template_id=False, record_id=None, context=None):
|
||||
"Return Template Object"
|
||||
if context is None:
|
||||
context = {}
|
||||
if not template_id:
|
||||
template_id = context.get('template_id', False)
|
||||
|
||||
if not template_id:
|
||||
return False
|
||||
|
||||
template_pool = self.pool.get('email.template')
|
||||
template = template_pool.browse(cr, uid, int(template_id), context)
|
||||
lang = self.get_template_value(cr, uid, template.lang, template.model, record_id, context)
|
||||
if lang:
|
||||
# Use translated template if necessary
|
||||
ctx = context.copy()
|
||||
ctx['lang'] = lang
|
||||
template = self.browse(cr, uid, template.id, ctx)
|
||||
return template
|
||||
|
||||
def onchange_model_id(self, cr, uid, ids, model_id, context=None):
|
||||
mod_name = False
|
||||
if object_name:
|
||||
mod_name = self.pool.get('ir.model').browse(cursor, user, object_name, context).model
|
||||
return {'value':{'model_int_name':mod_name}}
|
||||
if model_id:
|
||||
mod_name = self.pool.get('ir.model').browse(cr, uid, model_id, context).model
|
||||
return {'value':{'model':mod_name}}
|
||||
|
||||
_columns = {
|
||||
'name' : fields.char('Name', size=100, required=True),
|
||||
'object_name':fields.many2one('ir.model', 'Resource'),
|
||||
'model_int_name':fields.char('Model Internal Name', size=200,),
|
||||
'smtp_server_id':fields.many2one(
|
||||
'email.smtp_server',
|
||||
string="SMTP Server",
|
||||
help="Emails will be sent from this SMTP Server."),
|
||||
'def_to':fields.char(
|
||||
'Recipient (To)',
|
||||
size=250,
|
||||
help="The Recipient of email. "
|
||||
"Placeholders can be used here. "
|
||||
"e.g. ${object.email_to}"),
|
||||
'def_cc':fields.char(
|
||||
'CC',
|
||||
size=250,
|
||||
help="Carbon Copy address(es), comma-separated."
|
||||
" Placeholders can be used here. "
|
||||
"e.g. ${object.email_cc}"),
|
||||
'def_bcc':fields.char(
|
||||
'BCC',
|
||||
size=250,
|
||||
help="Blind Carbon Copy address(es), comma-separated."
|
||||
" Placeholders can be used here. "
|
||||
"e.g. ${object.email_bcc}"),
|
||||
'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. "
|
||||
"e.g. ${object.email_reply_to}"),
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
help="Specify the Message-ID SMTP header to use in outgoing emails. Please note that this overrides the Resource tracking option! Placeholders can be used here."),
|
||||
'name': fields.char('Name', size=250, required=True),
|
||||
'model_id':fields.many2one('ir.model', 'Resource'),
|
||||
'model': fields.related('model_id', 'model', string='Model', type="char", size=128, store=True, readonly=True),
|
||||
'track_campaign_item':fields.boolean('Resource Tracking',
|
||||
help="Enable this is you wish to include a special \
|
||||
tracking marker in outgoing emails so you can identify replies and link \
|
||||
|
@ -126,25 +82,25 @@ This is useful for CRM leads for example"),
|
|||
help="The default language for the email."
|
||||
" Placeholders can be used here. "
|
||||
"eg. ${object.partner_id.lang}"),
|
||||
'def_subject':fields.char(
|
||||
'subject':fields.char(
|
||||
'Subject',
|
||||
size=200,
|
||||
help="The subject of email."
|
||||
" Placeholders can be used here.",
|
||||
translate=True),
|
||||
'def_body_text':fields.text(
|
||||
'description':fields.text(
|
||||
'Standard Body (Text)',
|
||||
help="The text version of the mail",
|
||||
translate=True),
|
||||
'def_body_html':fields.text(
|
||||
'body_html':fields.text(
|
||||
'Body (Text-Web Client Only)',
|
||||
help="The text version of the mail",
|
||||
translate=True),
|
||||
'use_sign':fields.boolean(
|
||||
'user_signature':fields.boolean(
|
||||
'Signature',
|
||||
help="the signature from the User details"
|
||||
" will be appended to the mail"),
|
||||
'file_name':fields.char(
|
||||
'report_name':fields.char(
|
||||
'Report Filename',
|
||||
size=200,
|
||||
help="Name of the generated report file. Placeholders can be used in the filename. eg: 2009_SO003.pdf",
|
||||
|
@ -226,7 +182,7 @@ This is useful for CRM leads for example"),
|
|||
context = {}
|
||||
action_obj = self.pool.get('ir.actions.act_window')
|
||||
for template in self.browse(cr, uid, ids, context=context):
|
||||
src_obj = template.object_name.model
|
||||
src_obj = template.model_id.model
|
||||
vals['ref_ir_act_window'] = action_obj.create(cr, uid, {
|
||||
'name': template.name,
|
||||
'type': 'ir.actions.act_window',
|
||||
|
@ -401,197 +357,106 @@ This is useful for CRM leads for example"),
|
|||
})
|
||||
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.message',
|
||||
'res_id': mailbox_id,
|
||||
}
|
||||
attachment_id = attachment_obj.create(cursor, user, attachment_data, context)
|
||||
if attachment_id:
|
||||
self.pool.get('email.message').write(cursor, user, mailbox_id,
|
||||
{
|
||||
'attachments_ids':[(4, attachment_id)],
|
||||
'mail_type':'multipart/mixed'
|
||||
},
|
||||
context)
|
||||
|
||||
def generate_attach_reports(self, cursor, user, template, record_id, mail, context=None):
|
||||
"""
|
||||
Generate report to be attached and attach it
|
||||
to the email, and add any directly attached files as well.
|
||||
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of User
|
||||
@param template: Browse record of
|
||||
template
|
||||
@param record_id: ID of the target model
|
||||
for which this mail has
|
||||
to be generated
|
||||
@param mail: Browse record of email object
|
||||
@return: True
|
||||
"""
|
||||
if template.report_template:
|
||||
reportname = 'report.' + self.pool.get('ir.actions.report.xml').browse(cursor,
|
||||
user, template.report_template.id, context).report_name
|
||||
service = netsvc.LocalService(reportname)
|
||||
data = {}
|
||||
data['model'] = template.model_int_name
|
||||
(result, format) = service.create(cursor, user, [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, cursor, user, template, record_id, context=None):
|
||||
def _generate_email(self, cr, uid, template_id, record_id, context=None):
|
||||
"""
|
||||
Generates an email from the template for
|
||||
record record_id of target object
|
||||
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of User
|
||||
@param template: Browse record of
|
||||
template
|
||||
@param record_id: ID of the target model
|
||||
for which this mail has
|
||||
to be generated
|
||||
@return: ID of created object
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
#If account to send from is in context select it, else use enforced account
|
||||
if 'account_id' in context.keys():
|
||||
smtp_server_id = self.pool.get('email.smtp_server').read(cursor, user, context.get('account_id'), ['name', 'email_id'], context)
|
||||
else:
|
||||
smtp_server_id = {
|
||||
'id':template.smtp_server_id.id,
|
||||
'name':template.smtp_server_id.name,
|
||||
'email_id':template.smtp_server_id.email_id
|
||||
}
|
||||
lang = get_value(cursor, user, record_id, template.lang, template, context)
|
||||
if lang:
|
||||
ctx = context.copy()
|
||||
ctx.update({'lang':lang})
|
||||
template = self.browse(cursor, user, template.id, context=ctx)
|
||||
smtp_pool = self.pool.get('email.smtp_server')
|
||||
email_message_pool = self.pool.get('email.message')
|
||||
report_xml_pool = self.pool.get('ir.actions.report.xml')
|
||||
template = self.get_email_template(cr, uid, template_id, record_id, context)
|
||||
smtp_server_id = context.get('smtp_server_id', False)
|
||||
if not smtp_server_id:
|
||||
smtp_server_id = template.smtp_server_id.id
|
||||
smtp_server = smtp_pool.browse(cr, uid, smtp_server_id, context=context)
|
||||
# determine name of sender, either it is specified in email_id
|
||||
|
||||
# determine name of sender, either it is specified in email_id or we
|
||||
# use the account name
|
||||
email_id = smtp_server_id['email_id'].strip()
|
||||
email_id = smtp_server.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 = smtp_server_id['email_id']
|
||||
email_from = smtp_server.email_id
|
||||
else:
|
||||
email_from = tools.ustr(smtp_server_id['name']) + "<" + tools.ustr(email_id) + ">"
|
||||
email_from = tools.ustr(smtp_server.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 = {
|
||||
model = template.model
|
||||
values = {
|
||||
'email_from': email_from,
|
||||
'email_to':get_value(cursor,
|
||||
user,
|
||||
record_id,
|
||||
template.def_to,
|
||||
template,
|
||||
context),
|
||||
'email_cc':get_value(cursor,
|
||||
user,
|
||||
record_id,
|
||||
template.def_cc,
|
||||
template,
|
||||
context),
|
||||
'email_bcc':get_value(cursor,
|
||||
user,
|
||||
record_id,
|
||||
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,
|
||||
template.def_subject,
|
||||
template,
|
||||
context),
|
||||
'body_text':get_value(cursor,
|
||||
user,
|
||||
record_id,
|
||||
template.def_body_text,
|
||||
template,
|
||||
context),
|
||||
'body_html':get_value(cursor,
|
||||
user,
|
||||
record_id,
|
||||
template.def_body_html,
|
||||
template,
|
||||
context),
|
||||
#This is a mandatory field when automatic emails are sent
|
||||
'state':'na',
|
||||
'folder':'drafts',
|
||||
'mail_type':'multipart/alternative',
|
||||
'template_id': template.id
|
||||
'email_to': self.get_template_value(cr, uid, template.email_to, model, record_id, context),
|
||||
'email_cc': self.get_template_value(cr, uid, template.email_cc, model, record_id, context),
|
||||
'email_bcc': self.get_template_value(cr, uid, template.email_bcc, model, record_id, context),
|
||||
'reply_to': self.get_template_value(cr, uid, template.reply_to, model, record_id, context),
|
||||
'name': self.get_template_value(cr, uid, template.subject, model, record_id, context),
|
||||
'description': self.get_template_value(cr, uid, template.description, model, record_id, context),
|
||||
#'body_html': self.get_template_value(cr, uid, template.body_html, model, record_id, context),
|
||||
}
|
||||
|
||||
if template['message_id']:
|
||||
if template.message_id:
|
||||
# use provided message_id with placeholders
|
||||
mailbox_values.update({'message_id': get_value(cursor, user, record_id, template['message_id'], template, context)})
|
||||
values.update({'message_id': self.get_template_value(cr, uid, template.message_id, model, record_id, context)})
|
||||
|
||||
elif 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.")
|
||||
values.update({'message_id': tools.misc.generate_tracking_message_id(record_id)})
|
||||
|
||||
#Use signatures if allowed
|
||||
if template.use_sign:
|
||||
sign = self.pool.get('res.users').read(cursor, user, user, ['signature'], context)['signature']
|
||||
if mailbox_values['body_text']:
|
||||
mailbox_values['body_text'] += sign
|
||||
if mailbox_values['body_html']:
|
||||
mailbox_values['body_html'] += sign
|
||||
mailbox_id = self.pool.get('email.message').create(cursor, user, mailbox_values, context)
|
||||
if template.user_signature:
|
||||
sign = self.pool.get('res.users').read(cr, uid, uid, ['signature'], context)['signature']
|
||||
if values['description']:
|
||||
values['description'] += sign
|
||||
#if values['body_html']:
|
||||
# values['body_html'] += sign
|
||||
|
||||
return mailbox_id
|
||||
attachment = []
|
||||
|
||||
# Add report as a Document
|
||||
if template.report_template:
|
||||
report_name = template.report_name
|
||||
reportname = 'report.' + report_xml_pool.browse(cr, uid, template.report_template.id, context).report_name
|
||||
data = {}
|
||||
data['model'] = template.model
|
||||
|
||||
# Ensure report is rendered using template's language
|
||||
ctx = context.copy()
|
||||
if template.lang:
|
||||
ctx['lang'] = self.get_template_value(cr, uid, template.lang, template.model, record_id, context)
|
||||
service = netsvc.LocalService(reportname)
|
||||
(result, format) = service.create(cr, uid, [record_id], data, ctx)
|
||||
result = base64.b64encode(result)
|
||||
if not report_name:
|
||||
report_name = reportname
|
||||
report_name = report_name + "." + format
|
||||
attachment.append((report_name, result))
|
||||
|
||||
|
||||
def generate_mail(self, cursor, user, template_id, record_ids, context=None):
|
||||
# Add document attachments
|
||||
for attach in template.attachment_ids:
|
||||
#attach = attahcment_obj.browse(cr, uid, attachment_id, context)
|
||||
attachment.append((attach.datas_fname, attach.datas))
|
||||
|
||||
#Send emails
|
||||
email_id = email_message_pool.email_send(cr, uid, values.get('email_from'), values.get('email_to'), values.get('name'), values.get('description'),
|
||||
model=template.model, email_cc=values.get('email_cc'), email_bcc=values.get('email_bcc'), reply_to=values.get('reply_to'),
|
||||
attach=attachment, openobject_id=record_id, debug=True, subtype='plain', x_headers={}, priority='3', smtp_server_id=smtp_server.id, context=context)
|
||||
email_message_pool.write(cr, uid, email_id, {'template_id': template.id})
|
||||
return email_id
|
||||
|
||||
|
||||
|
||||
def generate_email(self, cr, uid, ids, record_ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
template = self.browse(cursor, user, template_id, context=context)
|
||||
if not template:
|
||||
raise Exception("The requested template could not be loaded")
|
||||
result = True
|
||||
mailbox_obj = self.pool.get('email.message')
|
||||
email_message_pool = self.pool.get('email.message')
|
||||
email_ids = []
|
||||
for template in self.browse(cr, uid, ids, context=context):
|
||||
for record_id in record_ids:
|
||||
mailbox_id = self._generate_mailbox_item_from_template(cursor, user, template, record_id, context)
|
||||
mail = mailbox_obj.browse(cursor, user, mailbox_id, context=context)
|
||||
if template.report_template or template.attachment_ids:
|
||||
self.generate_attach_reports(cursor, user, template, record_id, mail, context )
|
||||
mailbox_obj.write(cursor, user, mailbox_id, {'folder':'outbox', 'state': 'waiting'}, context=context)
|
||||
return result
|
||||
|
||||
email_id = self._generate_email(cr, uid, template.id, record_id, context)
|
||||
email_message_pool.write(cr, uid, email_id, {'folder':'outbox', 'state': 'waiting'}, context=context)
|
||||
email_ids.append(email_id)
|
||||
return email_ids
|
||||
email_template()
|
||||
|
||||
class email_message(osv.osv):
|
||||
|
|
|
@ -7,38 +7,38 @@
|
|||
<field name="model">email.template</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email Templates">
|
||||
<form string="Templates">
|
||||
<field name="name"/>
|
||||
<field name="object_name" required="1"
|
||||
on_change="change_model(object_name)"/>
|
||||
<field name="model_int_name" invisible="1"/>
|
||||
<field name="model_id" required="1"
|
||||
on_change="onchange_model_id(model_id)"/>
|
||||
<field name="model" invisible="1"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Mail Details">
|
||||
<page string="Email Details">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Addresses" colspan="2"/>
|
||||
<field name="smtp_server_id"/>
|
||||
<field name="def_to" required="1"/>
|
||||
<field name="def_cc"/>
|
||||
<field name="def_bcc"/>
|
||||
<field name="email_to" required="1"/>
|
||||
<field name="email_cc"/>
|
||||
<field name="email_bcc"/>
|
||||
<field name="reply_to"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Options" colspan="2"/>
|
||||
<field name="lang" colspan="4" />
|
||||
<field name="use_sign" colspan="4" />
|
||||
<field name="user_signature" colspan="4" />
|
||||
<field name="track_campaign_item" colspan="4"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="Email Content"/>
|
||||
<field name="def_subject" colspan="4" required="1"/>
|
||||
<field name="subject" colspan="4" required="1"/>
|
||||
<notebook>
|
||||
<page string="Body (Text)">
|
||||
<field name="def_body_text" colspan="4" nolabel="1"/>
|
||||
<page string="Body">
|
||||
<field name="description" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Body (Raw HTML)">
|
||||
<!-- <page string="Body (Raw HTML)">
|
||||
<field name="def_body_html" colspan="4" nolabel="1"/>
|
||||
<label string="Note: This is Raw HTML." colspan="4"/>
|
||||
</page>
|
||||
</page> -->
|
||||
</notebook>
|
||||
</group>
|
||||
<group col="4" colspan="2">
|
||||
|
@ -60,7 +60,7 @@
|
|||
</page>
|
||||
</notebook>
|
||||
<button name="%(wizard_email_template_preview)d" string="Preview Template"
|
||||
type="action" colspan="4" target="new" icon="gtk-zoom-fit"/>
|
||||
type="action" colspan="4" target="new" icon="gtk-zoom-fit" context="{'template_id':active_id}"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Advanced">
|
||||
|
@ -86,8 +86,8 @@
|
|||
</page>
|
||||
<page string="Report">
|
||||
<field name="report_template" colspan="4"
|
||||
domain="[('model','=',model_int_name)]"/>
|
||||
<field name="file_name" colspan="4" />
|
||||
domain="[('model','=',model)]"/>
|
||||
<field name="report_name" colspan="4" />
|
||||
</page>
|
||||
</notebook>
|
||||
</group>
|
||||
|
@ -102,16 +102,16 @@
|
|||
<field name="model">email.template</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Email Templates">
|
||||
<tree string="Templates">
|
||||
<field name="name"/>
|
||||
<field name="smtp_server_id"/>
|
||||
<field name="object_name"/>
|
||||
<field name="def_to"/>
|
||||
<field name="def_cc"/>
|
||||
<field name="def_bcc"/>
|
||||
<field name="def_subject"/>
|
||||
<field name="use_sign"/>
|
||||
<field name="file_name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="email_to"/>
|
||||
<field name="email_cc"/>
|
||||
<field name="email_bcc"/>
|
||||
<field name="subject"/>
|
||||
<field name="user_signature"/>
|
||||
<field name="report_name"/>
|
||||
<button name="%(wizard_email_template_preview)d" string="Preview Template"
|
||||
type="action" target="new" icon="gtk-zoom-fit"/>
|
||||
</tree>
|
||||
|
@ -126,25 +126,25 @@
|
|||
<search string="Templates">
|
||||
<group col="13" colspan="4">
|
||||
<field name="name"/>
|
||||
<field name="object_name"/>
|
||||
<field name="def_to"/>
|
||||
<field name="model_id"/>
|
||||
<field name="email_to"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="lang"/>
|
||||
<field name="def_subject"/>
|
||||
<field name="file_name"/>
|
||||
<field name="subject"/>
|
||||
<field name="report_name"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="0" string="Group by..." colspan="4" col="10">
|
||||
<filter string="Account" domain="[]" context="{'group_by':'smtp_server_id'}" icon="terp-folder-orange"/>
|
||||
<filter string="SMTP Server" domain="[]" context="{'group_by':'smtp_server_id'}" icon="terp-folder-orange"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Resource" domain="[]" context="{'group_by':'object_name'}" icon="terp-accessories-archiver"/>
|
||||
<filter string="Model" domain="[]" context="{'group_by':'model_id'}" icon="terp-accessories-archiver"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_template_tree_all">
|
||||
<field name="name">Email Templates</field>
|
||||
<field name="name">Templates</field>
|
||||
<field name="res_model">email.template</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form,tree</field>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2010-Today 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
|
||||
|
@ -19,6 +19,6 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import email_template_send_wizard
|
||||
import email_template_preview
|
||||
import email_template_send_wizard
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2010-Today 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
|
||||
|
@ -22,106 +22,92 @@
|
|||
|
||||
from osv import osv, fields
|
||||
from tools.translate import _
|
||||
from email_template.email_template import get_value
|
||||
import tools
|
||||
|
||||
|
||||
class email_template_preview(osv.osv_memory):
|
||||
_inherit = "email.template"
|
||||
_name = "email_template.preview"
|
||||
_description = "Email Template Preview"
|
||||
_rec_name = "subject"
|
||||
|
||||
def _get_model_recs(self, cr, uid, context=None):
|
||||
|
||||
def get_email_template(self, cr, uid, template_id=None, record_id=None, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
#Fills up the selection box which allows records from the selected object to be displayed
|
||||
self.context = context
|
||||
if 'template_id' in context:
|
||||
ref_obj_id = self.pool.get('email.template').browse(cr, uid, context['template_id'], context).object_name.id
|
||||
ref_obj_name = self.pool.get('ir.model').browse(cr, uid, ref_obj_id, context).model
|
||||
model_obj = self.pool.get(ref_obj_name)
|
||||
ref_obj_ids = model_obj.search(cr, uid, [], 0, 20, 'id', context=context)
|
||||
if not ref_obj_ids:
|
||||
ref_obj_ids = []
|
||||
# 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)
|
||||
|
||||
template_id = context.get('template_id', False)
|
||||
record_id = context.get('src_rec_ids',[]) and context.get('src_rec_ids')[0]
|
||||
return super(email_template_preview, self).get_email_template(cr, uid, template_id, record_id, context=context)
|
||||
|
||||
|
||||
|
||||
def _get_records(self, cr, uid, context=None):
|
||||
"""
|
||||
Return Records of particular Email Template's Model
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
template_id = context.get('template_id', False)
|
||||
if not template_id:
|
||||
return []
|
||||
template_pool = self.pool.get('email.template')
|
||||
model_pool = self.pool.get('ir.model')
|
||||
template = template_pool.browse(cr, uid, int(template_id), context=context)
|
||||
template_object = template.model_id
|
||||
model = self.pool.get(template_object.model)
|
||||
record_ids = model.search(cr, uid, [], 0, 20, 'id', context=context)
|
||||
default_id = context.get('default_res_id')
|
||||
if default_id and default_id not in record_ids:
|
||||
record_ids.insert(0, default_id)
|
||||
|
||||
return model.name_get(cr, uid, record_ids, context)
|
||||
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = super(email_template_preview, self).default_get(cr, uid, fields, context=context)
|
||||
if (not fields or 'rel_model_ref' in fields) and 'template_id' in context and not result.get('rel_model_ref'):
|
||||
selectables = self._get_model_recs(cr, uid, context=context)
|
||||
result['rel_model_ref'] = selectables and selectables[0][0] or False
|
||||
|
||||
template_pool = self.pool.get('email.template')
|
||||
template_id = context.get('template_id',False)
|
||||
if 'res_id' in fields:
|
||||
records = self._get_records(cr, uid, context=context)
|
||||
result['res_id'] = records and records[0][0] or False # select first record as a Default
|
||||
if template_id and 'model_id' in fields:
|
||||
result['model_id'] = template_pool.read(cr, uid, int(template_id), ['model_id'], context).get('model_id', False)
|
||||
return result
|
||||
|
||||
def _default_model(self, cursor, user, context=None):
|
||||
"""
|
||||
Returns the default value for model field
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of current user
|
||||
@param context: OpenERP Context
|
||||
"""
|
||||
return self.pool.get('email.template').read(cursor, user, context['template_id'], ['object_name'], context).get('object_name', False)
|
||||
|
||||
_columns = {
|
||||
'ref_template':fields.many2one(
|
||||
'email.template',
|
||||
'Template', readonly=True),
|
||||
'rel_model':fields.many2one('ir.model', 'Model', readonly=True),
|
||||
'rel_model_ref':fields.selection(_get_model_recs, 'Referred Document'),
|
||||
'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),
|
||||
'report':fields.char('Report Name', size=100, readonly=True),
|
||||
'res_id':fields.selection(_get_records, 'Referred Document'),
|
||||
}
|
||||
_defaults = {
|
||||
'ref_template': lambda self, cr, uid, ctx:ctx['template_id'] or False,
|
||||
'rel_model': _default_model,
|
||||
}
|
||||
def on_change_ref(self, cr, uid, ids, rel_model_ref, context=None):
|
||||
def on_change_ref(self, cr, uid, ids, res_id, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if not rel_model_ref:
|
||||
if not res_id:
|
||||
return {}
|
||||
vals = {}
|
||||
if context == {}:
|
||||
context = self.context
|
||||
template = self.pool.get('email.template').browse(cr, uid, context['template_id'], context)
|
||||
#Search translated template
|
||||
lang = get_value(cr, uid, rel_model_ref, template.lang, template, context)
|
||||
if lang:
|
||||
ctx = context.copy()
|
||||
ctx.update({'lang':lang})
|
||||
template = self.pool.get('email.template').browse(cr, uid, context['template_id'], ctx)
|
||||
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)
|
||||
|
||||
template_pool = self.pool.get('email.template')
|
||||
template = self.get_email_template(cr, uid, context)
|
||||
model = template.model
|
||||
vals['email_to'] = self.get_template_value(cr, uid, template.email_to, model, res_id, context)
|
||||
vals['email_cc'] = self.get_template_value(cr, uid, template.email_cc, model, res_id, context)
|
||||
vals['email_bcc'] = self.get_template_value(cr, uid, template.email_bcc, model, res_id, context)
|
||||
vals['reply_to'] = self.get_template_value(cr, uid, template.reply_to, model, res_id, context)
|
||||
if template.message_id:
|
||||
vals['message_id'] = get_value(cr, uid, rel_model_ref, template.message_id, template, context)
|
||||
vals['message_id'] = self.get_template_value(cr, uid, message_id, model, res_id, 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)
|
||||
vals['report'] = get_value(cr, uid, rel_model_ref, template.file_name, template, context)
|
||||
vals['subject'] = self.get_template_value(cr, uid, template.subject, model, res_id, context)
|
||||
vals['description'] = self.get_template_value(cr, uid, template.description, model, res_id, context)
|
||||
vals['body_html'] = self.get_template_value(cr, uid, template.body_html, model, res_id, context)
|
||||
vals['report_name'] = self.get_template_value(cr, uid, template.report_name, model, res_id, context)
|
||||
return {'value':vals}
|
||||
|
||||
email_template_preview()
|
||||
|
|
|
@ -9,25 +9,25 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Email Preview">
|
||||
<group col="4" colspan="4">
|
||||
<field name="rel_model"/>
|
||||
<field name="rel_model_ref" on_change="on_change_ref(rel_model_ref, context)"/>
|
||||
<field name="model_id" readonly="1"/>
|
||||
<field name="res_id" on_change="on_change_ref(res_id, context)"/>
|
||||
</group>
|
||||
<group col="8" colspan="4">
|
||||
<field name="to"/>
|
||||
<field name="cc"/>
|
||||
<field name="bcc"/>
|
||||
<field name="reply_to"/>
|
||||
<field name="message_id" attrs="{'invisible':[('message_id','=',False)]}" groups="base.group_extended"/>
|
||||
<field name="subject" colspan="8"/>
|
||||
<field name="email_to" readonly="1"/>
|
||||
<field name="email_cc" readonly="1"/>
|
||||
<field name="email_bcc" readonly="1"/>
|
||||
<field name="reply_to" readonly="1"/>
|
||||
<field name="message_id" readonly="1" attrs="{'invisible':[('message_id','=',False)]}" groups="base.group_extended"/>
|
||||
<field name="subject" colspan="8" readonly="1"/>
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<separator string= "Body(Text)" colspan="2"/>
|
||||
<separator string= "Body(Html)" colspan="2"/>
|
||||
<separator string= "Body" colspan="2" />
|
||||
<!--<separator string= "Body(Html)" colspan="2" />-->
|
||||
<newline/>
|
||||
<field name="body_text" nolabel="1" colspan="2"/>
|
||||
<field name="body_html" nolabel="1" colspan="2"/>
|
||||
<field name="description" nolabel="1" colspan="2" readonly="1"/>
|
||||
<!-- <field name="body_html" nolabel="1" colspan="2" readonly="1"/>-->
|
||||
</group>
|
||||
<field name="report" colspan="2"/>
|
||||
<field name="report_name" colspan="2" readonly="1"/>
|
||||
<button icon="gtk-ok" special="cancel" string="OK" colspan="1"/>
|
||||
</form>
|
||||
</field>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2010-Today 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
|
||||
|
@ -21,167 +21,118 @@
|
|||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
from mako.template import Template
|
||||
from mako import exceptions
|
||||
import netsvc
|
||||
import base64
|
||||
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'
|
||||
_inherit = 'email_template.preview'
|
||||
_description = 'This is the wizard for sending mail'
|
||||
_rec_name = "subject"
|
||||
|
||||
def _get_accounts(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
template = self._get_template(cr, uid, context)
|
||||
if not template:
|
||||
return []
|
||||
|
||||
logger = netsvc.Logger()
|
||||
|
||||
if template.smtp_server_id:
|
||||
return [(template.smtp_server_id.id, '%s (%s)' % (template.smtp_server_id.name, template.smtp_server_id.email_id))]
|
||||
else:
|
||||
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)"""
|
||||
if context is None:
|
||||
context = {}
|
||||
if not message:
|
||||
return ''
|
||||
if not id:
|
||||
id = context.get('src_rec_ids',[]) and context.get('src_rec_ids')[0]
|
||||
return get_value(cursor, user, id, message, template, context)
|
||||
|
||||
def _get_template(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
email_temp_obj = self.pool.get('email.template')
|
||||
if not 'template' in context and not 'template_id' in context:
|
||||
return None
|
||||
if 'template_id' in context.keys():
|
||||
template_ids = email_temp_obj.search(cr, uid, [('id','=',context['template_id'])], context=context)
|
||||
elif 'template' in context.keys():
|
||||
# Old versions of email_template used the name of the template. This caused
|
||||
# problems when the user changed the name of the template, but we keep the code
|
||||
# for compatibility with those versions.
|
||||
template_ids = email_temp_obj.search(cr, uid, [('name','=',context['template'])], context=context)
|
||||
if not template_ids:
|
||||
return None
|
||||
|
||||
template = email_temp_obj.browse(cr, uid, template_ids[0], context)
|
||||
lang = self.get_value(cr, uid, template, template.lang, context)
|
||||
if lang:
|
||||
# Use translated template if necessary
|
||||
ctx = context.copy()
|
||||
ctx['lang'] = lang
|
||||
template = email_temp_obj.browse(cr, uid, template.id, ctx)
|
||||
return template
|
||||
|
||||
def _get_template_value(self, cr, uid, field, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
template = self._get_template(cr, uid, context)
|
||||
if not template:
|
||||
return False
|
||||
if len(context['src_rec_ids']) > 1: # Multiple Mail: Gets original template values for multiple email change
|
||||
return getattr(template, field)
|
||||
else: # Simple Mail: Gets computed template values
|
||||
return self.get_value(cr, uid, template, getattr(template, field), context)
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = super(email_template_send_wizard, self).default_get(cr, uid, fields, context=context)
|
||||
if 'template_id' in context and context.get('template_id'):
|
||||
temp_data = self.pool.get('email.template').read(cr, uid, int(context.get('template_id')), ['attachment_ids'])
|
||||
result['attachment_ids'] = temp_data['attachment_ids']
|
||||
|
||||
template_pool = self.pool.get('email.template')
|
||||
model_pool = self.pool.get('ir.model')
|
||||
template_id=context.get('template_id', False)
|
||||
template = self.get_email_template(cr, uid, template_id=template_id, context=context)
|
||||
def _get_template_value(field):
|
||||
if not template:
|
||||
return False
|
||||
if len(context['src_rec_ids']) > 1: # Multiple Mail: Gets original template values for multiple email change
|
||||
return getattr(template, field)
|
||||
else: # Simple Mail: Gets computed template values
|
||||
return self.get_template_value(cr, uid, getattr(template, field), template.model, context)
|
||||
|
||||
if 'user_signature' in fields:
|
||||
result['user_signature'] = template.user_signature
|
||||
|
||||
if 'template_id' in fields:
|
||||
result['template_id'] = template.id
|
||||
|
||||
if 'smtp_server_id' in fields:
|
||||
result['smtp_server_id'] = template.smtp_server_id.id
|
||||
|
||||
if 'attachment_ids' in fields:
|
||||
result['attachment_ids'] = template_pool.read(cr, uid, template.id, ['attachment_ids'])['attachment_ids']
|
||||
|
||||
if 'requested' in fields:
|
||||
result['requested'] = len(context.get('src_rec_ids',''))
|
||||
|
||||
if 'state' in fields:
|
||||
result['state'] = len(context.get('src_rec_ids','')) > 1 and 'multi' or 'single'
|
||||
|
||||
if 'model_id' in fields:
|
||||
result['model_id'] = model_pool.search(cr, uid, [('model','=',context.get('src_model'))],context=context)[0]
|
||||
|
||||
if 'res_id' in fields:
|
||||
result['res_id'] = context['active_id']
|
||||
|
||||
if 'email_to' in fields:
|
||||
result['email_to'] = _get_template_value('email_to')
|
||||
|
||||
if 'email_cc' in fields:
|
||||
result['email_cc'] = _get_template_value('email_cc')
|
||||
|
||||
if 'email_bcc' in fields:
|
||||
result['email_bcc'] = _get_template_value('email_bcc')
|
||||
|
||||
if 'subject' in fields:
|
||||
result['subject'] = _get_template_value('subject')
|
||||
|
||||
if 'description' in fields:
|
||||
result['description'] = _get_template_value('description')
|
||||
|
||||
#if 'body_html' in fields:
|
||||
# result['body_html'] = _get_template_value('body_html')
|
||||
|
||||
if 'reply_to' in fields:
|
||||
result['reply_to'] = _get_template_value('reply_to')
|
||||
|
||||
if 'report_name' in fields:
|
||||
result['report_name'] = _get_template_value('report_name')
|
||||
|
||||
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'state':fields.selection([
|
||||
('single','Simple Mail Wizard Step 1'),
|
||||
('multi','Multiple Mail Wizard Step 1'),
|
||||
('done','Wizard Complete')
|
||||
],'Status',readonly=True),
|
||||
'ref_template':fields.many2one('email.template','Template',readonly=True),
|
||||
'rel_model':fields.many2one('ir.model','Model',readonly=True),
|
||||
'rel_model_ref':fields.integer('Referred Document',readonly=True),
|
||||
'from':fields.selection(_get_accounts,'From Account',select=True),
|
||||
'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',),
|
||||
'report':fields.char('Report File Name',size=100,),
|
||||
'signature':fields.boolean('Attach my signature to mail'),
|
||||
#'filename':fields.text('File Name'),
|
||||
'requested':fields.integer('No of requested Mails',readonly=True),
|
||||
'generated':fields.integer('No of generated Mails',readonly=True),
|
||||
'full_success':fields.boolean('Complete Success',readonly=True),
|
||||
'attachment_ids': fields.many2many('ir.attachment','send_wizard_attachment_rel', 'wizard_id', 'attachment_id', 'Attachments'),
|
||||
'state':fields.selection([
|
||||
('single','Simple Mail Wizard Step 1'),
|
||||
('multi','Multiple Mail Wizard Step 1'),
|
||||
('done','Wizard Complete')
|
||||
],'State',readonly=True),
|
||||
}
|
||||
|
||||
#FIXME: probably better by overriding default_get directly
|
||||
_defaults = {
|
||||
'state': lambda self,cr,uid,ctx: len(ctx.get('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.get('src_model'))],context=ctx)[0],
|
||||
'rel_model_ref': lambda self,cr,uid,ctx: ctx['active_id'],
|
||||
'to': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_to', ctx),
|
||||
'cc': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_cc', ctx),
|
||||
'bcc': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_bcc', ctx),
|
||||
'subject':lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_subject', ctx),
|
||||
'body_text':lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_body_text', ctx),
|
||||
'body_html':lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_body_html', ctx),
|
||||
'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.get('src_rec_ids','')),
|
||||
}
|
||||
|
||||
def fields_get(self, cr, uid, fields=None, context=None, write_access=True):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = super(email_template_send_wizard, self).fields_get(cr, uid, fields, context, write_access)
|
||||
if 'attachment_ids' in result and 'src_model' in context:
|
||||
result['attachment_ids']['domain'] = [('res_model','=',context['src_model']),('res_id','=',context['active_id'])]
|
||||
return result
|
||||
#def fields_get(self, cr, uid, fields=None, context=None, write_access=True):
|
||||
# if context is None:
|
||||
# context = {}
|
||||
# result = super(email_template_send_wizard, self).fields_get(cr, uid, fields, context, write_access)
|
||||
# if 'attachment_ids' in result and 'src_model' in context:
|
||||
# result['attachment_ids']['domain'] = [('res_model','=',context['src_model']),('res_id','=',context['active_id'])]
|
||||
# return result
|
||||
|
||||
def sav_to_drafts(self, cr, uid, ids, context=None):
|
||||
def save_to_drafts(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
mailid = self.save_to_mailbox(cr, uid, ids, context=context)
|
||||
self.pool.get('email.message').write(cr, uid, mailid, {'folder':'drafts', 'state': 'na'}, context)
|
||||
self.pool.get('email.message').write(cr, uid, mailid, {'folder':'drafts', 'state': 'draft'}, context)
|
||||
return {}
|
||||
|
||||
def send_mail(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
mailid = self.save_to_mailbox(cr, uid, ids, context)
|
||||
self.pool.get('email.message').write(cr, uid, mailid, {'folder':'outbox', 'state': 'waiting'}, context)
|
||||
return {}
|
||||
|
||||
def get_generated(self, cr, uid, ids=None, context=None):
|
||||
|
@ -194,7 +145,6 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
#Means there are multiple items selected for email.
|
||||
mail_ids = self.save_to_mailbox(cr, uid, ids, context)
|
||||
if mail_ids:
|
||||
self.pool.get('email.message').write(cr, uid, mail_ids, {'folder':'outbox', 'state': 'waiting'}, context)
|
||||
logger.notifyChannel("email-template", netsvc.LOG_INFO, _("Emails for multiple items saved in outbox."))
|
||||
self.write(cr, uid, ids, {
|
||||
'generated':len(mail_ids),
|
||||
|
@ -205,75 +155,18 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
return True
|
||||
|
||||
def save_to_mailbox(self, cr, uid, ids, context=None):
|
||||
def get_end_value(id, value):
|
||||
if len(context['src_rec_ids']) > 1: # Multiple Mail: Gets value from the template
|
||||
return self.get_value(cr, uid, template, value, context, id)
|
||||
else:
|
||||
return value
|
||||
if context is None:
|
||||
context = {}
|
||||
mail_ids = []
|
||||
email_message_obj = self.pool.get('email.message')
|
||||
attahcment_obj = self.pool.get('ir.attachment')
|
||||
smtp_obj = self.pool.get('email.smtp_server')
|
||||
user_obj = self.pool.get('res.users')
|
||||
report_xml_obj = self.pool.get('ir.actions.report.xml')
|
||||
model_obj = self.pool.get('ir.model')
|
||||
template = self._get_template(cr, uid, context)
|
||||
for id in context.get('src_rec_ids',[]):
|
||||
screen_vals = self.read(cr, uid, ids[0], [], context)
|
||||
smtp_data = smtp_obj.browse(cr, uid, screen_vals['from'], context=context)
|
||||
vals = {
|
||||
'email_from': tools.ustr(smtp_data.name) + "<" + tools.ustr(smtp_data.email_id) + ">",
|
||||
'email_to': get_end_value(id, screen_vals['to']),
|
||||
'email_cc': get_end_value(id, screen_vals['cc']),
|
||||
'email_bcc': get_end_value(id, screen_vals['bcc']),
|
||||
'name': get_end_value(id, screen_vals['subject']),
|
||||
'description': get_end_value(id, screen_vals['body_text']) + "\n" + get_end_value(id, screen_vals['body_html'] or ''),
|
||||
'state':'na',
|
||||
}
|
||||
if screen_vals['signature']:
|
||||
signature = user_obj.browse(cr, uid, uid, context).signature
|
||||
if signature:
|
||||
vals['description'] = tools.ustr(vals['description'] or '') + signature
|
||||
#def get_end_value(id, value):
|
||||
# if len(context['src_rec_ids']) > 1: # Multiple Mail: Gets value from the template
|
||||
# return self.get_value(cr, uid, template, value, context, id)
|
||||
# else:
|
||||
# return value
|
||||
|
||||
attachment_ids = []
|
||||
#Create partly the mail and later update attachments
|
||||
mail_id = email_message_obj.create(cr, uid, vals, context)
|
||||
mail_ids.append(mail_id)
|
||||
if template.report_template:
|
||||
reportname = 'report.' + report_xml_obj.browse(cr, uid, template.report_template.id, context).report_name
|
||||
data = {}
|
||||
data['model'] = model_obj.browse(cr, uid, screen_vals['rel_model'], context).model
|
||||
|
||||
# Ensure report is rendered using template's language
|
||||
ctx = context.copy()
|
||||
if template.lang:
|
||||
ctx['lang'] = self.get_value(cr, uid, template, template.lang, context, id)
|
||||
service = netsvc.LocalService(reportname)
|
||||
(result, format) = service.create(cr, uid, [id], data, ctx)
|
||||
attachment_id = attahcment_obj.create(cr, uid, {
|
||||
'name': _('%s (Email Attachment)') % tools.ustr(vals['name']),
|
||||
'datas': base64.b64encode(result),
|
||||
'datas_fname': tools.ustr(get_end_value(id, screen_vals['report']) or _('Report')) + "." + format,
|
||||
'description': vals['description'] or _("No Description"),
|
||||
'res_model': 'email.message',
|
||||
'res_id': mail_id
|
||||
}, context)
|
||||
attachment_ids.append(attachment_id)
|
||||
|
||||
# Add document attachments
|
||||
for attachment_id in screen_vals.get('attachment_ids',[]):
|
||||
new_id = attahcment_obj.copy(cr, uid, attachment_id, {
|
||||
'res_model': 'email.message',
|
||||
'res_id': mail_id,
|
||||
}, context)
|
||||
attachment_ids.append(new_id)
|
||||
if attachment_ids:
|
||||
email_message_obj.write(cr, uid, mail_id, {
|
||||
'attachment_ids': [[6, 0, attachment_ids]],
|
||||
}, context)
|
||||
return mail_ids
|
||||
email_ids = []
|
||||
for template in self.browse(cr, uid, ids, context=context):
|
||||
for record_id in context.get('src_rec_ids',[]):
|
||||
email_id = self._generate_email(cr, uid, template.id, record_id, context)
|
||||
email_ids.append(email_id)
|
||||
return email_ids
|
||||
|
||||
email_template_send_wizard()
|
||||
|
||||
|
|
|
@ -7,50 +7,57 @@
|
|||
<field name="model">email_template.send.wizard</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Send mail Wizard">
|
||||
<form string="Send Email Wizard">
|
||||
<group col="4" colspan="4">
|
||||
<field name="rel_model" colspan="2"/>
|
||||
<field name="from" required="1" colspan="2"/>
|
||||
<field name="smtp_server_id" widget="selection" required="1" colspan="4"/>
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<group col="6" colspan="4">
|
||||
<field name="to" colspan="4"/>
|
||||
<field name="cc" colspan="4"/>
|
||||
<field name="bcc" colspan="4"/>
|
||||
<field name="email_to" colspan="4"/>
|
||||
<field name="email_cc" colspan="4"/>
|
||||
<field name="email_bcc" colspan="4"/>
|
||||
<field name="subject" colspan="4" attrs="{'required':[('state','=','single')]}"/>
|
||||
<field name="report" colspan="4"/>
|
||||
<field name="report_name" colspan="4"/>
|
||||
<field name="user_signature" colspan="4"/>
|
||||
</group>
|
||||
<separator string="" colspan="4"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Body (Plain Text)">
|
||||
<field name="body_text" colspan="4" nolabel="1"/>
|
||||
<page string="Body">
|
||||
<field name="description" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Body (HTML)">
|
||||
<!-- <page string="Body (HTML)">
|
||||
<field name="body_html" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</page> -->
|
||||
<page string="Attachments">
|
||||
<label string="Add here all attachments of the current document you want to include in the Email." colspan="4"/>
|
||||
<field name="attachment_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="signature" colspan="4"/>
|
||||
</group>
|
||||
<group col="4" colspan="4" attrs="{'invisible':[('state','!=','single')]}">
|
||||
<button icon="gtk-apply" name="sav_to_drafts" string="Save in Drafts" type="object"/>
|
||||
<button icon="gtk-ok" name="send_mail" string="Send now" type="object"/>
|
||||
<button icon="gtk-cancel" special="cancel" string="Discard Mail"/>
|
||||
|
||||
</group>
|
||||
<field name="state" invisible="1"/>
|
||||
<group col="4" colspan="4" attrs="{'invisible':[('state','=','single')]}">
|
||||
<label string="Tip: Multiple emails are sent in the same language (the first one is proposed). We suggest you send emails in groups according to language." colspan="4"/>
|
||||
<field name="requested"/>
|
||||
<field name="generated"/>
|
||||
<button icon="gtk-ok" name="get_generated" string="Send all mails" type="object" states="multi" colspan="2"/>
|
||||
<button icon="gtk-cancel" special="cancel" string="Discard Mail" colspan="2" states="multi"/>
|
||||
</group>
|
||||
<button icon="gtk-ok" special="cancel" string="Close" colspan="4" states="done"/>
|
||||
<field name="state"/>
|
||||
<newline/>
|
||||
<label string="After clicking send all mails, mails will be sent to outbox and cleared in next Send/Recieve" colspan="4"/>
|
||||
<label string="After clicking Send All, emails will be sent to outbox and cleared in next Send/Recieve" colspan="4"/>
|
||||
<label string="Tip: Multiple emails are sent in the same language (the first one is proposed). We suggest you send emails in groups according to language." colspan="4"/>
|
||||
<newline/>
|
||||
</group>
|
||||
<label string="" colspan="2"/>
|
||||
<group col="4" colspan="2" attrs="{'invisible':[('state','=','single')]}">
|
||||
<button icon="gtk-cancel" special="cancel" string="Discard" states="multi"/>
|
||||
<button icon="gtk-ok" name="get_generated" string="Send All" type="object" states="multi"/>
|
||||
<button icon="gtk-ok" special="cancel" string="Close" states="done"/>
|
||||
</group>
|
||||
<group col="4" colspan="2" attrs="{'invisible':[('state','!=','single')]}">
|
||||
<button icon="gtk-cancel" special="cancel" string="Discard"/>
|
||||
<button icon="gtk-apply" name="save_to_drafts" string="Save in Drafts" type="object"/>
|
||||
<button icon="gtk-ok" name="send_mail" string="Send now" type="object"/>
|
||||
</group>
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -153,45 +153,44 @@ class email_message(osv.osv):
|
|||
return result
|
||||
|
||||
_columns = {
|
||||
'name':fields.text('Subject', readonly=True),
|
||||
'model': fields.char('Object Name', size=128, select=1, readonly=True),
|
||||
'res_id': fields.integer('Resource ID', select=1, readonly=True),
|
||||
'date': fields.datetime('Date', readonly=True),
|
||||
'user_id': fields.many2one('res.users', 'User Responsible', readonly=True),
|
||||
'message': fields.text('Description', readonly=True),
|
||||
'email_from': fields.char('From', size=128, help="Email From", readonly=True),
|
||||
'email_to': fields.char('To', help="Email Recipients", size=256, readonly=True),
|
||||
'email_cc': fields.char('Cc', help="Carbon Copy Email Recipients", size=256, readonly=True),
|
||||
'email_bcc': fields.char('Bcc', help='Blind Carbon Copy Email Recipients', size=256, readonly=True),
|
||||
'message_id': fields.char('Message Id', size=1024, readonly=True, help="Message Id on Email.", select=True),
|
||||
'references': fields.text('References', readonly=True, help="References emails."),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', required=False),
|
||||
'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel', 'message_id', 'attachment_id', 'Attachments', readonly=True),
|
||||
'name':fields.text('Subject'),
|
||||
'model': fields.char('Object Name', size=128, select=1),
|
||||
'res_id': fields.integer('Resource ID', select=1),
|
||||
'date': fields.datetime('Date'),
|
||||
'user_id': fields.many2one('res.users', 'User Responsible'),
|
||||
'message': fields.text('Description'),
|
||||
'email_from': fields.char('From', size=128, help="Email From"),
|
||||
'email_to': fields.char('To', help="Email Recipients", size=256),
|
||||
'email_cc': fields.char('Cc', help="Carbon Copy Email Recipients", size=256),
|
||||
'email_bcc': fields.char('Bcc', help='Blind Carbon Copy Email Recipients', size=256),
|
||||
'message_id': fields.char('Message Id', size=1024, help="Message Id on Email.", select=True),
|
||||
'references': fields.text('References', help="References emails."),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel', 'message_id', 'attachment_id', 'Attachments'),
|
||||
'display_text': fields.function(_get_display_text, method=True, type='text', size="512", string='Display Text'),
|
||||
'reply_to':fields.char('Reply-To', size=250, readonly=True),
|
||||
'sub_type': fields.char('Sub Type', size=32, readonly=True),
|
||||
'headers': fields.char('x_headers',size=256, readonly=True),
|
||||
'priority':fields.integer('Priority', readonly=True),
|
||||
'reply_to':fields.char('Reply-To', size=250),
|
||||
'sub_type': fields.char('Sub Type', size=32),
|
||||
'headers': fields.char('x_headers',size=256),
|
||||
'priority':fields.integer('Priority'),
|
||||
'debug':fields.boolean('Debug', readonly=True),
|
||||
'history': fields.boolean('History', readonly=True),
|
||||
'description': fields.text('Description', readonly=True),
|
||||
#I like GMAIL which allows putting same mail in many folders
|
||||
#Lets plan it for 0.9
|
||||
'description': fields.text('Description'),
|
||||
'smtp_server_id':fields.many2one('email.smtp_server', 'SMTP Server'),
|
||||
'folder':fields.selection([
|
||||
('drafts', 'Drafts'),
|
||||
('outbox', 'Outbox'),
|
||||
('trash', 'Trash'),
|
||||
('sent', 'Sent Items'),
|
||||
], 'Folder', readonly=True),
|
||||
], 'Folder'),
|
||||
'state':fields.selection([
|
||||
('na', 'Not Applicable'),
|
||||
('draft', 'Draft'),
|
||||
('sending', 'Sending'),
|
||||
('waiting', 'Waiting'),
|
||||
], 'State', readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': lambda * a: 'na',
|
||||
'state': lambda * a: 'draft',
|
||||
'folder': lambda * a: 'outbox',
|
||||
}
|
||||
|
||||
|
@ -237,8 +236,16 @@ class email_message(osv.osv):
|
|||
_("Error sending mail: %s") % e)
|
||||
|
||||
def email_send(self, cr, uid, email_from, email_to, subject, body, model=False, email_cc=None, email_bcc=None, reply_to=False, attach=None,
|
||||
openobject_id=False, debug=False, subtype='plain', x_headers={}, priority='3', context=None):
|
||||
openobject_id=False, debug=False, subtype='plain', x_headers={}, priority='3', smtp_server_id=False, context=None):
|
||||
attachment_obj = self.pool.get('ir.attachment')
|
||||
if type(email_to) != list:
|
||||
email_to = [email_to]
|
||||
if type(email_cc) != list:
|
||||
email_cc = [email_cc]
|
||||
if type(email_bcc) != list:
|
||||
email_bcc = [email_bcc]
|
||||
if type(reply_to) != list:
|
||||
reply_to = [reply_to]
|
||||
msg_vals = {
|
||||
'name': subject,
|
||||
'model': model or '',
|
||||
|
@ -256,6 +263,8 @@ class email_message(osv.osv):
|
|||
'priority': priority,
|
||||
'debug': debug,
|
||||
'folder': 'outbox',
|
||||
'history': True,
|
||||
'smtp_server_id': smtp_server_id,
|
||||
'state': 'waiting',
|
||||
}
|
||||
email_msg_id = self.create(cr, uid, msg_vals, context)
|
||||
|
@ -273,7 +282,7 @@ class email_message(osv.osv):
|
|||
attachment_ids.append(attachment_obj.create(cr, uid, attachment_data, context))
|
||||
self.write(cr, uid, email_msg_id,
|
||||
{ 'attachment_ids': [[6, 0, attachment_ids]] }, context)
|
||||
return True
|
||||
return email_msg_id
|
||||
|
||||
def process_email_queue(self, cr, uid, ids=None, context=None):
|
||||
if ids is None:
|
||||
|
@ -281,7 +290,7 @@ class email_message(osv.osv):
|
|||
if context is None:
|
||||
context = {}
|
||||
attachment_obj = self.pool.get('ir.attachment')
|
||||
account_obj = self.pool.get('email.smtp_server')
|
||||
smtp_server_obj = self.pool.get('email.smtp_server')
|
||||
if not ids:
|
||||
filters = [('folder', '=', 'outbox'), ('state', '!=', 'sending')]
|
||||
if 'filters' in context:
|
||||
|
@ -293,10 +302,11 @@ class email_message(osv.osv):
|
|||
attachments = []
|
||||
for attach in message.attachment_ids:
|
||||
attachments.append((attach.datas_fname ,attach.datas))
|
||||
smtp_account = False
|
||||
smtp_ids = account_obj.search(cr, uid, [('default','=',True)])
|
||||
smtp_server = message.smtp_server_id
|
||||
if not smtp_server:
|
||||
smtp_ids = smtp_server_obj.search(cr, uid, [('default','=',True)])
|
||||
if smtp_ids:
|
||||
smtp_account = account_obj.browse(cr, uid, smtp_ids, context)[0]
|
||||
smtp_server = smtp_server_obj.browse(cr, uid, smtp_ids, context)[0]
|
||||
tools.email_send(message.email_from,
|
||||
message.email_to and message.email_to.split(',') or [],
|
||||
message.name, message.description,
|
||||
|
|
|
@ -133,9 +133,7 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
default_ids = self.search(cr, uid, [('default','=',True)])
|
||||
if len(default_ids) > 1:
|
||||
return False
|
||||
elif not default_ids:
|
||||
return False
|
||||
else:
|
||||
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
|
|
|
@ -160,7 +160,6 @@
|
|||
<separator string="" colspan="4"/>
|
||||
<label string="" colspan="2"/>
|
||||
<button name="test_smtp_connection" type="object" string="Test Connection" icon="gtk-network" colspan="2"/>
|
||||
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
|
@ -172,12 +171,12 @@
|
|||
<field name="model">email.smtp_server</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Email Accounts">
|
||||
<tree string="SMTP Server">
|
||||
<field name="name"/>
|
||||
<field name="email_id"/>
|
||||
<field name="smtpuname"/>
|
||||
<field name="smtpserver"/>
|
||||
<field name="smtpport"/>
|
||||
<field name="default"/>
|
||||
<button name="test_smtp_connection" type="object" string="Test Connection" icon="gtk-network"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -187,7 +186,7 @@
|
|||
<field name="model">email.smtp_server</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Email Smtp Server">
|
||||
<search string="Smtp Server">
|
||||
<field name="name"/>
|
||||
<field name="email_id"/>
|
||||
</search>
|
||||
|
|
Loading…
Reference in New Issue