diff options
| author | Thibault Delavallée <tde@odoo.com> | 2021-05-06 09:15:28 +0000 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2021-05-21 16:45:37 +0000 |
| commit | 987d974ccb8c75c6eca899adb5be50fe48c8eb2c (patch) | |
| tree | bd1ac99d73bfc68c5eb33145841ff03dac055335 /addons/test_mail_full | |
| parent | 3ba3054f0aabd7307545712519594e9273dc7f28 (diff) | |
[FIX] sale, mass_mailing_sms, test_mail_full: correctly support partner-only records
When performing an sms marketing on a model having only a ``partner_id``
field available (aka no ``phone`` or ``mobile``) it crashes due to seen
list computation (aka already contacted recipients). This is due to an SQL
query not taking into account those models as it works only for those with
a phone field.
We fix it as done in ``mass_mailìng`` app, aka fetching information on the
related partner if available.
Some tests for models using a 2many relationships towards recipients are
added. Note that this kind of model does not really support complete SMS
notification, as only the first found partner is notified. Mass SMS on this
kind of model is currently not possible as seen list is not supported. There
is no standard use case of this in Odoo codebase.
Correctly support sms marketing on sale model by defining the necessary
methods. As sale order has only a partner_id field available we have to
correctly override phone related methods for SMS.
LINKS
Task ID-2431217
COM PR odoo/odoo#71140
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Diffstat (limited to 'addons/test_mail_full')
| -rw-r--r-- | addons/test_mail_full/models/mailing_mailing.py | 3 | ||||
| -rw-r--r-- | addons/test_mail_full/models/test_mail_models.py | 18 | ||||
| -rw-r--r-- | addons/test_mail_full/security/ir.model.access.csv | 2 | ||||
| -rw-r--r-- | addons/test_mail_full/tests/test_mass_sms.py | 83 | ||||
| -rw-r--r-- | addons/test_mail_full/tests/test_sms_post.py | 18 |
5 files changed, 122 insertions, 2 deletions
diff --git a/addons/test_mail_full/models/mailing_mailing.py b/addons/test_mail_full/models/mailing_mailing.py index a97c41e9047..8d8a49a1ec9 100644 --- a/addons/test_mail_full/models/mailing_mailing.py +++ b/addons/test_mail_full/models/mailing_mailing.py @@ -15,7 +15,8 @@ class Mailing(models.Model): """Returns a set of emails opted-out in target model""" self.ensure_one() if self.mailing_model_real in ('mail.test.sms.bl.optout', - 'mail.test.sms.partner'): + 'mail.test.sms.partner', + 'mail.test.sms.partner.2many'): res_ids = self._get_recipients() opt_out_contacts = set(self.env[self.mailing_model_real].search([ ('id', 'in', res_ids), diff --git a/addons/test_mail_full/models/test_mail_models.py b/addons/test_mail_full/models/test_mail_models.py index 9ee84a0b3a2..a3b5eb8dc4d 100644 --- a/addons/test_mail_full/models/test_mail_models.py +++ b/addons/test_mail_full/models/test_mail_models.py @@ -89,3 +89,21 @@ class MailTestSMSPartner(models.Model): def _sms_get_number_fields(self): return [] + + +class MailTestSMSPartner2Many(models.Model): + """ A model like sale order having only a customer, not specific phone + or mobile fields. """ + _description = 'Chatter Model for SMS Gateway (M2M Partners only)' + _name = 'mail.test.sms.partner.2many' + _inherit = ['mail.thread'] + + name = fields.Char() + customer_ids = fields.Many2many('res.partner', string='Customers') + opt_out = fields.Boolean() + + def _sms_get_partner_fields(self): + return ['customer_ids'] + + def _sms_get_number_fields(self): + return [] diff --git a/addons/test_mail_full/security/ir.model.access.csv b/addons/test_mail_full/security/ir.model.access.csv index b65c78635ce..5a099a7d8b4 100644 --- a/addons/test_mail_full/security/ir.model.access.csv +++ b/addons/test_mail_full/security/ir.model.access.csv @@ -7,3 +7,5 @@ access_mail_test_sms_bl_optout_all,mail.test.sms.bl.optout.all,model_mail_test_s access_mail_test_sms_bl_optout_user,mail.test.sms.bl.optout.user,model_mail_test_sms_bl_optout,base.group_user,1,1,1,1 access_mail_test_sms_partner_all,mail.test.sms.partner.all,model_mail_test_sms_partner,,0,0,0,0 access_mail_test_sms_partner_user,mail.test.sms.partner.user,model_mail_test_sms_partner,base.group_user,1,1,1,1 +access_mail_test_sms_partner_2many_all,mail.test.sms.partner.2many.all,model_mail_test_sms_partner_2many,,0,0,0,0 +access_mail_test_sms_partner_2many_user,mail.test.sms.partner.2many.user,model_mail_test_sms_partner_2many,base.group_user,1,1,1,1 diff --git a/addons/test_mail_full/tests/test_mass_sms.py b/addons/test_mail_full/tests/test_mass_sms.py index 9dc48232ab3..dbc91b95c77 100644 --- a/addons/test_mail_full/tests/test_mass_sms.py +++ b/addons/test_mail_full/tests/test_mass_sms.py @@ -5,6 +5,7 @@ from ast import literal_eval from odoo.addons.phone_validation.tools import phone_validation from odoo.addons.test_mail_full.tests.common import TestMailFullCommon +from odoo import exceptions from odoo.tests import tagged from odoo.tests.common import users from odoo.tools import mute_logger @@ -262,7 +263,7 @@ class TestMassSMSInternals(TestMassSMSCommon): mailing_test.action_send_sms() -@tagged('mass_mailing') +@tagged('mass_mailing', 'mass_mailing_sms') class TestMassSMS(TestMassSMSCommon): @users('user_marketing') @@ -295,6 +296,86 @@ class TestMassSMS(TestMassSMSCommon): @users('user_marketing') @mute_logger('odoo.addons.mail.models.mail_mail') + def test_mass_sms_partner_only(self): + """ Check sending SMS marketing on models having only a partner_id fields + set is working. """ + mailing = self.env['mailing.mailing'].browse(self.mailing_sms.ids) + mailing.write({ + 'mailing_model_id': self.env['ir.model']._get('mail.test.sms.partner').id, + }) + + records = self.env['mail.test.sms.partner'].create([ + {'name': 'SMSTest on %s' % partner.name, + 'customer_id': partner.id, + } for partner in self.partners + ]) + + with self.mockSMSGateway(): + mailing.action_send_sms() + + self.assertEqual(len(mailing.mailing_trace_ids), 10) + self.assertSMSTraces( + [{'partner': record.customer_id, + 'number': record.customer_id.phone_sanitized, + 'state': 'sent', + 'content': 'Dear %s this is a mass SMS with two links' % record.display_name + } for record in records], + mailing, records, + sms_links_info=[[ + ('http://www.odoo.com/smstest', True, {}), + ('http://www.odoo.com/smstest/%s' % record.id, True, {}), + # unsubscribe is not shortened and parsed at sending + ('unsubscribe', False, {}), + ] for record in records], + ) + + # add a new record, send -> sent list should not resend traces + new_record = self.env['mail.test.sms.partner'].create([ + {'name': 'Duplicate SMS on %s' % self.partners[0].name, + 'customer_id': self.partners[0].id, + } + ]) + with self.mockSMSGateway(): + mailing.action_send_sms() + + self.assertEqual(len(mailing.mailing_trace_ids), 11) + self.assertSMSTraces( + [{'partner': new_record.customer_id, + 'number': new_record.customer_id.phone_sanitized, + 'state': 'sent', + 'content': 'Dear %s this is a mass SMS with two links' % new_record.display_name + }], + mailing, new_record, + sms_links_info=[[ + ('http://www.odoo.com/smstest', True, {}), + ('http://www.odoo.com/smstest/%s' % new_record.id, True, {}), + # unsubscribe is not shortened and parsed at sending + ('unsubscribe', False, {}), + ]], + ) + + @users('user_marketing') + @mute_logger('odoo.addons.mail.models.mail_mail') + def test_mass_sms_partner_only_m2m(self): + """ Check sending SMS marketing on models having only a m2m to partners + is currently not suppored. """ + mailing = self.env['mailing.mailing'].browse(self.mailing_sms.ids) + mailing.write({ + 'mailing_model_id': self.env['ir.model']._get('mail.test.sms.partner.2many').id, + }) + + records = self.env['mail.test.sms.partner.2many'].create([ + {'name': 'SMSTest on %s' % partner.name, + 'customer_ids': [(4, partner.id)], + } for partner in self.partners + ]) + + with self.assertRaises(exceptions.UserError), self.mockSMSGateway(): + mailing.action_send_sms() + + + @users('user_marketing') + @mute_logger('odoo.addons.mail.models.mail_mail') def test_mass_sms_w_opt_out(self): mailing = self.env['mailing.mailing'].browse(self.mailing_sms.ids) recipients = self._create_mailing_sms_test_records(model='mail.test.sms.bl.optout', count=5) diff --git a/addons/test_mail_full/tests/test_sms_post.py b/addons/test_mail_full/tests/test_sms_post.py index 6851974fd88..ad39f0c2a8a 100644 --- a/addons/test_mail_full/tests/test_sms_post.py +++ b/addons/test_mail_full/tests/test_sms_post.py @@ -108,6 +108,24 @@ class TestSMSPost(TestMailFullCommon, TestRecipients): # should not crash but have a failed notification self.assertSMSNotification([{'partner': self.env['res.partner'], 'number': False, 'state': 'exception', 'failure_type': 'sms_number_missing'}], self._test_body, messages) + def test_message_sms_model_w_partner_m2m_only(self): + with self.with_user('employee'): + record = self.env['mail.test.sms.partner.2many'].create({'customer_ids': [(4, self.partner_1.id)]}) + + with self.mockSMSGateway(): + messages = record._message_sms(self._test_body) + + self.assertSMSNotification([{'partner': self.partner_1}], self._test_body, messages) + + # TDE: should take first found one according to partner ordering + with self.with_user('employee'): + record = self.env['mail.test.sms.partner.2many'].create({'customer_ids': [(4, self.partner_1.id), (4, self.partner_2.id)]}) + + with self.mockSMSGateway(): + messages = record._message_sms(self._test_body) + + self.assertSMSNotification([{'partner': self.partner_2}], self._test_body, messages) + def test_message_sms_on_field_w_partner(self): with self.with_user('employee'), self.mockSMSGateway(): test_record = self.env['mail.test.sms'].browse(self.test_record.id) |
