diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/mass_mailing_sms/wizard | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/mass_mailing_sms/wizard')
| -rw-r--r-- | addons/mass_mailing_sms/wizard/__init__.py | 5 | ||||
| -rw-r--r-- | addons/mass_mailing_sms/wizard/mailing_sms_test.py | 39 | ||||
| -rw-r--r-- | addons/mass_mailing_sms/wizard/mailing_sms_test_views.xml | 29 | ||||
| -rw-r--r-- | addons/mass_mailing_sms/wizard/sms_composer.py | 96 | ||||
| -rw-r--r-- | addons/mass_mailing_sms/wizard/sms_composer_views.xml | 16 |
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> |
