summaryrefslogtreecommitdiff
path: root/addons/mass_mailing_sms/wizard
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/mass_mailing_sms/wizard
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/mass_mailing_sms/wizard')
-rw-r--r--addons/mass_mailing_sms/wizard/__init__.py5
-rw-r--r--addons/mass_mailing_sms/wizard/mailing_sms_test.py39
-rw-r--r--addons/mass_mailing_sms/wizard/mailing_sms_test_views.xml29
-rw-r--r--addons/mass_mailing_sms/wizard/sms_composer.py96
-rw-r--r--addons/mass_mailing_sms/wizard/sms_composer_views.xml16
5 files changed, 185 insertions, 0 deletions
diff --git a/addons/mass_mailing_sms/wizard/__init__.py b/addons/mass_mailing_sms/wizard/__init__.py
new file mode 100644
index 00000000..eecb3976
--- /dev/null
+++ b/addons/mass_mailing_sms/wizard/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import mailing_sms_test
+from . import sms_composer
diff --git a/addons/mass_mailing_sms/wizard/mailing_sms_test.py b/addons/mass_mailing_sms/wizard/mailing_sms_test.py
new file mode 100644
index 00000000..1ea9f871
--- /dev/null
+++ b/addons/mass_mailing_sms/wizard/mailing_sms_test.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, exceptions, fields, models, _
+from odoo.addons.phone_validation.tools import phone_validation
+
+
+class MassSMSTest(models.TransientModel):
+ _name = 'mailing.sms.test'
+ _description = 'Test SMS Mailing'
+
+ def _default_numbers(self):
+ return self.env.user.partner_id.phone_sanitized or ""
+
+ numbers = fields.Char(string='Number(s)', required=True,
+ default=_default_numbers, help='Comma-separated list of phone numbers')
+ mailing_id = fields.Many2one('mailing.mailing', string='Mailing', required=True, ondelete='cascade')
+
+ def action_send_sms(self):
+ self.ensure_one()
+ numbers = [number.strip() for number in self.numbers.split(',')]
+ sanitize_res = phone_validation.phone_sanitize_numbers_w_record(numbers, self.env.user)
+ sanitized_numbers = [info['sanitized'] for info in sanitize_res.values() if info['sanitized']]
+ invalid_numbers = [number for number, info in sanitize_res.items() if info['code']]
+ if invalid_numbers:
+ raise exceptions.UserError(_('Following numbers are not correctly encoded: %s, example : "+32 495 85 85 77, +33 545 55 55 55"', repr(invalid_numbers)))
+
+ record = self.env[self.mailing_id.mailing_model_real].search([], limit=1)
+ body = self.mailing_id.body_plaintext
+ if record:
+ # Returns a proper error if there is a syntax error with jinja
+ body = self.env['mail.render.mixin']._render_template(body, self.mailing_id.mailing_model_real, record.ids)[record.id]
+
+ self.env['sms.api']._send_sms_batch([{
+ 'res_id': 0,
+ 'number': number,
+ 'content': body,
+ } for number in sanitized_numbers])
+ return True
diff --git a/addons/mass_mailing_sms/wizard/mailing_sms_test_views.xml b/addons/mass_mailing_sms/wizard/mailing_sms_test_views.xml
new file mode 100644
index 00000000..09656dd1
--- /dev/null
+++ b/addons/mass_mailing_sms/wizard/mailing_sms_test_views.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<odoo>
+ <record id="mailing_sms_test_view_form" model="ir.ui.view">
+ <field name="name">mailing.sms.test.view.form</field>
+ <field name="model">mailing.sms.test</field>
+ <field name="arch" type="xml">
+ <form string="Send a Sample SMS">
+ <p class="text-muted">
+ Send a sample SMS for testing purpose to the numbers below (comma-separated list).
+ </p>
+ <group>
+ <field name="numbers" placeholder="+32 495 85 85 77, +33 545 55 55 55"/>
+ <field name="mailing_id" invisible="1"/>
+ </group>
+ <footer>
+ <button string="Send" name="action_send_sms" type="object" class="btn-primary"/>
+ <button string="Cancel" class="btn btn-secondary" special="cancel"/>
+ </footer>
+ </form>
+ </field>
+ </record>
+
+ <record id="mailing_sms_test_action" model="ir.actions.act_window">
+ <field name="name">Test SMS Marketing</field>
+ <field name="res_model">mailing.sms.test</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ </record>
+</odoo>
diff --git a/addons/mass_mailing_sms/wizard/sms_composer.py b/addons/mass_mailing_sms/wizard/sms_composer.py
new file mode 100644
index 00000000..b8d13b7f
--- /dev/null
+++ b/addons/mass_mailing_sms/wizard/sms_composer.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import werkzeug.urls
+
+from odoo import fields, models, _
+
+
+class SMSComposer(models.TransientModel):
+ _inherit = 'sms.composer'
+
+ # mass mode with mass sms
+ mass_sms_allow_unsubscribe = fields.Boolean('Include opt-out link', default=True)
+ mailing_id = fields.Many2one('mailing.mailing', string='Mailing')
+ utm_campaign_id = fields.Many2one('utm.campaign', string='Campaign')
+
+ # ------------------------------------------------------------
+ # Mass mode specific
+ # ------------------------------------------------------------
+
+ def _get_unsubscribe_url(self, res_id, trace_code, number):
+ base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
+ return werkzeug.urls.url_join(
+ base_url,
+ '/sms/%s/%s' % (self.mailing_id.id, trace_code)
+ )
+
+ def _prepare_mass_sms_trace_values(self, record, sms_values):
+ trace_code = self.env['mailing.trace']._get_random_code()
+ trace_values = {
+ 'model': self.res_model,
+ 'res_id': record.id,
+ 'trace_type': 'sms',
+ 'mass_mailing_id': self.mailing_id.id,
+ 'sms_number': sms_values['number'],
+ 'sms_code': trace_code,
+ }
+ if sms_values['state'] == 'error':
+ if sms_values['error_code'] == 'sms_number_format':
+ trace_values['sent'] = fields.Datetime.now()
+ trace_values['bounced'] = fields.Datetime.now()
+ else:
+ trace_values['exception'] = fields.Datetime.now()
+ elif sms_values['state'] == 'canceled':
+ trace_values['ignored'] = fields.Datetime.now()
+ else:
+ if self.mass_sms_allow_unsubscribe:
+ sms_values['body'] = '%s\n%s' % (sms_values['body'] or '', _('STOP SMS : %s', self._get_unsubscribe_url(record.id, trace_code, sms_values['number'])))
+ return trace_values
+
+ def _get_blacklist_record_ids(self, records, recipients_info):
+ """ Consider opt-outed contact as being blacklisted for that specific
+ mailing. """
+ res = super(SMSComposer, self)._get_blacklist_record_ids(records, recipients_info)
+ if self.mailing_id:
+ optout_res_ids = self.mailing_id._get_opt_out_list_sms()
+ res += optout_res_ids
+ return res
+
+ def _get_done_record_ids(self, records, recipients_info):
+ """ A/B testing could lead to records having been already mailed. """
+ res = super(SMSComposer, self)._get_done_record_ids(records, recipients_info)
+ if self.mailing_id:
+ seen_ids, seen_list = self.mailing_id._get_seen_list_sms()
+ res += seen_ids
+ return res
+
+ def _prepare_body_values(self, records):
+ all_bodies = super(SMSComposer, self)._prepare_body_values(records)
+ if self.mailing_id:
+ tracker_values = self.mailing_id._get_link_tracker_values()
+ for sms_id, body in all_bodies.items():
+ body = self.env['mail.render.mixin'].sudo()._shorten_links_text(body, tracker_values)
+ all_bodies[sms_id] = body
+ return all_bodies
+
+ def _prepare_mass_sms_values(self, records):
+ result = super(SMSComposer, self)._prepare_mass_sms_values(records)
+ if self.composition_mode == 'mass' and self.mailing_id:
+ for record in records:
+ sms_values = result[record.id]
+
+ trace_values = self._prepare_mass_sms_trace_values(record, sms_values)
+ sms_values.update({
+ 'mailing_id': self.mailing_id.id,
+ 'mailing_trace_ids': [(0, 0, trace_values)],
+ })
+ return result
+
+ def _prepare_mass_sms(self, records, sms_record_values):
+ sms_all = super(SMSComposer, self)._prepare_mass_sms(records, sms_record_values)
+ if self.mailing_id:
+ updated_bodies = sms_all._update_body_short_links()
+ for sms in sms_all:
+ sms.body = updated_bodies[sms.id]
+ return sms_all
diff --git a/addons/mass_mailing_sms/wizard/sms_composer_views.xml b/addons/mass_mailing_sms/wizard/sms_composer_views.xml
new file mode 100644
index 00000000..139338c7
--- /dev/null
+++ b/addons/mass_mailing_sms/wizard/sms_composer_views.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="sms_composer_view_form" model="ir.ui.view">
+ <field name="name">sms.composer.views.inherit.sms</field>
+ <field name="model">sms.composer</field>
+ <field name="inherit_id" ref="sms.sms_composer_view_form"/>
+ <field name="arch" type="xml">
+ <xpath expr="//field[@name='res_model']" position="after">
+ <field name="utm_campaign_id" groups="mass_mailing.group_mass_mailing_campaign"
+ invisible="1"/>
+ <field name="mailing_id" invisible="1"/>
+ </xpath>
+ </field>
+ </record>
+
+</odoo>