summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
Diffstat (limited to 'addons')
-rw-r--r--addons/mass_mailing/models/mailing.py136
-rw-r--r--addons/mass_mailing/tests/__init__.py2
-rw-r--r--addons/mass_mailing/tests/common.py37
-rw-r--r--addons/mass_mailing/tests/test_mailing_internals.py73
-rw-r--r--addons/mass_mailing/views/mailing_mailing_views.xml2
-rw-r--r--addons/mass_mailing_event/models/__init__.py1
-rw-r--r--addons/mass_mailing_event/models/event.py6
-rw-r--r--addons/mass_mailing_event/models/mailing_mailing.py13
-rw-r--r--addons/mass_mailing_event_track/models/event.py2
-rw-r--r--addons/mass_mailing_slides/models/slide_channel.py2
-rw-r--r--addons/mass_mailing_sms/models/mailing_mailing.py50
-rw-r--r--addons/mass_mailing_sms/tests/__init__.py1
-rw-r--r--addons/mass_mailing_sms/tests/test_mailing_internals.py61
-rw-r--r--addons/test_mass_mailing/tests/test_mass_mailing.py6
14 files changed, 284 insertions, 108 deletions
diff --git a/addons/mass_mailing/models/mailing.py b/addons/mass_mailing/models/mailing.py
index 999b3f824b0..ee16a00b1d9 100644
--- a/addons/mass_mailing/models/mailing.py
+++ b/addons/mass_mailing/models/mailing.py
@@ -40,7 +40,7 @@ class MassMailing(models.Model):
A mass mailing is an occurence of sending emails. """
_name = 'mailing.mailing'
_description = 'Mass Mailing'
- _inherit = [ 'mail.thread', 'mail.activity.mixin', 'mail.render.mixin']
+ _inherit = ['mail.thread', 'mail.activity.mixin', 'mail.render.mixin']
# number of periods for tracking mail_mail statistics
_period_number = 6
_order = 'sent_date DESC'
@@ -56,16 +56,6 @@ class MassMailing(models.Model):
except ValueError:
return False
- @api.model
- def default_get(self, fields):
- res = super(MassMailing, self).default_get(fields)
- if 'reply_to_mode' in fields and not 'reply_to_mode' in res and res.get('mailing_model_real'):
- if res['mailing_model_real'] in ['res.partner', 'mailing.contact']:
- res['reply_to_mode'] = 'email'
- else:
- res['reply_to_mode'] = 'thread'
- return res
-
active = fields.Boolean(default=True, tracking=True)
subject = fields.Char('Subject', help='Subject of emails to send', required=True, translate=True)
email_from = fields.Char(string='Send From', required=True,
@@ -81,7 +71,10 @@ class MassMailing(models.Model):
campaign_id = fields.Many2one('utm.campaign', string='UTM Campaign')
source_id = fields.Many2one('utm.source', string='Source', required=True, ondelete='cascade',
help="This is the link source, e.g. Search Engine, another domain, or name of email list")
- medium_id = fields.Many2one('utm.medium', string='Medium', help="Delivery method: Email")
+ medium_id = fields.Many2one(
+ 'utm.medium', string='Medium',
+ compute='_compute_medium_id', readonly=False, store=True,
+ help="UTM Medium: delivery method (email, sms, ...)")
clicks_ratio = fields.Integer(compute="_compute_clicks_ratio", string="Number of Clicks")
state = fields.Selection([('draft', 'Draft'), ('in_queue', 'In Queue'), ('sending', 'Sending'), ('done', 'Sent')],
string='Status', required=True, tracking=True, copy=False, default='draft', group_expand='_group_expand_states')
@@ -89,21 +82,30 @@ class MassMailing(models.Model):
user_id = fields.Many2one('res.users', string='Responsible', tracking=True, default=lambda self: self.env.user)
# mailing options
mailing_type = fields.Selection([('mail', 'Email')], string="Mailing Type", default="mail", required=True)
- reply_to_mode = fields.Selection(
- [('thread', 'Recipient Followers'), ('email', 'Specified Email Address')], string='Reply-To Mode', required=True)
- reply_to = fields.Char(string='Reply To', help='Preferred Reply-To Address',
- default=lambda self: self.env.user.email_formatted)
+ reply_to_mode = fields.Selection([
+ ('thread', 'Recipient Followers'), ('email', 'Specified Email Address')],
+ string='Reply-To Mode', compute='_compute_reply_to_mode',
+ readonly=False, store=True,
+ help='Thread: replies go to target document. Email: replies are routed to a given email.')
+ reply_to = fields.Char(
+ string='Reply To', compute='_compute_reply_to', readonly=False, store=True,
+ help='Preferred Reply-To Address')
# recipients
- mailing_model_real = fields.Char(compute='_compute_model', string='Recipients Real Model', default='mailing.contact', required=True)
- mailing_model_id = fields.Many2one('ir.model', string='Recipients Model', domain=[('model', 'in', MASS_MAILING_BUSINESS_MODELS)],
+ mailing_model_real = fields.Char(string='Recipients Real Model', compute='_compute_model')
+ mailing_model_id = fields.Many2one(
+ 'ir.model', string='Recipients Model', ondelete='cascade', required=True,
+ domain=[('model', 'in', MASS_MAILING_BUSINESS_MODELS)],
default=lambda self: self.env.ref('mass_mailing.model_mailing_list').id)
- mailing_model_name = fields.Char(related='mailing_model_id.model', string='Recipients Model Name', readonly=True, related_sudo=True)
- mailing_domain = fields.Char(string='Domain', default=[])
+ mailing_model_name = fields.Char(
+ string='Recipients Model Name', related='mailing_model_id.model',
+ readonly=True, related_sudo=True)
+ mailing_domain = fields.Char(
+ string='Domain', compute='_compute_mailing_domain',
+ readonly=False, store=True)
mail_server_id = fields.Many2one('ir.mail_server', string='Mail Server',
default=_get_default_mail_server_id,
help="Use a specific mail server in priority. Otherwise Odoo relies on the first outgoing mail server available (based on their sequencing) as it does for normal mails.")
- contact_list_ids = fields.Many2many('mailing.list', 'mail_mass_mailing_list_rel',
- string='Mailing Lists')
+ contact_list_ids = fields.Many2many('mailing.list', 'mail_mass_mailing_list_rel', string='Mailing Lists')
contact_ab_pc = fields.Integer(string='A/B Testing percentage',
help='Percentage of the contacts that will be mailed. Recipients will be taken randomly.', default=100)
unique_ab_testing = fields.Boolean(string='Allow A/B Testing', default=False,
@@ -128,7 +130,7 @@ class MassMailing(models.Model):
replied_ratio = fields.Integer(compute="_compute_statistics", string='Replied Ratio')
bounced_ratio = fields.Integer(compute="_compute_statistics", string='Bounced Ratio')
next_departure = fields.Datetime(compute="_compute_next_departure", string='Scheduled date')
-
+
def _compute_total(self):
for mass_mailing in self:
mass_mailing.total = len(mass_mailing.sudo()._get_recipients())
@@ -147,11 +149,6 @@ class MassMailing(models.Model):
for mass_mailing in self:
mass_mailing.clicks_ratio = mapped_data.get(mass_mailing.id, 0)
- @api.depends('mailing_model_id')
- def _compute_model(self):
- for record in self:
- record.mailing_model_real = (record.mailing_model_name != 'mailing.list') and record.mailing_model_name or 'mailing.contact'
-
def _compute_statistics(self):
""" Compute statistics of the mass mailing """
self.env.cr.execute("""
@@ -197,30 +194,40 @@ class MassMailing(models.Model):
else:
mass_mailing.next_departure = cron_time
- @api.onchange('mailing_model_name', 'contact_list_ids')
- def _onchange_model_and_list(self):
- mailing_domain = literal_eval(self.mailing_domain) if self.mailing_domain else []
- if self.mailing_model_name:
- if mailing_domain:
- try:
- self.env[self.mailing_model_name].search(mailing_domain, limit=1)
- except:
- mailing_domain = []
- if not mailing_domain:
- if self.mailing_model_name == 'mailing.list' and self.contact_list_ids:
- mailing_domain = [('list_ids', 'in', self.contact_list_ids.ids)]
- elif 'is_blacklisted' in self.env[self.mailing_model_name]._fields and not self.mailing_domain:
- mailing_domain = [('is_blacklisted', '=', False)]
- elif 'opt_out' in self.env[self.mailing_model_name]._fields and not self.mailing_domain:
- mailing_domain = [('opt_out', '=', False)]
- else:
- mailing_domain = []
- self.mailing_domain = repr(mailing_domain)
+ @api.depends('mailing_type')
+ def _compute_medium_id(self):
+ for mailing in self:
+ if mailing.mailing_type == 'mail' and not mailing.medium_id:
+ mailing.medium_id = self.env.ref('utm.utm_medium_email').id
- @api.onchange('mailing_type')
- def _onchange_mailing_type(self):
- if self.mailing_type == 'mail' and not self.medium_id:
- self.medium_id = self.env.ref('utm.utm_medium_email').id
+ @api.depends('mailing_model_id')
+ def _compute_model(self):
+ for record in self:
+ record.mailing_model_real = (record.mailing_model_name != 'mailing.list') and record.mailing_model_name or 'mailing.contact'
+
+ @api.depends('mailing_model_real')
+ def _compute_reply_to_mode(self):
+ for mailing in self:
+ if mailing.mailing_model_real in ['res.partner', 'mailing.contact']:
+ mailing.reply_to_mode = 'email'
+ else:
+ mailing.reply_to_mode = 'thread'
+
+ @api.depends('reply_to_mode')
+ def _compute_reply_to(self):
+ for mailing in self:
+ if mailing.reply_to_mode == 'email' and not mailing.reply_to:
+ mailing.reply_to = self.env.user.email_formatted
+ elif mailing.reply_to_mode == 'thread':
+ mailing.reply_to = False
+
+ @api.depends('mailing_model_name', 'contact_list_ids')
+ def _compute_mailing_domain(self):
+ for mailing in self:
+ if not mailing.mailing_model_name:
+ mailing.mailing_domain = ''
+ else:
+ mailing.mailing_domain = repr(mailing._get_default_mailing_domain())
# ------------------------------------------------------
# ORM
@@ -232,8 +239,6 @@ class MassMailing(models.Model):
values['name'] = "%s %s" % (values['subject'], datetime.strftime(fields.datetime.now(), tools.DEFAULT_SERVER_DATETIME_FORMAT))
if values.get('body_html'):
values['body_html'] = self._convert_inline_images_to_urls(values['body_html'])
- if 'medium_id' not in values and values.get('mailing_type', 'mail') == 'mail':
- values['medium_id'] = self.env.ref('utm.utm_medium_email').id
return super(MassMailing, self).create(values)
def write(self, values):
@@ -474,16 +479,17 @@ class MassMailing(models.Model):
}
def _get_recipients(self):
- if self.mailing_domain:
- domain = safe_eval(self.mailing_domain)
- res_ids = self.env[self.mailing_model_real].search(domain).ids
- else:
+ try:
+ mailing_domain = literal_eval(self.mailing_domain)
+ except:
res_ids = []
- domain = [('id', 'in', res_ids)]
+ mailing_domain = [('id', 'in', res_ids)]
+ else:
+ res_ids = self.env[self.mailing_model_real].search(mailing_domain).ids
# randomly choose a fragment
if self.contact_ab_pc < 100:
- contact_nbr = self.env[self.mailing_model_real].search_count(domain)
+ contact_nbr = self.env[self.mailing_model_real].search_count(mailing_domain)
topick = int(contact_nbr / 100.0 * self.contact_ab_pc)
if self.campaign_id and self.unique_ab_testing:
already_mailed = self.campaign_id._get_mailing_recipients()[self.campaign_id.id]
@@ -574,6 +580,18 @@ class MassMailing(models.Model):
# TOOLS
# ------------------------------------------------------
+ def _get_default_mailing_domain(self):
+ mailing_domain = []
+ if self.mailing_model_name == 'mailing.list' and self.contact_list_ids:
+ mailing_domain = [('list_ids', 'in', self.contact_list_ids.ids)]
+
+ if self.mailing_type == 'mail' and 'is_blacklisted' in self.env[self.mailing_model_name]._fields:
+ mailing_domain = expression.AND([[('is_blacklisted', '=', False)], mailing_domain])
+ if self.mailing_type == 'mail' and 'opt_out' in self.env[self.mailing_model_name]._fields:
+ mailing_domain = expression.AND([[('opt_out', '=', False)], mailing_domain])
+
+ return mailing_domain
+
def _unsubscribe_token(self, res_id, email):
"""Generate a secure hash for this mailing list and parameters.
diff --git a/addons/mass_mailing/tests/__init__.py b/addons/mass_mailing/tests/__init__.py
index 36745d1525a..4d3ec554b79 100644
--- a/addons/mass_mailing/tests/__init__.py
+++ b/addons/mass_mailing/tests/__init__.py
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from . import common
+from . import test_mailing_internals
from . import test_mass_mailing_list_merge
from . import test_mass_mailing_shortener
diff --git a/addons/mass_mailing/tests/common.py b/addons/mass_mailing/tests/common.py
new file mode 100644
index 00000000000..3eb93ea226f
--- /dev/null
+++ b/addons/mass_mailing/tests/common.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.mail.tests.common import MailCase, mail_new_test_user
+from odoo.tests.common import SavepointCase
+
+
+class TestMassMailCommon(SavepointCase, MailCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestMassMailCommon, cls).setUpClass()
+
+ cls.user_marketing = mail_new_test_user(
+ cls.env, login='user_marketing',
+ groups='base.group_user,base.group_partner_manager,mass_mailing.group_mass_mailing_user',
+ name='Martial Marketing', signature='--\nMartial')
+
+ cls.mailing_list_1 = cls.env['mailing.list'].create({
+ 'name': 'List1',
+ 'contact_ids': [
+ (0, 0, {'name': 'Déboulonneur', 'email': 'fleurus@example.com'}),
+ (0, 0, {'name': 'Gorramts', 'email': 'gorramts@example.com'}),
+ (0, 0, {'name': 'Ybrant', 'email': 'ybrant@example.com'}),
+ ]
+ })
+ cls.mailing_list_2 = cls.env['mailing.list'].create({
+ 'name': 'List2',
+ 'contact_ids': [
+ (0, 0, {'name': 'Gilberte', 'email': 'gilberte@example.com'}),
+ (0, 0, {'name': 'Gilberte En Mieux', 'email': 'gilberte@example.com'}),
+ (0, 0, {'name': 'Norbert', 'email': 'norbert@example.com'}),
+ (0, 0, {'name': 'Ybrant', 'email': 'ybrant@example.com'}),
+ ]
+ })
+
+ cls.email_reply_to = 'MyCompany SomehowAlias <test.alias@test.mycompany.com>'
diff --git a/addons/mass_mailing/tests/test_mailing_internals.py b/addons/mass_mailing/tests/test_mailing_internals.py
new file mode 100644
index 00000000000..8f25119063d
--- /dev/null
+++ b/addons/mass_mailing/tests/test_mailing_internals.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from ast import literal_eval
+
+from odoo.addons.mass_mailing.tests.common import TestMassMailCommon
+from odoo.tests.common import users
+from odoo.tools import mute_logger
+
+
+class TestMassMailValues(TestMassMailCommon):
+
+ @users('user_marketing')
+ def test_mailing_computed_fields(self):
+ # Create on res.partner, with default values for computed fields
+ mailing = self.env['mailing.mailing'].create({
+ 'name': 'TestMailing',
+ 'subject': 'Test',
+ 'mailing_type': 'mail',
+ 'body_html': '<p>Hello ${object.name}</p>',
+ 'mailing_model_id': self.env['ir.model']._get('res.partner').id,
+ })
+ self.assertEqual(mailing.user_id, self.user_marketing)
+ self.assertEqual(mailing.medium_id, self.env.ref('utm.utm_medium_email'))
+ self.assertEqual(mailing.mailing_model_name, 'res.partner')
+ self.assertEqual(mailing.mailing_model_real, 'res.partner')
+ self.assertEqual(mailing.reply_to_mode, 'email')
+ self.assertEqual(mailing.reply_to, self.user_marketing.email_formatted)
+ # default for partner: remove blacklisted
+ self.assertEqual(literal_eval(mailing.mailing_domain), [('is_blacklisted', '=', False)])
+ # update domain
+ mailing.write({
+ 'mailing_domain': [('email', 'ilike', 'test.example.com')]
+ })
+ self.assertEqual(literal_eval(mailing.mailing_domain), [('email', 'ilike', 'test.example.com')])
+
+ # reset mailing model -> reset domain; set reply_to -> keep it
+ mailing.write({
+ 'mailing_model_id': self.env['ir.model']._get('mailing.list').id,
+ 'reply_to': self.email_reply_to,
+ })
+ self.assertEqual(mailing.mailing_model_name, 'mailing.list')
+ self.assertEqual(mailing.mailing_model_real, 'mailing.contact')
+ self.assertEqual(mailing.reply_to_mode, 'email')
+ self.assertEqual(mailing.reply_to, self.email_reply_to)
+ # default for mailing list: depends upon contact_list_ids
+ self.assertEqual(literal_eval(mailing.mailing_domain), [])
+ mailing.write({
+ 'contact_list_ids': [(4, self.mailing_list_1.id), (4, self.mailing_list_2.id)]
+ })
+ self.assertEqual(literal_eval(mailing.mailing_domain), [('list_ids', 'in', (self.mailing_list_1 | self.mailing_list_2).ids)])
+
+ # reset mailing model -> reset domain and reply to mode
+ mailing.write({
+ 'mailing_model_id': self.env['ir.model']._get('mail.channel').id,
+ })
+ self.assertEqual(mailing.mailing_model_name, 'mail.channel')
+ self.assertEqual(mailing.mailing_model_real, 'mail.channel')
+ self.assertEqual(mailing.reply_to_mode, 'thread')
+ self.assertFalse(mailing.reply_to)
+
+ @users('user_marketing')
+ def test_mailing_computed_fields_default(self):
+ mailing = self.env['mailing.mailing'].with_context(
+ default_mailing_domain=repr([('email', 'ilike', 'test.example.com')])
+ ).create({
+ 'name': 'TestMailing',
+ 'subject': 'Test',
+ 'mailing_type': 'mail',
+ 'body_html': '<p>Hello ${object.name}</p>',
+ 'mailing_model_id': self.env['ir.model']._get('res.partner').id,
+ })
+ self.assertEqual(literal_eval(mailing.mailing_domain), [('email', 'ilike', 'test.example.com')])
diff --git a/addons/mass_mailing/views/mailing_mailing_views.xml b/addons/mass_mailing/views/mailing_mailing_views.xml
index 53f60fcbbb6..414248e5034 100644
--- a/addons/mass_mailing/views/mailing_mailing_views.xml
+++ b/addons/mass_mailing/views/mailing_mailing_views.xml
@@ -144,7 +144,7 @@
<div name="mailing_model_id_container">
<div class="row">
<div class="col-xs-12 col-md-3" >
- <field name="mailing_model_id" widget="selection" required="True"
+ <field name="mailing_model_id" widget="selection"
attrs="{'readonly': [('state', 'in', ('sending', 'done'))]}"/>
</div>
<div attrs="{'invisible': [('mailing_model_name', '!=', 'mailing.list')]}" class="col-xs-12 col-md-9 pt-1">
diff --git a/addons/mass_mailing_event/models/__init__.py b/addons/mass_mailing_event/models/__init__.py
index 87f0737c96a..80862024115 100644
--- a/addons/mass_mailing_event/models/__init__.py
+++ b/addons/mass_mailing_event/models/__init__.py
@@ -2,4 +2,3 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import event
-from . import mailing_mailing
diff --git a/addons/mass_mailing_event/models/event.py b/addons/mass_mailing_event/models/event.py
index e0443acc7d3..88def04d85f 100644
--- a/addons/mass_mailing_event/models/event.py
+++ b/addons/mass_mailing_event/models/event.py
@@ -8,10 +8,6 @@ class Event(models.Model):
_inherit = "event.event"
def action_mass_mailing_attendees(self):
- if len(self) == 1:
- domain = "[('event_id', '=', {})]".format(self.id)
- else:
- domain = "[('event_id', 'in', {})]".format(self.ids)
mass_mailing_action = dict(
name='Mass Mail Attendees',
type='ir.actions.act_window',
@@ -20,7 +16,7 @@ class Event(models.Model):
target='current',
context=dict(
default_mailing_model_id=self.env.ref('event.model_event_registration').id,
- default_mailing_domain=domain,
+ default_mailing_domain=repr([('event_id', 'in', self.ids)])
),
)
return mass_mailing_action
diff --git a/addons/mass_mailing_event/models/mailing_mailing.py b/addons/mass_mailing_event/models/mailing_mailing.py
deleted file mode 100644
index cf70517af1c..00000000000
--- a/addons/mass_mailing_event/models/mailing_mailing.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from odoo import models, api
-
-
-class MassMailingCampaign(models.Model):
- _inherit = "mailing.mailing"
-
- @api.onchange('mailing_model_real', 'contact_list_ids')
- def _onchange_model_and_list(self):
- # TDE FIXME: whuuut ?
- result = super(MassMailingCampaign, self)._onchange_model_and_list()
- if self.mailing_model_name == 'event.registration' and self.mailing_domain == '[]':
- self.mailing_domain = self.env.context.get('default_mailing_domain', '[]')
- return result
diff --git a/addons/mass_mailing_event_track/models/event.py b/addons/mass_mailing_event_track/models/event.py
index c3395986fbd..c6210c728aa 100644
--- a/addons/mass_mailing_event_track/models/event.py
+++ b/addons/mass_mailing_event_track/models/event.py
@@ -16,7 +16,7 @@ class Event(models.Model):
target='current',
context=dict(
default_mailing_model_id=self.env.ref('website_event_track.model_event_track').id,
- default_mailing_domain="[('event_id', 'in', %s), ('stage_id.is_cancel', '!=', True)]" % self.ids,
+ default_mailing_domain=repr([('event_id', 'in', self.ids), ('stage_id.is_cancel', '!=', True)]),
),
)
return mass_mailing_action
diff --git a/addons/mass_mailing_slides/models/slide_channel.py b/addons/mass_mailing_slides/models/slide_channel.py
index 7822dc8113d..1c781c02da3 100644
--- a/addons/mass_mailing_slides/models/slide_channel.py
+++ b/addons/mass_mailing_slides/models/slide_channel.py
@@ -8,7 +8,7 @@ class Course(models.Model):
_inherit = "slide.channel"
def action_mass_mailing_attendees(self):
- domain = [('slide_channel_ids', 'in', self.ids)]
+ domain = repr([('slide_channel_ids', 'in', self.ids)])
mass_mailing_action = dict(
name=_('Mass Mail Course Members'),
type='ir.actions.act_window',
diff --git a/addons/mass_mailing_sms/models/mailing_mailing.py b/addons/mass_mailing_sms/models/mailing_mailing.py
index 1738e03dc78..d8064da6c0e 100644
--- a/addons/mass_mailing_sms/models/mailing_mailing.py
+++ b/addons/mass_mailing_sms/models/mailing_mailing.py
@@ -5,6 +5,7 @@ import logging
from odoo import api, fields, models, _
from odoo.exceptions import UserError
+from odoo.osv import expression
_logger = logging.getLogger(__name__)
@@ -22,7 +23,7 @@ class Mailing(models.Model):
# mailing options
mailing_type = fields.Selection(selection_add=[('sms', 'SMS')])
# sms options
- body_plaintext = fields.Text('SMS Body')
+ body_plaintext = fields.Text('SMS Body', compute='_compute_body_plaintext', store=True, readonly=False)
sms_template_id = fields.Many2one('sms.template', string='SMS Template', ondelete='set null')
sms_has_insufficient_credit = fields.Boolean(
'Insufficient IAP credits', compute='_compute_sms_has_insufficient_credit',
@@ -32,17 +33,20 @@ class Mailing(models.Model):
# opt_out_link
sms_allow_unsubscribe = fields.Boolean('Include opt-out link', default=False)
- @api.onchange('mailing_type')
- def _onchange_mailing_type(self):
- if self.mailing_type == 'sms' and (not self.medium_id or self.medium_id == self.env.ref('utm.utm_medium_email')):
- self.medium_id = self.env.ref('mass_mailing_sms.utm_medium_sms').id
- elif self.mailing_type == 'mail' and (not self.medium_id or self.medium_id == self.env.ref('mass_mailing_sms.utm_medium_sms')):
- self.medium_id = self.env.ref('utm.utm_medium_email').id
+ @api.depends('mailing_type')
+ def _compute_medium_id(self):
+ super(Mailing, self)._compute_medium_id()
+ for mailing in self:
+ if mailing.mailing_type == 'sms' and (not mailing.medium_id or mailing.medium_id == self.env.ref('utm.utm_medium_email')):
+ mailing.medium_id = self.env.ref('mass_mailing_sms.utm_medium_sms').id
+ elif mailing.mailing_type == 'mail' and (not mailing.medium_id or mailing.medium_id == self.env.ref('mass_mailing_sms.utm_medium_sms')):
+ mailing.medium_id = self.env.ref('utm.utm_medium_email').id
- @api.onchange('sms_template_id', 'mailing_type')
- def _onchange_sms_template_id(self):
- if self.mailing_type == 'sms' and self.sms_template_id:
- self.body_plaintext = self.sms_template_id.body
+ @api.depends('sms_template_id', 'mailing_type')
+ def _compute_body_plaintext(self):
+ for mailing in self:
+ if mailing.mailing_type == 'sms' and mailing.sms_template_id:
+ mailing.body_plaintext = mailing.sms_template_id.body
@api.depends('mailing_trace_ids.failure_type')
def _compute_sms_has_insufficient_credit(self):
@@ -55,19 +59,6 @@ class Mailing(models.Model):
mailing.sms_has_insufficient_credit = mailing in mailing_ids
# --------------------------------------------------
- # CRUD
- # --------------------------------------------------
-
- @api.model
- def create(self, values):
- if values.get('mailing_type') == 'sms':
- if not values.get('medium_id'):
- values['medium_id'] = self.env.ref('mass_mailing_sms.utm_medium_sms').id
- if values.get('sms_template_id') and not values.get('body_plaintext'):
- values['body_plaintext'] = self.env['sms.template'].browse(values['sms_template_id']).body
- return super(Mailing, self).create(values)
-
- # --------------------------------------------------
# BUSINESS / VIEWS ACTIONS
# --------------------------------------------------
@@ -219,3 +210,14 @@ class Mailing(models.Model):
composer._action_send_sms()
mailing.write({'state': 'done', 'sent_date': fields.Datetime.now()})
return True
+
+ # --------------------------------------------------
+ # TOOLS
+ # --------------------------------------------------
+
+ def _get_default_mailing_domain(self):
+ mailing_domain = super(Mailing, self)._get_default_mailing_domain()
+ if self.mailing_type == 'sms' and 'phone_blacklisted' in self.env[self.mailing_model_name]._fields:
+ mailing_domain = expression.AND([mailing_domain, [('phone_blacklisted', '=', False)]])
+
+ return mailing_domain
diff --git a/addons/mass_mailing_sms/tests/__init__.py b/addons/mass_mailing_sms/tests/__init__.py
index 511e649c9e2..56c4c9c54f6 100644
--- a/addons/mass_mailing_sms/tests/__init__.py
+++ b/addons/mass_mailing_sms/tests/__init__.py
@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import common
+from . import test_mailing_internals
diff --git a/addons/mass_mailing_sms/tests/test_mailing_internals.py b/addons/mass_mailing_sms/tests/test_mailing_internals.py
new file mode 100644
index 00000000000..049c41fae32
--- /dev/null
+++ b/addons/mass_mailing_sms/tests/test_mailing_internals.py
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from ast import literal_eval
+
+from odoo.addons.mass_mailing.tests.common import TestMassMailCommon
+from odoo.tests.common import users
+from odoo.tools import mute_logger
+
+
+class TestMassMailValues(TestMassMailCommon):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestMassMailValues, cls).setUpClass()
+
+ cls.sms_template_partner = cls.env['sms.template'].create({
+ 'name': 'Test Template',
+ 'model_id': cls.env['ir.model']._get('res.partner').id,
+ 'body': 'Dear ${object.display_name} this is an SMS.'
+ })
+
+ @users('user_marketing')
+ def test_mailing_computed_fields(self):
+ # Create on res.partner, with default values for computed fields
+ mailing = self.env['mailing.mailing'].create({
+ 'name': 'TestMailing',
+ 'subject': 'Test',
+ 'mailing_type': 'sms',
+ 'body_plaintext': 'Coucou hibou',
+ 'mailing_model_id': self.env['ir.model']._get('res.partner').id,
+ })
+ self.assertEqual(mailing.user_id, self.user_marketing)
+ self.assertEqual(mailing.body_plaintext, 'Coucou hibou')
+ self.assertEqual(mailing.medium_id, self.env.ref('mass_mailing_sms.utm_medium_sms'))
+ self.assertEqual(mailing.mailing_model_name, 'res.partner')
+ self.assertEqual(mailing.mailing_model_real, 'res.partner')
+ # default for partner: remove blacklisted
+ self.assertEqual(literal_eval(mailing.mailing_domain), [('phone_blacklisted', '=', False)])
+ # update template -> update body
+ mailing.write({'sms_template_id': self.sms_template_partner.id})
+ self.assertEqual(mailing.body_plaintext, self.sms_template_partner.body)
+ # update domain
+ mailing.write({
+ 'mailing_domain': [('email', 'ilike', 'test.example.com')]
+ })
+ self.assertEqual(literal_eval(mailing.mailing_domain), [('email', 'ilike', 'test.example.com')])
+
+ # reset mailing model -> reset domain; set reply_to -> keep it
+ mailing.write({
+ 'mailing_model_id': self.env['ir.model']._get('mailing.list').id,
+ 'reply_to': self.email_reply_to,
+ })
+ self.assertEqual(mailing.mailing_model_name, 'mailing.list')
+ self.assertEqual(mailing.mailing_model_real, 'mailing.contact')
+ # default for mailing list: depends upon contact_list_ids
+ self.assertEqual(literal_eval(mailing.mailing_domain), [])
+ mailing.write({
+ 'contact_list_ids': [(4, self.mailing_list_1.id), (4, self.mailing_list_2.id)]
+ })
+ self.assertEqual(literal_eval(mailing.mailing_domain), [('list_ids', 'in', (self.mailing_list_1 | self.mailing_list_2).ids)])
diff --git a/addons/test_mass_mailing/tests/test_mass_mailing.py b/addons/test_mass_mailing/tests/test_mass_mailing.py
index 430438e76a0..47d372f986a 100644
--- a/addons/test_mass_mailing/tests/test_mass_mailing.py
+++ b/addons/test_mass_mailing/tests/test_mass_mailing.py
@@ -135,7 +135,7 @@ class TestAccessRights(TransactionCase):
self.mass_mailing = mass_mailing.create({
'name': 'One',
'subject': 'One',
- 'mailing_model_id': self.env['ir.model']._get(mass_mailing_contacts).id,
+ 'mailing_model_id': self.env['ir.model']._get('mailing.contact').id,
'body_html': 'This is mass mail marketing demo'})
self.mass_mailing.contact_list_ids = [mailing_list_1.id]
self.mass_mailing.action_put_in_queue()
@@ -191,7 +191,7 @@ class TestAccessRights(TransactionCase):
self.mass_mailing = mass_mailing.create({
'name': 'One',
'subject': 'One',
- 'mailing_model_id': self.env['ir.model']._get(mass_mailing_contacts).id,
+ 'mailing_model_id': self.env['ir.model']._get('mailing.contact').id,
'body_html': 'This is mass mail marketing demo'})
self.mass_mailing.contact_list_ids = [mailing_list_1.id, mailing_list_2.id]
self.mass_mailing.action_put_in_queue()
@@ -241,7 +241,7 @@ class TestAccessRights(TransactionCase):
self.mass_mailing = mass_mailing.create({
'name': 'One',
'subject': 'One',
- 'mailing_model_id': self.env['ir.model']._get(mass_mailing_contacts).id,
+ 'mailing_model_id': self.env['ir.model']._get('mailing.contact').id,
'body_html': 'This is mass mail marketing demo'})
self.mass_mailing.contact_list_ids = [mailing_list_1.id]
self.mass_mailing.action_put_in_queue()