[IMP] sms: add a is_mail_thread_sms field allowing to filter models

PURPOSE

SMS are a powerful marketing tool. For instance it is perfect to announce a
sale or to communicate a coupon code, to welcome a new customer in a fidelity
program, ...

Purpose of this task is to integrate SMS sending in batch in mass mailing. It
will use same mailing objects but sending SMS instead of emails. Some metrics
and flows will have to be slightly updated at the same time.

SPECIFICATIONS

Limit use of templates to models that are really capable of sending
SMS. Templates are now available on models that inherit from mail.thread
and effectively have fields used in SMS sending.

Technically this is done through a not stored field on ir.model that is
searchable. SMS sending capabilities is based on

  * having fields holding phone numbers, as defined on mail.thread in SMS;
  * having fields holding partners, as defined on mail.thread in SMS;

This implied some code rewriting notably about finding default SMS
recipients on a given model, in order to have fields instead of directly
returning partners.

LINKS

Task 1997464
PR #34424
Original SMS addition: Task 1922163 (4287481)
This commit is contained in:
Thibault Delavallée
2019-08-12 12:00:22 +00:00
parent 5450415354
commit e7cd604afa
7 changed files with 62 additions and 12 deletions
+1 -1
View File
@@ -545,7 +545,7 @@ class Meeting(models.Model):
"""
_name = 'calendar.event'
_description = "Event"
_description = "Calendar Event"
_order = "id desc"
_inherit = ["mail.thread"]
+2 -2
View File
@@ -381,8 +381,8 @@ class HrEmployeePrivate(models.Model):
def message_post(self, *args, **kwargs):
return super(HrEmployeePrivate, self._post_author()).message_post(*args, **kwargs)
def _sms_get_default_partners(self):
return self.mapped('user_partner_id')
def _sms_get_partner_fields(self):
return ['user_partner_id']
def _sms_get_number_fields(self):
return ['mobile_phone']
+1
View File
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import ir_actions
from . import ir_model
from . import mail_followers
from . import mail_message
from . import mail_notification
+39
View File
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class IrModel(models.Model):
_inherit = 'ir.model'
is_mail_thread_sms = fields.Boolean(
string="Mail Thread SMS", default=False,
store=False, compute='_compute_is_mail_thread_sms', search='_search_is_mail_thread_sms',
help="Whether this model supports messages and notifications through SMS",
)
@api.depends('is_mail_thread')
def _compute_is_mail_thread_sms(self):
for model in self:
if model.is_mail_thread:
ModelObject = self.env[model.model]
potential_fields = ModelObject._sms_get_number_fields() + ModelObject._sms_get_partner_fields()
if any(fname in ModelObject._fields for fname in potential_fields):
model.is_mail_thread_sms = True
continue
model.is_mail_thread_sms = False
def _search_is_mail_thread_sms(self, operator, value):
thread_models = self.search([('is_mail_thread', '=', True)])
valid_models = self.env['ir.model']
for model in thread_models:
ModelObject = self.env[model.model]
potential_fields = ModelObject._sms_get_number_fields() + ModelObject._sms_get_partner_fields()
if any(fname in ModelObject._fields for fname in potential_fields):
valid_models |= model
search_sms = (operator == '=' and value) or (operator == '!=' and not value)
if search_sms:
return [('id', 'in', valid_models.ids)]
return [('id', 'not in', valid_models.ids)]
+14 -4
View File
@@ -35,15 +35,25 @@ class MailThread(models.AbstractModel):
def _search_message_has_sms_error(self, operator, operand):
return ['&', ('message_ids.has_sms_error', operator, operand), ('message_ids.author_id', '=', self.env.user.partner_id.id)]
def _sms_get_partner_fields(self):
""" This method returns the fields to use to find the contact to link
whensending an SMS. Having partner is not necessary, having only phone
number fields is possible. However it gives more flexibility to
notifications management when having partners. """
fields = []
if hasattr(self, 'partner_id'):
fields.append('partner_id')
if hasattr(self, 'partner_ids'):
fields.append('partner_ids')
return fields
def _sms_get_default_partners(self):
""" This method will likely need to be overridden by inherited models.
:returns partners: recordset of res.partner
"""
partners = self.env['res.partner']
if hasattr(self, 'partner_id'):
partners |= self.mapped('partner_id')
if hasattr(self, 'partner_ids'):
partners |= self.mapped('partner_ids')
for fname in self._sms_get_partner_fields():
partners |= self.mapped(fname)
return partners
def _sms_get_number_fields(self):
+1 -1
View File
@@ -19,7 +19,7 @@ class SMSTemplate(models.Model):
name = fields.Char('Name', translate=True)
model_id = fields.Many2one(
'ir.model', string='Applies to', required=True,
domain=['&', ('is_mail_thread', '=', True), ('transient', '=', False)],
domain=['&', ('is_mail_thread_sms', '=', True), ('transient', '=', False)],
help="The type of document this template can be used with")
model = fields.Char('Related Document Model', related='model_id.model', index=True, store=True, readonly=True)
body = fields.Char('Body', translate=True, required=True)
@@ -19,8 +19,8 @@ class MailTestSMS(models.Model):
mobile_nbr = fields.Char()
customer_id = fields.Many2one('res.partner', 'Customer')
def _sms_get_default_partners(self):
return self.mapped('customer_id')
def _sms_get_partner_fields(self):
return ['customer_id']
def _sms_get_number_fields(self):
return ['phone_nbr', 'mobile_nbr']
@@ -41,8 +41,8 @@ class MailTestSMSBL(models.Model):
mobile_nbr = fields.Char()
customer_id = fields.Many2one('res.partner', 'Customer')
def _sms_get_default_partners(self):
return self.mapped('customer_id')
def _sms_get_partner_fields(self):
return ['customer_id']
def _sms_get_number_fields(self):
return ['phone_nbr', 'mobile_nbr']