- Mass SMS Statistics allows you to check different mailing related information like number of sent SMS or bounced SMS.
+ SMS Marketing Statistics allows you to check different mailing related information like number of sent SMS or bounced SMS.
You can sort out your analysis by different groups to get accurate grained analysis.
- Blacklisted phone numbers means that the recipient won't receive mass SMS anymore.
+ Blacklisted phone numbers means that the recipient won't receive SMS Marketing anymore.
diff --git a/addons/sms/__manifest__.py b/addons/sms/__manifest__.py
index 2b15020a219..90462b4c8fb 100644
--- a/addons/sms/__manifest__.py
+++ b/addons/sms/__manifest__.py
@@ -16,6 +16,7 @@ The service is provided by the In App Purchase Odoo platform.
'data/ir_cron_data.xml',
'wizard/sms_cancel_views.xml',
'wizard/sms_composer_views.xml',
+ 'wizard/sms_template_preview_views.xml',
'wizard/sms_resend_views.xml',
'views/ir_actions_views.xml',
'views/res_config_settings_views.xml',
diff --git a/addons/sms/data/mail_demo.xml b/addons/sms/data/mail_demo.xml
index 103a89fbd8c..8086bef21fe 100644
--- a/addons/sms/data/mail_demo.xml
+++ b/addons/sms/data/mail_demo.xml
@@ -18,20 +18,20 @@
-
-
-
- email
- exception
- SMTP
-
+
+
+
+ email
+ exception
+ SMTP
+ res.partner
Hello! This is an example of SMS.
sms
-
+
@@ -40,23 +40,23 @@
Hello! This is an example of another SMS with notifications.
sms
-
+
-
-
-
- sms
- exception
- sms_credit
-
-
-
-
- sms
- exception
- sms_credit
-
+
+
+
+ sms
+ exception
+ sms_credit
+
+
+
+
+ sms
+ exception
+ sms_credit
+
diff --git a/addons/sms/models/sms_sms.py b/addons/sms/models/sms_sms.py
index 9ea635b2070..8bf9c8c2924 100644
--- a/addons/sms/models/sms_sms.py
+++ b/addons/sms/models/sms_sms.py
@@ -56,6 +56,9 @@ class SmsSms(models.Model):
if auto_commit is True and not getattr(threading.currentThread(), 'testing', False):
self._cr.commit()
+ def cancel(self):
+ self.state = 'canceled'
+
@api.model
def _process_queue(self, ids=None):
""" Send immediately queued messages, committing after each message is sent.
diff --git a/addons/sms/models/sms_template.py b/addons/sms/models/sms_template.py
index 5439c9cbb22..e1ba74d3bb1 100644
--- a/addons/sms/models/sms_template.py
+++ b/addons/sms/models/sms_template.py
@@ -23,7 +23,13 @@ class SMSTemplate(models.Model):
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)
- lang = fields.Char('Language', placeholder="${object.partner_id.lang}")
+ lang = fields.Char('Language', help="Use this field to either force a specific language (ISO code) or dynamically "
+ "detect the language of your recipient by a placeholder expression "
+ "(e.g. ${object.partner_id.lang})")
+ # Use to create contextual action (same as for email template)
+ sidebar_action_id = fields.Many2one('ir.actions.act_window', 'Sidebar action', readonly=True, copy=False,
+ help="Sidebar action to make this template available on records "
+ "of the related document model")
# Fake fields used to implement the placeholder assistant
model_object_field = fields.Many2one('ir.model.fields', string="Field", store=False,
help="Select target field from the related document model.\n"
@@ -86,6 +92,32 @@ class SMSTemplate(models.Model):
name=_("%s (copy)") % self.name)
return super(SMSTemplate, self).copy(default=default)
+ def action_create_sidebar_action(self):
+ ActWindow = self.env['ir.actions.act_window']
+ view = self.env.ref('sms.sms_composer_view_form')
+
+ for template in self:
+ button_name = _('Send SMS (%s)') % template.name
+ action = ActWindow.create({
+ 'name': button_name,
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'sms.composer',
+ # Add default_composition_mode to guess to determine if need to use mass or comment composer
+ 'context': "{'default_template_id' : %d, 'default_composition_mode': 'guess', 'default_res_ids': active_ids, 'default_res_id': active_id}" % (template.id),
+ 'view_mode': 'form',
+ 'view_id': view.id,
+ 'target': 'new',
+ 'binding_model_id': template.model_id.id,
+ })
+ template.write({'sidebar_action_id': action.id})
+ return True
+
+ def action_unlink_sidebar_action(self):
+ for template in self:
+ if template.sidebar_action_id:
+ template.sidebar_action_id.unlink()
+ return True
+
def _get_context_lang_per_id(self, res_ids):
self.ensure_one()
if res_ids is None:
@@ -96,8 +128,7 @@ class SMSTemplate(models.Model):
results = dict((res_id, self.with_context(lang=lang)) for res_id in res_ids)
else:
rendered_langs = self._render_template(self.lang, self.model, res_ids)
- results = dict(
- (res_id, self.with_context(lang=lang) if lang else self)
+ results = dict((res_id, self.with_context(lang=lang) if lang else self)
for res_id, lang in rendered_langs.items())
return results
@@ -112,6 +143,16 @@ class SMSTemplate(models.Model):
return tpl_to_rids
+ def _get_translated_bodies(self, res_ids):
+ """ return sms translated bodies into a dict {'res_id':'body'} """
+ self.ensure_one()
+ lang_to_rids = self._get_ids_per_lang(res_ids)
+ all_bodies = {}
+ for lang, rids in lang_to_rids.items():
+ template = self.with_context(lang=lang)
+ all_bodies.update(template._render_template(template.body, self.model, rids))
+ return all_bodies
+
@api.model
def _render_template(self, template_txt, model, res_ids):
""" Render the jinja template """
diff --git a/addons/sms/views/res_partner_views.xml b/addons/sms/views/res_partner_views.xml
index c696531fc3b..91c6b77c9b2 100644
--- a/addons/sms/views/res_partner_views.xml
+++ b/addons/sms/views/res_partner_views.xml
@@ -9,7 +9,7 @@
10
-
+
@@ -27,7 +27,7 @@
-
-