[IMP] mass_mailing: choose model among all chatter models

This commit removes the strange selection box based on a magic flag and
some strange methods returning a string. Instead just allow to send mass
mailing on all models inheriting from mail.thread using the is mail
thread flag.

Various addons are updated to remove the _mail_mass_mailing class
attribute used to determine mass mailing capability.

We consider people could send a mass mailing on every model inheriting
from mail.thread. It makes no sense to limit it to a given set of addons.
This commit is contained in:
Yannick Tivisse
2017-09-15 15:56:23 +02:00
parent e9fca14452
commit 51b5ee7c3c
15 changed files with 24 additions and 52 deletions
-1
View File
@@ -51,7 +51,6 @@ class Lead(models.Model):
_description = "Lead/Opportunity"
_order = "priority desc,activity_date_deadline,id desc"
_inherit = ['mail.thread', 'mail.activity.mixin', 'utm.mixin', 'format.address.mixin']
_mail_mass_mailing = _('Leads / Opportunities')
def _default_probability(self):
stage_id = self._default_stage_id()
+1 -1
View File
@@ -319,12 +319,12 @@ class EventEvent(models.Model):
def _is_event_registrable(self):
return True
class EventRegistration(models.Model):
_name = 'event.registration'
_description = 'Attendee'
_inherit = ['mail.thread']
_order = 'name, create_date desc'
_mail_mass_mailing = _('Event Attendees')
origin = fields.Char(
string='Source Document', readonly=True,
@@ -89,7 +89,6 @@ class Applicant(models.Model):
_description = "Applicant"
_order = "priority desc, id desc"
_inherit = ['mail.thread', 'mail.activity.mixin', 'utm.mixin']
_mail_mass_mailing = _('Applicants')
def _default_stage_id(self):
if self._context.get('default_job_id'):
-11
View File
@@ -79,7 +79,6 @@ class MailThread(models.AbstractModel):
_description = 'Email Thread'
_mail_flat_thread = True # flatten the discussino history
_mail_post_access = 'write' # access required on the document to post on it
_mail_mass_mailing = False # enable mass mailing on this model
_Attachment = namedtuple('Attachment', ('fname', 'content', 'info'))
message_is_follower = fields.Boolean(
@@ -2201,13 +2200,3 @@ class MailThread(models.AbstractModel):
msg_comment.write({"res_id": new_thread.id, "model": new_thread._name})
msg_not_comment.write({"res_id": new_thread.id, "model": new_thread._name, "subtype_id": None})
return True
# ------------------------------------------------------
# Mass mailing
# ------------------------------------------------------
def message_mass_mailing_enabled(self):
if self._mail_mass_mailing:
# TODO master properly translate
# the _mail_mass_mailing is evaluted at code start so not translated
return _(self._mail_mass_mailing)
-1
View File
@@ -18,7 +18,6 @@ class Partner(models.Model):
_name = "res.partner"
_inherit = ['res.partner', 'mail.thread', 'mail.activity.mixin']
_mail_flat_thread = False
_mail_mass_mailing = _('Customers')
message_bounce = fields.Integer('Bounce', help="Counter of the number of bounced emails for this contact", default=0)
opt_out = fields.Boolean(
+1 -1
View File
@@ -17,7 +17,7 @@ class MassMailController(http.Controller):
if mailing.exists():
res_id = res_id and int(res_id)
res_ids = []
if mailing.mailing_model == 'mail.mass_mailing.contact':
if mailing.mailing_model_name == 'mail.mass_mailing.contact':
contacts = request.env['mail.mass_mailing.contact'].sudo().search([
('email', '=', email),
('list_id', 'in', [mailing_list.id for mailing_list in mailing.contact_list_ids])
@@ -64,7 +64,7 @@
<field name="state">done</field>
<field name="sent_date" eval="(DateTime.today() - relativedelta(days=5)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="mass_mailing_campaign_id" eval="ref('mass_mail_campaign_1')"/>
<field name="mailing_model">res.partner</field>
<field name="mailing_model_id" ref="base.model_res_partner"/>
<field name="mailing_domain">[('customer', '=', True)]</field>
<field name="reply_to_mode">email</field>
<field name="reply_to"><![CDATA[Info <info@yourcompany.example.com>]]></field>
@@ -77,7 +77,7 @@
<field name="name">Second Newsletter</field>
<field name="state">draft</field>
<field name="mass_mailing_campaign_id" eval="ref('mass_mail_campaign_1')"/>
<field name="mailing_model">res.partner</field>
<field name="mailing_model_id" ref="base.model_res_partner"/>
<field name="mailing_domain">[('customer', '=', True)]</field>
<field name="reply_to_mode">email</field>
<field name="reply_to"><![CDATA[Info <info@yourcompany.example.com>]]></field>
+8 -22
View File
@@ -290,22 +290,6 @@ class MassMailing(models.Model):
res['reply_to_mode'] = 'thread'
return res
def _get_mailing_model(self):
res = []
for model_name in self.env:
model = self.env[model_name]
if hasattr(model, '_mail_mass_mailing') and getattr(model, '_mail_mass_mailing'):
if hasattr(model, 'message_mass_mailing_enabled'):
res.append((model._name, model.message_mass_mailing_enabled()))
else:
res.append((model._name, model._mail_mass_mailing))
res.append(('mail.mass_mailing.contact', _('Mail Contacts')))
res.append(('mail.mass_mailing.list', _('Mailing List')))
return res
# indirections for inheritance
_mailing_model = lambda self: self._get_mailing_model()
active = fields.Boolean(default=True)
email_from = fields.Char(string='From', required=True,
default=lambda self: self.env['mail.message']._get_default_from())
@@ -335,7 +319,9 @@ class MassMailing(models.Model):
default=lambda self: self.env['mail.message']._get_default_from())
# recipients
mailing_model_real = fields.Char(compute='_compute_model', string='Recipients Real Model', default='mail.mass_mailing.contact', required=True)
mailing_model = fields.Selection(selection=_mailing_model, string='Recipients Model', default='mail.mass_mailing.list')
mailing_model_id = fields.Many2one('ir.model', string='Recipients Model', domain="[('is_mail_thread', '=', True)]",
default=lambda self: self.env.ref('mass_mailing.model_mail_mass_mailing_list').id)
mailing_model_name = fields.Char(related='mailing_model_id.model', string='Recipients Model Name')
mailing_domain = fields.Char(string='Domain', oldname='domain', default=[])
contact_list_ids = fields.Many2many('mail.mass_mailing.list', 'mail_mass_mailing_list_rel',
string='Mailing Lists')
@@ -376,10 +362,10 @@ class MassMailing(models.Model):
for mass_mailing in self:
mass_mailing.clicks_ratio = mapped_data.get(mass_mailing.id, 0)
@api.depends('mailing_model')
@api.depends('mailing_model_id')
def _compute_model(self):
for record in self:
record.mailing_model_real = (record.mailing_model != 'mail.mass_mailing.list') and record.mailing_model or 'mail.mass_mailing.contact'
record.mailing_model_real = (record.mailing_model_name != 'mail.mass_mailing.list') and record.mailing_model_name or 'mail.mass_mailing.contact'
def _compute_statistics(self):
""" Compute statistics of the mass mailing """
@@ -451,14 +437,14 @@ class MassMailing(models.Model):
'medium_id': self.mass_mailing_campaign_id.medium_id}
self.update(dic)
@api.onchange('mailing_model', 'contact_list_ids')
@api.onchange('mailing_model_id', 'contact_list_ids')
def _onchange_model_and_list(self):
if self.mailing_model == 'mail.mass_mailing.list':
if self.mailing_model_name == 'mail.mass_mailing.list':
if self.contact_list_ids:
self.mailing_domain = "[('list_ids', 'in', [%s]), ('opt_out', '=', False)]" % (','.join(str(id) for id in self.contact_list_ids.ids),)
else:
self.mailing_domain = "[(0, '=', 1)]"
elif 'opt_out' in self.env[self.mailing_model]._fields and not self.mailing_domain:
elif 'opt_out' in self.env[self.mailing_model_name]._fields and not self.mailing_domain:
self.mailing_domain = "[('opt_out', '=', False)]"
self.body_html = "on_change_model_and_list"
@@ -413,15 +413,16 @@
<div>
<field name="name" nolabel="1"/>
</div>
<label for="mailing_model" string="Recipients"/>
<label for="mailing_model_id" string="Recipients"/>
<div>
<field name="mailing_model" widget="radio" options="{'horizontal': true}"/>
<field name="mailing_model_id"/>
<field name="mailing_model_name" invisible="1"/>
<field name="mailing_model_real" invisible="1"/>
<field name="mailing_domain" widget="domain"
attrs="{'invisible': [('mailing_model', '=', 'mail.mass_mailing.list')]}"
attrs="{'invisible': [('mailing_model_name', '=', 'mail.mass_mailing.list')]}"
options="{'model': 'mailing_model_real'}"
context="{'search_default_not_opt_out':1}"/>
<div attrs="{'invisible': [('mailing_model', '!=', 'mail.mass_mailing.list')]}">
<div attrs="{'invisible': [('mailing_model_name', '!=', 'mail.mass_mailing.list')]}">
<label for="contact_list_ids" string="Select mailing lists:" class="oe_edit_only"/>
<field name="contact_list_ids" widget="many2many_tags"
placeholder="Select mailing lists..." class="oe_inline"/>
@@ -443,7 +444,7 @@
<label for="reply_to"/>
<div>
<field name="reply_to_mode" widget="radio"
attrs="{'invisible': [('mailing_model', 'in', ['mail.mass_mailing.contact', 'res.partner'])]}"/>
attrs="{'invisible': [('mailing_model_name', 'in', ['mail.mass_mailing.contact', 'res.partner'])]}"/>
<field name="reply_to"
attrs="{'required': [('reply_to_mode', '=', 'email')]}"/>
</div>
@@ -23,7 +23,7 @@ class MailComposeMessage(models.TransientModel):
# use only for allowed models in mass mailing
if self.composition_mode == 'mass_mail' and \
(self.mass_mailing_name or self.mass_mailing_id) and \
self.model in [item[0] for item in self.env['mail.mass_mailing']._get_mailing_model()]:
self.env['ir.model'].sudo().search([('model', '=', self.model), ('is_mail_thread', '=', True)], limit=1):
mass_mailing = self.mass_mailing_id
if not mass_mailing:
reply_to_mode = 'email' if self.no_auto_thread else 'thread'
@@ -37,7 +37,7 @@ class MailComposeMessage(models.TransientModel):
'reply_to': reply_to,
'sent_date': fields.Datetime.now(),
'body_html': self.body,
'mailing_model': self.model,
'mailing_model_id': self.env['ir.model'].search([('model', '=', self.model)], limit=1).id,
'mailing_domain': self.active_domain,
})
+1 -1
View File
@@ -16,7 +16,7 @@ class Event(models.Model):
view_mode='form',
target='current',
context=dict(
default_mailing_model='event.registration',
default_mailing_model_id=self.env.ref('event.model_event_registration').id,
default_mailing_domain="[('event_id', 'in', %s)]" % self.ids, # , ('state', 'in', ['draft', 'open', 'done'])
),
)
@@ -16,7 +16,7 @@ class Event(models.Model):
view_mode='form',
target='current',
context=dict(
default_mailing_model='event.track',
default_mailing_model=self.env.ref('website_event_track.model_event_track').id,
default_mailing_domain="[('event_id', 'in', %s), ('stage_id.is_cancel', '!=', True)]" % self.ids,
),
)
@@ -50,7 +50,6 @@ class Track(models.Model):
_description = 'Event Track'
_order = 'priority, date'
_inherit = ['mail.thread', 'mail.activity.mixin', 'website.seo.metadata', 'website.published.mixin']
_mail_mass_mailing = _('Track Speakers')
@api.model
def _get_default_stage_id(self):
@@ -11,7 +11,7 @@ class MassMailController(MassMailController):
def mailing(self, mailing_id, email=None, res_id=None, **post):
mailing = request.env['mail.mass_mailing'].sudo().browse(mailing_id)
if mailing.exists():
if mailing.mailing_model == 'mail.mass_mailing.contact':
if mailing.mailing_model_name == 'mail.mass_mailing.contact':
contacts = request.env['mail.mass_mailing.contact'].sudo().search([('email', '=', email)])
return request.render('website_mass_mailing.page_unsubscribe', {
'contacts': contacts,
+1 -1
View File
@@ -84,7 +84,7 @@
<record model="ir.rule" id="res_partner_rule">
<field name="name">res.partner company</field>
<field name="model_id" ref="model_res_partner"/>
<field name="model_id" ref="base.model_res_partner"/>
<!--
Show partners from ancestors and descendants companies
(or company-less), this is usually a better default for