[IMP] mass_mailing: new refactoring of the way the body is managed
- now body_html is a right field on mass_mailing, editable using the website - email_designer controller / template now works on everything that has a body receiving its model and res_id as post parameters; it does not work only on email tempaltes anymore - cleaning of the mass mailing form view: reply_to managment option (either replied go into the document, either there is a specified reply_to; it is implemented using boolean fields instead of a selection because all options are not available for all models ... models like contact or partner do not have a chatter or shoudl be be used for a chatter-like use) - send to all now instantiates a mail.compose.message; the mass mailign processing is delegated to the wizard itself. bzr revid: tde@openerp.com-20140407170346-hpklabi513xskd07
This commit is contained in:
parent
efe75bd7e8
commit
271e805cb8
|
@ -448,8 +448,14 @@ class MassMailing(osv.Model):
|
|||
res[mailing.id] = val
|
||||
return res
|
||||
|
||||
def _get_edit_link(self, cr, uid, ids, name, args, context=None):
|
||||
return dict((id, _('<a href="website_mail/email_designer?model=mail.mass_mailing&res_id=%s">Open with Visual Editor</a>') % id) for id in ids)
|
||||
def _get_private_models(self, context=None):
|
||||
return ['res.partner', 'mail.maass_mailing.contact']
|
||||
|
||||
def _get_auto_reply_to_available(self, cr, uid, ids, name, arg, context=None):
|
||||
res = dict.fromkeys(ids, False)
|
||||
for mailing in self.browse(cr, uid, ids, context=context):
|
||||
res[mailing.id] = mailing.mailing_model not in self._get_private_models(context=context)
|
||||
return res
|
||||
|
||||
def _get_mailing_model(self, cr, uid, context=None):
|
||||
return [
|
||||
|
@ -475,11 +481,6 @@ class MassMailing(osv.Model):
|
|||
domain="[('use_in_mass_mailing', '=', True), ('model', '=', mailing_model)]",
|
||||
),
|
||||
'body_html': fields.html('Body'),
|
||||
'edit_link': fields.function(
|
||||
_get_edit_link, type='text',
|
||||
string='Visual Editor',
|
||||
help='Link to the website',
|
||||
),
|
||||
'mass_mailing_campaign_id': fields.many2one(
|
||||
'mail.mass_mailing.campaign', 'Mass Mailing Campaign',
|
||||
ondelete='set null',
|
||||
|
@ -494,12 +495,14 @@ class MassMailing(osv.Model):
|
|||
),
|
||||
# mailing options
|
||||
'email_from': fields.char('From'),
|
||||
'reply_in_thread': fields.boolean('Reply in thread'),
|
||||
'reply_specified': fields.boolean('Specific Reply-To'),
|
||||
'auto_reply_to_available': fields.function(
|
||||
_get_auto_reply_to_available,
|
||||
type='boolean', string='Reply in thread available'
|
||||
),
|
||||
'reply_to': fields.char('Reply To'),
|
||||
'mailing_model': fields.selection(_mailing_model, string='Type', required=True),
|
||||
# 'reply_to_mode': fields.selection(
|
||||
# [('existing', 'Use existing lists'), ('new', 'Create a new list')],
|
||||
# string='Contact List Choice', required=True
|
||||
# ),
|
||||
'contact_list_ids': fields.many2many(
|
||||
'mail.mass_mailing.list', 'mail_mass_mailing_list_rel',
|
||||
string='Mailing Lists',
|
||||
|
@ -633,7 +636,39 @@ class MassMailing(osv.Model):
|
|||
#------------------------------------------------------
|
||||
|
||||
def on_change_mailing_model(self, cr, uid, ids, mailing_model, context=None):
|
||||
return {'value': {'contact_list_ids': [], 'template_id': False, 'contact_nbr': 0}}
|
||||
values = {
|
||||
'contact_list_ids': [],
|
||||
'template_id': False,
|
||||
'contact_nbr': 0,
|
||||
'auto_reply_to_available': not mailing_model in self._get_private_models(context),
|
||||
'reply_in_thread': not mailing_model in self._get_private_models(context),
|
||||
'reply_specified': mailing_model in self._get_private_models(context)
|
||||
}
|
||||
return {'value': values}
|
||||
|
||||
def on_change_reply_specified(self, cr, uid, ids, reply_specified, reply_in_thread, context=None):
|
||||
if reply_specified == reply_in_thread:
|
||||
return {'value': {'reply_in_thread': not reply_specified}}
|
||||
return {}
|
||||
|
||||
def on_change_reply_in_thread(self, cr, uid, ids, reply_specified, reply_in_thread, context=None):
|
||||
if reply_in_thread == reply_specified:
|
||||
return {'value': {'reply_specified': not reply_in_thread}}
|
||||
return {}
|
||||
|
||||
def on_change_contact_list_ids(self, cr, uid, ids, mailing_model, contact_list_ids, context=None):
|
||||
values = {}
|
||||
list_ids = []
|
||||
for command in contact_list_ids:
|
||||
if command[0] == 6:
|
||||
list_ids += command[2]
|
||||
if list_ids:
|
||||
values['contact_nbr'] = self.pool[mailing_model].search(
|
||||
cr, uid,
|
||||
self.pool['mail.mass_mailing.list'].get_global_domain(cr, uid, list_ids, context=context)[mailing_model],
|
||||
count=True, context=context
|
||||
)
|
||||
return {'value': values}
|
||||
|
||||
def on_change_template_id(self, cr, uid, ids, template_id, context=None):
|
||||
values = {}
|
||||
|
@ -714,6 +749,15 @@ class MassMailing(osv.Model):
|
|||
'context': ctx,
|
||||
}
|
||||
|
||||
def action_edit_html(self, cr, uid, ids, context=None):
|
||||
url = '/website_mail/email_designer?model=mail.mass_mailing&res_id=%d' % ids[0]
|
||||
return {
|
||||
'name': _('Open with Visual Editor'),
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': url,
|
||||
'target': 'self',
|
||||
}
|
||||
|
||||
#------------------------------------------------------
|
||||
# Email Sending
|
||||
#------------------------------------------------------
|
||||
|
@ -758,54 +802,27 @@ class MassMailing(osv.Model):
|
|||
|
||||
def send_mail(self, cr, uid, ids, context=None):
|
||||
author_id = self.pool['res.users'].browse(cr, uid, uid, context=context).partner_id.id
|
||||
Mail = self.pool['mail.mail']
|
||||
for mailing in self.browse(cr, uid, ids, context=context):
|
||||
if not mailing.template_id:
|
||||
raise Warning('Please specify a template to use.')
|
||||
if not mailing.contact_nbr:
|
||||
raise Warning('Please select recipients.')
|
||||
|
||||
# get mail and recipints data
|
||||
# instantiate an email composer + send emails
|
||||
res_ids = self.get_recipients(cr, uid, mailing, context=context)
|
||||
template_values = self.pool['mail.compose.message'].generate_email_for_composer_batch(
|
||||
cr, uid, mailing.template_id.id, res_ids,
|
||||
context=context, fields=['body_html', 'attachment_ids', 'mail_server_id'])
|
||||
recipient_values = self.get_recipients_data(cr, uid, mailing, res_ids, context=context)
|
||||
|
||||
for res_id, mail_values in template_values.iteritems():
|
||||
body = mail_values.get('body')
|
||||
recipient = recipient_values[res_id]
|
||||
unsubscribe_url = self.get_unsubscribe_url(cr, uid, mailing.id, res_id, recipient['email'], context=context)
|
||||
if unsubscribe_url:
|
||||
body = tools.append_content_to_html(body, unsubscribe_url, plaintext=False, container_tag='p')
|
||||
|
||||
mail_values.update({
|
||||
'email_from': mailing.email_from,
|
||||
'reply_to': mailing.reply_to,
|
||||
'subject': mailing.name,
|
||||
'record_name': False,
|
||||
'model': mailing.mailing_model,
|
||||
'res_id': res_id,
|
||||
'author_id': author_id,
|
||||
'body_html': body,
|
||||
'auto_delete': True,
|
||||
'notification': True,
|
||||
'email_to': '"%s" <%s>' % (recipient['name'], recipient['email'])
|
||||
})
|
||||
mail_values['statistics_ids'] = [
|
||||
(0, 0, {
|
||||
'model': mailing.mailing_model,
|
||||
'res_id': res_id,
|
||||
'mass_mailing_id': mailing.id,
|
||||
})]
|
||||
m2m_attachment_ids = self.pool['mail.thread']._message_preprocess_attachments(
|
||||
cr, uid, mail_values.pop('attachments', []),
|
||||
mail_values.pop('attachment_ids', []),
|
||||
'mail.message', 0,
|
||||
context=context)
|
||||
mail_values['attachment_ids'] = m2m_attachment_ids
|
||||
|
||||
Mail.create(cr, uid, mail_values, context=context)
|
||||
comp_ctx = dict(context, active_ids=res_ids)
|
||||
composer_values = {
|
||||
'author_id': author_id,
|
||||
'body': mailing.body_html,
|
||||
'subject': mailing.name,
|
||||
'model': mailing.mailing_model,
|
||||
'email_from': mailing.email_from,
|
||||
'record_name': False,
|
||||
'composition_mode': 'mass_mail',
|
||||
'mass_mailing_id': mailing.id,
|
||||
'mailing_list_ids': [(4, l.id) for l in mailing.contact_list_ids],
|
||||
}
|
||||
if mailing.reply_specified:
|
||||
composer_values['reply_to'] = mailing.reply_to
|
||||
composer_id = self.pool['mail.compose.message'].create(cr, uid, composer_values, context=comp_ctx)
|
||||
self.pool['mail.compose.message'].send_mail(cr, uid, [composer_id], context=comp_ctx)
|
||||
return True
|
||||
|
||||
|
||||
|
|
|
@ -260,7 +260,20 @@
|
|||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="reply_to"/>
|
||||
<label for="reply_to"/>
|
||||
<div>
|
||||
<field name="auto_reply_to_available" invisible="1"/>
|
||||
<field name="reply_in_thread" class="oe_inline"
|
||||
on_change="on_change_reply_in_thread(reply_specified, reply_in_thread, context)"
|
||||
attrs="{'readonly': [('auto_reply_to_available', '=', False)]}"/> Replies go into the original document
|
||||
<span attrs="{'invisible': [('auto_reply_to_available', '=', True)]}"> (not available for those recipients)</span>
|
||||
<br />
|
||||
<field name="reply_specified" class="oe_inline"
|
||||
on_change="on_change_reply_specified(reply_specified, reply_in_thread, context)"/> Use a specific reply-to address
|
||||
<field name="reply_to" class="oe_inline"
|
||||
style="margin-left: 8px;"
|
||||
attrs="{'required': [('reply_specified', '=', True)]}"/>
|
||||
</div>
|
||||
<label for="mailing_model" string="Recipients"/>
|
||||
<div>
|
||||
<field name="mailing_model" widget="radio"
|
||||
|
@ -268,11 +281,13 @@
|
|||
|
||||
<label for="contact_list_ids" string="Mailing Lists"/>
|
||||
<field name="contact_list_ids" widget="many2many_tags" options="{'no_create': True}"
|
||||
class="oe_inline"
|
||||
placeholder="Choose mailing lists"/><span style="margin-left: 8px; margin-right: 8px">or</span>
|
||||
class="oe_inline" placeholder="Choose mailing lists"
|
||||
on_change="on_change_contact_list_ids(mailing_model, contact_list_ids, context)"/>
|
||||
<span style="margin-left: 8px; margin-right: 8px">or</span>
|
||||
<button string='Create a New List' class="oe_link" type='object' name='action_new_list'/><br />
|
||||
|
||||
<label for="contact_nbr" string="Total"/><field name="contact_nbr" nolabel="1" class="oe_inline" readonly="True"/> recipients
|
||||
<label for="contact_nbr" string="Total"/>
|
||||
<field name="contact_nbr" nolabel="1" class="oe_inline" readonly="True"/> recipients
|
||||
<button name="action_see_recipients" type="object" string="See Recipients" class="oe_inline oe_link" style='margin-left: 8px;'/><br />
|
||||
|
||||
<div groups="mass_mailing.group_mass_mailing_campaign" style="display: inline;">
|
||||
|
@ -293,12 +308,11 @@
|
|||
<label for="template_id"/>
|
||||
<div style="max-height: 200px; overflow: hidden !important;">
|
||||
<field name="template_id" string="Select Template" nolabel="1"
|
||||
class="oe_inline"
|
||||
options="{'no_create': True, 'no_open': True}"
|
||||
class="oe_inline" options="{'no_create': True, 'no_open': True}"
|
||||
on_change="on_change_template_id(template_id, context)"/>
|
||||
<field name="edit_link" widget='html' radonly='1'
|
||||
style='margin: 0px; padding: 0px;'/>
|
||||
<field name="body_html" readonly="1"/>
|
||||
<button name="action_edit_html" type="object" string="Edit Mail Content"
|
||||
class="oe_link" style="margin-left: 8px"/>
|
||||
<field name="body_html"/>
|
||||
</div>
|
||||
</group>
|
||||
</sheet>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import tools
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
|
||||
|
@ -29,9 +30,15 @@ class MailComposeMessage(osv.TransientModel):
|
|||
|
||||
_columns = {
|
||||
'mass_mailing_campaign_id': fields.many2one(
|
||||
'mail.mass_mailing.campaign', 'Mass mailing campaign',
|
||||
'mail.mass_mailing.campaign', 'Mass Mailing Campaign',
|
||||
),
|
||||
'mass_mailing_id': fields.many2one(
|
||||
'mail.mass_mailing', 'Mass Mailing'
|
||||
),
|
||||
'mass_mailing_name': fields.char('Mass Mailing'),
|
||||
'mailing_list_ids': fields.many2many(
|
||||
'mail.mass_mailing.list', string='Mailing List'
|
||||
),
|
||||
}
|
||||
|
||||
def get_mail_values(self, cr, uid, wizard, res_ids, context=None):
|
||||
|
@ -40,27 +47,44 @@ class MailComposeMessage(osv.TransientModel):
|
|||
email mass mailing. """
|
||||
res = super(MailComposeMessage, self).get_mail_values(cr, uid, wizard, res_ids, context=context)
|
||||
# use only for allowed models in mass mailing
|
||||
if wizard.composition_mode == 'mass_mail' and wizard.mass_mailing_name and \
|
||||
wizard.model in [item[0] for item in self.pool['mail.mass_mailing']._get_mailing_model()]:
|
||||
list_id = self.pool['mail.mass_mailing.list'].create(
|
||||
cr, uid, {
|
||||
'name': wizard.mass_mailing_name,
|
||||
'model': wizard.model,
|
||||
'domain': wizard.active_domain,
|
||||
}, context=context)
|
||||
mass_mailing_id = self.pool['mail.mass_mailing'].create(
|
||||
cr, uid, {
|
||||
'mass_mailing_campaign_id': wizard.mass_mailing_campaign_id and wizard.mass_mailing_campaign_id.id or False,
|
||||
'name': wizard.mass_mailing_name,
|
||||
'template_id': wizard.template_id and wizard.template_id.id or False,
|
||||
'state': 'done',
|
||||
'mailing_type': wizard.model,
|
||||
'contact_list_ids': [(4, list_id)],
|
||||
}, context=context)
|
||||
if wizard.composition_mode == 'mass_mail' and \
|
||||
(wizard.mass_mailing_name or wizard.mass_mailing_id) and \
|
||||
wizard.model in [item[0] for item in self.pool['mail.mass_mailing']._get_mailing_model(cr, uid, context=context)]:
|
||||
if wizard.mailing_list_ids:
|
||||
list_ids = [l.id for l in wizard.mailing_list_ids]
|
||||
if not list_ids:
|
||||
list_ids = [self.pool['mail.mass_mailing.list'].create(
|
||||
cr, uid, {
|
||||
'name': wizard.mass_mailing_name,
|
||||
'model': wizard.model,
|
||||
'domain': wizard.active_domain,
|
||||
}, context=context)]
|
||||
mass_mailing = wizard.mass_mailing_id
|
||||
if not mass_mailing:
|
||||
mass_mailing_id = self.pool['mail.mass_mailing'].create(
|
||||
cr, uid, {
|
||||
'mass_mailing_campaign_id': wizard.mass_mailing_campaign_id and wizard.mass_mailing_campaign_id.id or False,
|
||||
'name': wizard.mass_mailing_name,
|
||||
'template_id': wizard.template_id and wizard.template_id.id or False,
|
||||
'state': 'done',
|
||||
'mailing_type': wizard.model,
|
||||
'contact_list_ids': [(4, list_id) for list_id in list_ids],
|
||||
}, context=context)
|
||||
mass_mailing = self.pool['mail.mass_mailing'].browse(cr, uid, mass_mailing_id, context=context)
|
||||
recipient_values = self.pool['mail.mass_mailing'].get_recipients_data(cr, uid, mass_mailing, res_ids, context=context)
|
||||
for res_id in res_ids:
|
||||
mail_values = res[res_id]
|
||||
recipient = recipient_values[res_id]
|
||||
unsubscribe_url = self.pool['mail.mass_mailing'].get_unsubscribe_url(cr, uid, mass_mailing.id, res_id, recipient['email'], context=context)
|
||||
if unsubscribe_url:
|
||||
mail_values['body_html'] = tools.append_content_to_html(mail_values['body_html'], unsubscribe_url, plaintext=False, container_tag='p')
|
||||
mail_values.update({
|
||||
'email_to': '"%s" <%s>' % (recipient['name'], recipient['email'])
|
||||
})
|
||||
recipient = recipient_values[res_id]
|
||||
res[res_id]['statistics_ids'] = [(0, 0, {
|
||||
'model': wizard.model,
|
||||
'res_id': res_id,
|
||||
'mass_mailing_id': mass_mailing_id,
|
||||
'mass_mailing_id': mass_mailing.id,
|
||||
})]
|
||||
return res
|
||||
|
|
|
@ -7,12 +7,21 @@ from openerp.addons.web.http import request
|
|||
|
||||
class WebsiteEmailDesigner(http.Controller):
|
||||
|
||||
@http.route('/website_mail/email_designer/<model("email.template"):template>', type='http', auth="user", website=True, multilang=True)
|
||||
def index(self, template, **kw):
|
||||
@http.route('/website_mail/email_designer', type='http', auth="user", website=True, multilang=True)
|
||||
def index(self, model=None, res_id=None, **kw):
|
||||
if not model or not model in request.registry or not res_id:
|
||||
return request.redirect('/')
|
||||
if not 'body' in request.registry[model]._all_columns and not 'body_html' in request.registry[model]._all_columns:
|
||||
return request.redirect('/')
|
||||
obj_ids = request.registry[model].exists(request.cr, request.uid, [res_id], context=request.context)
|
||||
if not obj_ids:
|
||||
return request.redirect('/')
|
||||
values = {
|
||||
'template': template,
|
||||
'object': request.registry[model].browse(request.cr, request.uid, obj_ids[0], context=request.context),
|
||||
'model': request.registry[model],
|
||||
'model_name': model,
|
||||
'res_id': res_id,
|
||||
}
|
||||
print template
|
||||
return request.website.render("website_mail.designer_index", values)
|
||||
|
||||
@http.route(['/website_mail/snippets'], type='json', auth="user", website=True)
|
||||
|
|
|
@ -13,38 +13,38 @@
|
|||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<a class="pull-right mt32"
|
||||
t-att-href="'/web#return_label=Website&action=email_template.action_email_template_tree_all&view_type=form&id=%d' % template.id">
|
||||
<button class="btn btn-primary">Back to Template Form</button>
|
||||
t-att-href="'/web#return_label=Website&model=%s&id=%s&view_type=form' % (model_name, res_id)">
|
||||
<button class="btn btn-primary">Back to Form</button>
|
||||
</a>
|
||||
<h1 t-field="template.name"/>
|
||||
<h1 t-field="object.name"/>
|
||||
<div class="row" style="width: 600px;">
|
||||
<div class="row">
|
||||
<div t-if="'email_from' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>Email From</b></div>
|
||||
<div class="col-lg-9"><span t-field="template.email_from"/></div>
|
||||
<div class="col-lg-9"><span t-field="object.email_from"/></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div t-if="'email_to' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>To (Email)</b></div>
|
||||
<div class="col-lg-9"><span t-field="template.email_to"/></div>
|
||||
<div class="col-lg-9"><span t-field="object.email_to"/></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div t-if="'partner_to' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>To (Partners)</b></div>
|
||||
<div class="col-lg-9"><span t-field="template.partner_to"/></div>
|
||||
<div class="col-lg-9"><span t-field="object.partner_to"/></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div t-if="'reply_to' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>Reply To</b></div>
|
||||
<div class="col-lg-9"><span t-field="template.reply_to"/></div>
|
||||
<div class="col-lg-9"><span t-field="object.reply_to"/></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div t-if="'subject' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>Subject</b></div>
|
||||
<div class="col-lg-9"><span t-field="template.subject"/></div>
|
||||
<div class="col-lg-9"><span t-field="object.subject"/></div>
|
||||
</div>
|
||||
|
||||
<div class="row well">
|
||||
<div t-field="template.body_html" style="position: relative;"/>
|
||||
<div t-field="object.body_html" style="position: relative;"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue