summaryrefslogtreecommitdiff
path: root/addons/mass_mailing_sms/views
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2019-07-30 12:06:41 +0000
committerThibault Delavallée <tde@odoo.com>2019-08-12 12:00:22 +0000
commit14648272dadfbc9e2c7069de76770d5c052cd37f (patch)
tree7a8e4a3d7b6f44b4c66a626e4fe52ce596ed28e7 /addons/mass_mailing_sms/views
parentc7a14e9109ff81611b77b91ae1910a2f2e9b576e (diff)
[ADD] mass_mailing_sms: support SMS in mass mailing
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 Create a new application called "Mass SMS" that follows the structure of mass_mailing application. General guidelines * use the fa-comment icon for this module; * add a "Notification type" field to the mailings: email or sms. Set it invisible and set as domain from context when choosing mass mailing or mass sms application (menus / action specific); * adapt the metrics from Mass Mailing to SMS * sent = received = whether the SMS was sent or not; * opened => we don't have this information; * replied => we don't have this information; * clicks = from link tracker (no change of behavior); * bounced = SMS that failed to be delivered because the format is wrong; * exception = any issue when sending SMS; * keep the Mailing Lists menu, hide email related fields on contact model; * settings: hide the "Specific Mail Server" feature Mailing form view * add an "SMS Content" tab between Mail Body and Options. In there, we should have the following fields: * content * opt-out link: provide a link to the Unsubscribe page. Make it as short as possible; * SMS Template * add an "SMS Text Message" Medium; Mailing actions * add an "SMS Sent" smart button. Use the fa-comment-o icon and it should redirect to the same list views as the "Email sent" smart button and list the contacts to which an SMS was sent; * add a "Mobile" field in the list views of the "Email sent" smart button: * adapt the TEST button > Test Mailing modal to SMS (we should have 1 button for Email and 1 for SMS); update description; * default value for the Recipients field should be Name of the current user, work mobile/phone number; * If there are no Work Mobile/Phone numbers set on res.users, display (123)-456-7890 instead; * rename the Send Sample Mail button into Send Sample SMS; * adapt the SEND NOW button > Confirmation modal to SMS. Change the message into "This will send the SMS Text Message to all recipients. Do you still want to proceed?" * hide the following elements: Subject, From, Reply to, Attachments, Mail Server, Mail Body tab; Opened, Replied; * adapt the label of the following "warnings" to SMS * x SMS Text Message(s) have been ignored and will not be sent. * x SMS Text Message(s) are in queue and will be sent soon. * x SMS Text Message(s) could not be sent. Mailing kanban view * hide the following stats: https://nimb.ws/grvBn0: Opened, Replied; Mailing list / contact management * following fields should be left empty: https://nimb.ws/3HBeJL: Opened, Replied; * when browsing through mailing lsits and contacts through the Mass SMS application, update actions and views to hide fields related to email and display only phone-related information; UTM Campaign * form view > Related Mailings tab: the following fields should be left empty if notification type = SMS: https://nimb.ws/nfvr1O: Opened, Replied Mass Mailing > Reporting (mail.trace.report model) * adapt the reporting based on the fact that we do not have the following metrics for SMS: Opened, Replied; Mass Mailing > Configuration > Blacklist * do not display any email information (phone blacklist is about phone); * support phone blacklist. Phone blacklist is therefore a separate model from mail.blacklist to simplify management. It is included in sms sending process like mail blacklist when mailing in mass; Opt-out and blacklist handling * we do support mailing lists because they could come from different sources and are a way to communicate with a specific audience (and not just a list we bought), e.g. subscribe to this list to be kept updated whenever this product is back in stock, or to receive results of this ... * if the SMSing is from a list, opt-out removes ourselves from the list; * if it is from the contact ==> Sent to blacklist; * allow to attach unsubscription links in sent SMS, redirecting to a new route in mass mailing SMS allowing quick unsubscribe and/or blacklist of phone numbers; Error management * if the user clicks on Send Now / Schedule / Test and does not have enough credits, open the "Insufficient credits" modal in a lazy option (aka when having failed statistics linked to insufficient credits); * on the mailing, we however display this failure as : * a message on the mailing kanban view * a message on the top of the form view + same behavior as the mailing and "Could not be sent" https://www.screencast.com/t/BExgd1Gc; LINKS Task 1997464 PR #34424 Original SMS addition: Task 1922163 (4287481)
Diffstat (limited to 'addons/mass_mailing_sms/views')
-rw-r--r--addons/mass_mailing_sms/views/link_tracker_views.xml8
-rw-r--r--addons/mass_mailing_sms/views/mailing_contact_views.xml96
-rw-r--r--addons/mass_mailing_sms/views/mailing_list_views.xml22
-rw-r--r--addons/mass_mailing_sms/views/mailing_mailing_views.xml183
-rw-r--r--addons/mass_mailing_sms/views/mailing_sms_menus.xml63
-rw-r--r--addons/mass_mailing_sms/views/mailing_trace_views.xml121
-rw-r--r--addons/mass_mailing_sms/views/mass_mailing_sms_templates_portal.xml60
7 files changed, 553 insertions, 0 deletions
diff --git a/addons/mass_mailing_sms/views/link_tracker_views.xml b/addons/mass_mailing_sms/views/link_tracker_views.xml
new file mode 100644
index 00000000000..30ab3459e02
--- /dev/null
+++ b/addons/mass_mailing_sms/views/link_tracker_views.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <menuitem id="link_tracker_menu"
+ name="Link Tracker"
+ parent="mass_mailing_sms_menu_configuration"
+ sequence="2"
+ action="link_tracker.link_tracker_action"/>
+</odoo>
diff --git a/addons/mass_mailing_sms/views/mailing_contact_views.xml b/addons/mass_mailing_sms/views/mailing_contact_views.xml
new file mode 100644
index 00000000000..374191ec91f
--- /dev/null
+++ b/addons/mass_mailing_sms/views/mailing_contact_views.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="mailing_contact_view_search" model="ir.ui.view">
+ <field name="name">mailing.contact.view.search.inherit.sms</field>
+ <field name="model">mailing.contact</field>
+ <field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_search"/>
+ <field name="arch" type="xml">
+ <xpath expr="//field[@name='name']" position="after">
+ <field name="phone_sanitized"/>
+ </xpath>
+ <xpath expr="//filter[@name='filter_not_optout']" position="after">
+ <separator/>
+ <filter string="Valid SMS Recipients"
+ name="filter_valid_sms_recipient"
+ domain="[('opt_out', '=', False), ('phone_blacklisted', '=', False), ('phone_sanitized', '!=', False)]"
+ invisible="not context.get('default_list_ids')"/>
+ <separator/>
+ <filter string="Exclude Blacklisted Phone"
+ name="filter_not_phone_bl"
+ domain="[('phone_blacklisted', '=', False)]"/>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="mailing_contact_view_tree_sms" model="ir.ui.view">
+ <field name="name">mailing.contact.view.tree.sms</field>
+ <field name="model">mailing.contact</field>
+ <field name="priority">20</field>
+ <field name="arch" type="xml">
+ <tree string="Contacts">
+ <field name="create_date"/>
+ <field name="name"/>
+ <field name="company_name"/>
+ <field name="phone_sanitized"/>
+ <field name="phone_blacklisted"/>
+ <field name="opt_out" invisible="'default_list_ids' not in context"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="mailing_contact_view_form" model="ir.ui.view">
+ <field name="name">mailing.contact.view.form.inherit.sms</field>
+ <field name="model">mailing.contact</field>
+ <field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_form"/>
+ <field name="arch" type="xml">
+ <xpath expr="//label[@for='email']" position="attributes">
+ <attribute name="invisible">context.get('mailing_sms') == True</attribute>
+ </xpath>
+ <xpath expr="//div[@name='email_details']" position="attributes">
+ <attribute name="invisible">context.get('mailing_sms') == True</attribute>
+ </xpath>
+ <xpath expr="//div[@name='email_details']" position="after">
+ <label for="phone_sanitized" class="oe_inline"/>
+ <div class="o_row o_row_readonly" name="phone_details">
+ <i class="fa fa-ban" style="color: red;" role="img" title="This number is blacklisted for mass SMS"
+ aria-label="Phone Blacklisted" attrs="{'invisible': [('phone_blacklisted', '=', False)]}" groups="base.group_user"></i>
+ <field name="phone_sanitized" widget="phone"/>
+ <field name="phone_blacklisted" invisible="1"/>
+ </div>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="mailing_contact_view_kanban" model="ir.ui.view">
+ <field name="name">mailing.contact.view.kanban.inherit.sms</field>
+ <field name="model">mailing.contact</field>
+ <field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_kanban"/>
+ <field name="arch" type="xml">
+ <xpath expr="//field[@name='email']" position="after">
+ <field name="phone_sanitized"/>
+ </xpath>
+ <xpath expr="//t[@t-esc='record.email.value']" position="after">
+ <t t-esc="record.phone_sanitized.value"/>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="mailing_contact_action_sms" model="ir.actions.act_window">
+ <field name="name">Contacts</field>
+ <field name="res_model">mailing.contact</field>
+ <field name="view_mode">tree,form</field>
+ <field name="context">{'mailing_sms': True, 'search_default_filter_not_phone_bl': 1, }</field>
+ <field name="view_id" ref="mailing_contact_view_tree_sms"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Create a new contact
+ </p>
+ </field>
+ </record>
+
+ <!-- Mass SMS / Contacts Lists / Contacts Lists -->
+ <record id="mass_mailing_sms.mailing_contact_menu_sms" model="ir.ui.menu">
+ <field name="action" ref="mailing_contact_action_sms"/>
+ </record>
+
+</odoo>
diff --git a/addons/mass_mailing_sms/views/mailing_list_views.xml b/addons/mass_mailing_sms/views/mailing_list_views.xml
new file mode 100644
index 00000000000..d1b88669078
--- /dev/null
+++ b/addons/mass_mailing_sms/views/mailing_list_views.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="mailing_list_action_sms" model="ir.actions.act_window">
+ <field name="name">Contact Lists</field>
+ <field name="res_model">mailing.list</field>
+ <field name="view_mode">kanban,tree,form</field>
+ <field name="context">{'mailing_sms': True}</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Create a new contacts list
+ </p><p>
+ You don't need to import your contacts lists, you can easily
+ send SMS to any contact saved in other Odoo apps.
+ </p>
+ </field>
+ </record>
+
+ <!-- Mass SMS / Contacts Lists / Contacts Lists -->
+ <record id="mass_mailing_sms.mailing_list_menu_sms" model="ir.ui.menu">
+ <field name="action" ref="mailing_list_action_sms"/>
+ </record>
+</odoo>
diff --git a/addons/mass_mailing_sms/views/mailing_mailing_views.xml b/addons/mass_mailing_sms/views/mailing_mailing_views.xml
new file mode 100644
index 00000000000..d4517cf0b1f
--- /dev/null
+++ b/addons/mass_mailing_sms/views/mailing_mailing_views.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo><data>
+ <record id="mailing_mailing_view_form" model="ir.ui.view">
+ <field name="name">mailing.mailing.view.form.inherit.sms</field>
+ <field name="model">mailing.mailing</field>
+ <field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_form"/>
+ <field name="arch" type="xml">
+ <!-- Buttons / Actions -->
+ <xpath expr="//button[@name='action_put_in_queue']" position="attributes">
+ <attribute name="attrs">{'invisible': ['|', ('state', 'in', ('in_queue', 'done')), ('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//button[@name='action_put_in_queue']" position="after">
+ <button name="action_put_in_queue" type="object"
+ class="oe_highlight" string="Send Now"
+ attrs="{'invisible': ['|', ('mailing_type', '=', 'mail'), ('state', 'in', ('in_queue', 'done'))]}"
+ confirm="This will send SMS to all recipients. Do you still want to proceed ?"/>
+ </xpath>
+ <!-- Headers / Warnings -->
+ <xpath expr="//header" position="after">
+ <field name="sms_has_insufficient_credit" invisible="1"/>
+ <div class="alert alert-warning text-center" attrs="{'invisible': [('sms_has_insufficient_credit', '=', False)]}" role="alert">
+ <p>
+ <button class="btn-link"
+ name="action_buy_sms_credits"
+ type="object">
+ <strong>
+ It appears you don't have enough IAP credits. Click here to buy credits.
+ </strong>
+ </button>
+ </p>
+ </div>
+ </xpath>
+ <xpath expr="//span[@name='ignored_text']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//span[@name='ignored_text']" position="after">
+ <span name="ignored_text_sms" attrs="{'invisible': [('mailing_type', '!=', 'sms')]}">SMS Text Message have been ignored and will not be sent.</span>
+ </xpath>
+ <xpath expr="//span[@name='scheduled_text']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//span[@name='scheduled_text']" position="after">
+ <span name="scheduled_text_sms" attrs="{'invisible': [('mailing_type', '!=', 'sms')]}">SMS Text Message are in queue and will be sent soon.</span>
+ </xpath>
+ <xpath expr="//span[@name='failed_text']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//span[@name='failed_text']" position="after">
+ <span name="failed_text_sms" attrs="{'invisible': [('mailing_type', '!=', 'sms')]}">SMS Text Message could not be sent.</span>
+ </xpath>
+ <!-- Stat Buttons -->
+ <xpath expr="//button[@id='button_view_sent']" position="attributes">
+ <attribute name="attrs">{'invisible': ['|', '&amp;', ('sent', '=', 0), ('state', 'in', ('draft', 'test')), ('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//button[@id='button_view_sent']" position="after">
+ <button name="action_view_sent"
+ type="object"
+ context="{'search_default_filter_sent': True}"
+ icon="fa-comment-o" class="oe_stat_button"
+ attrs="{'invisible': ['|', '&amp;', ('sent', '=', 0), ('state', 'in', ('draft', 'test')), ('mailing_type', '!=', 'sms')]}" >
+ <field name="sent" string="Sent" widget="statinfo"/>
+ </button>
+ </xpath>
+ <xpath expr="//button[@name='action_view_opened']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//button[@name='action_view_replied']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <!-- Form -->
+ <xpath expr="//field[@name='subject']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//page[@name='mail_body']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//page[@name='mail_body']" position="after">
+ <page string="SMS Content" name="sms_body" attrs="{'invisible': [('mailing_type', '!=', 'sms')]}">
+ <field name="body_plaintext" widget="sms_widget"/>
+ <group>
+ <field name="sms_template_id" domain="[('model', '=', mailing_model_real)]"/>
+ <field name="sms_allow_unsubscribe"/>
+ </group>
+ </page>
+ </xpath>
+ <!-- Option page tweaks -->
+ <xpath expr="//field[@name='email_from']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//label[@for='reply_to']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//div[@name='reply_to_details']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//label[@for='attachment_ids']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//div[@name='attachment_ids_details']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//field[@name='mail_server_id']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="mailing_mailing_view_kanban" model="ir.ui.view">
+ <field name="name">mailing.mailing.view.kanban.inherit.sms</field>
+ <field name="model">mailing.mailing</field>
+ <field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_kanban"/>
+ <field name="arch" type="xml">
+ <xpath expr="//field[@name='active']" position="after">
+ <field name="sms_has_insufficient_credit"/>
+ </xpath>
+ <xpath expr="//h3" position="after">
+ <div class="alert alert-warning" role="alert" attrs="{'invisible': [('sms_has_insufficient_credit', '=', False)]}">
+ <a name="action_buy_sms_credits"
+ type="object">Insufficient credits</a>
+ </div>
+ </xpath>
+ <xpath expr="//div[@name='stat_opened']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//div[@name='stat_replied']" position="attributes">
+ <attribute name="attrs">{'invisible': [('mailing_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="mailing_mailing_view_tree_sms" model="ir.ui.view">
+ <field name="name">mailing.mailing.view.tree.sms</field>
+ <field name="model">mailing.mailing</field>
+ <field name="priority">20</field>
+ <field name="arch" type="xml">
+ <tree string="Mass SMS">
+ <field name="name"/>
+ <field name="mailing_type" invisible="1"/>
+ <field name="sent"/>
+ <field name="clicked"/>
+ <field name="bounced"/>
+ <field name="campaign_id" groups="mass_mailing.group_mass_mailing_campaign"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="mailing_mailing_action_sms" model="ir.actions.act_window">
+ <field name="name">Mass SMS</field>
+ <field name="res_model">mailing.mailing</field>
+ <field name="view_mode">kanban,tree,form,graph</field>
+ <field name="domain">[('mailing_type', '=', 'sms')]</field>
+ <field name="context">{
+ 'search_default_assigned_to_me': 1,
+ 'default_user_id': uid,
+ 'default_mailing_type': 'sms',
+ }</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Create a new mass SMS
+ </p><p>
+ You can easily send SMS to any contact saved in other Odoo apps.
+ </p>
+ </field>
+ </record>
+ <record id="mailing_mailing_action_sms_view_kanban" model="ir.actions.act_window.view">
+ <field name="sequence">1</field>
+ <field name="view_mode">kanban</field>
+ <field name="view_id" ref="mass_mailing.view_mail_mass_mailing_kanban"/>
+ <field name="act_window_id" ref="mailing_mailing_action_sms"/>
+ </record>
+ <record id="mailing_mailing_action_sms_view_tree" model="ir.actions.act_window.view">
+ <field name="sequence">2</field>
+ <field name="view_mode">tree</field>
+ <field name="view_id" ref="mailing_mailing_view_tree_sms"/>
+ <field name="act_window_id" ref="mailing_mailing_action_sms"/>
+ </record>
+
+ <!-- Mass SMS / Mass SMS -->
+ <record id="mass_mailing_sms_menu_mass_sms" model="ir.ui.menu">
+ <field name="action" ref="mailing_mailing_action_sms"/>
+ </record>
+
+</data></odoo>
diff --git a/addons/mass_mailing_sms/views/mailing_sms_menus.xml b/addons/mass_mailing_sms/views/mailing_sms_menus.xml
new file mode 100644
index 00000000000..f7cc0f05edb
--- /dev/null
+++ b/addons/mass_mailing_sms/views/mailing_sms_menus.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <!-- Mass SMS -->
+ <menuitem id="mass_mailing_sms_menu_root"
+ name="Mass SMS"
+ sequence="60"
+ web_icon="mass_mailing_sms,static/description/icon.png"
+ groups="mass_mailing.group_mass_mailing_user"/>
+
+ <!-- Mass SMS / Mass SMS -->
+ <menuitem id="mass_mailing_sms_menu_mass_sms"
+ name="Mass SMS"
+ parent="mass_mailing_sms_menu_root"
+ sequence="1"
+ groups="mass_mailing.group_mass_mailing_user"/>
+
+ <!-- Mass SMS / Contacts Lists -->
+ <menuitem id="mass_mailing_sms_menu_contacts"
+ name="Contacts Lists"
+ parent="mass_mailing_sms_menu_root"
+ sequence="2"
+ groups="mass_mailing.group_mass_mailing_user"/>
+ <!-- Mass SMS / Contacts Lists / Contacts Lists -->
+ <menuitem id="mailing_list_menu_sms"
+ name="Contacts Lists"
+ parent="mass_mailing_sms_menu_contacts"
+ sequence="1"
+ groups="mass_mailing.group_mass_mailing_user"/>
+ <!-- Mass SMS / Contacts Lists / Contacts -->
+ <menuitem id="mailing_contact_menu_sms"
+ name="Contacts"
+ parent="mass_mailing_sms_menu_contacts"
+ sequence="2"
+ groups="mass_mailing.group_mass_mailing_user"/>
+
+ <!-- Mass SMS / Reporting -->
+ <menuitem id="mass_mailing_sms_menu_reporting"
+ name="Reporting"
+ parent="mass_mailing_sms_menu_root"
+ sequence="80"
+ groups="mass_mailing.group_mass_mailing_user"/>
+
+ <!-- Mass SMS / Configuration -->
+ <menuitem id="mass_mailing_sms_menu_configuration"
+ name="Configuration"
+ parent="mass_mailing_sms_menu_root"
+ sequence="100"
+ groups="mass_mailing.group_mass_mailing_user"/>
+ <!-- Mass SMS / Configuration / Blacklist -->
+ <menuitem id="phone_blacklist_menu"
+ name="Phone Blacklist"
+ parent="mass_mailing_sms_menu_configuration"
+ sequence="1"
+ action="phone_validation.phone_blacklist_action"
+ groups="mass_mailing.group_mass_mailing_user"/>
+ <!-- Mass SMS / Configuration / Link Tracker -->
+ <menuitem id="link_tracker_menu"
+ name="Link Tracker Blacklist"
+ parent="mass_mailing_sms_menu_configuration"
+ sequence="2"
+ action="link_tracker.link_tracker_action"
+ groups="mass_mailing.group_mass_mailing_user"/>
+</odoo> \ No newline at end of file
diff --git a/addons/mass_mailing_sms/views/mailing_trace_views.xml b/addons/mass_mailing_sms/views/mailing_trace_views.xml
new file mode 100644
index 00000000000..d109c86b8b4
--- /dev/null
+++ b/addons/mass_mailing_sms/views/mailing_trace_views.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="mailing_trace_view_search" model="ir.ui.view">
+ <field name="name">mailing.trace.view.search.inherit.sms</field>
+ <field name="model">mailing.trace</field>
+ <field name="inherit_id" ref="mass_mailing.mailing_trace_view_search"/>
+ <field name="arch" type="xml">
+ <xpath expr="//field[@name='email']" position="after">
+ <field name="sms_sms_id_int"/>
+ <field name="sms_sms_id"/>
+ <field name="sms_number"/>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="mailing_trace_view_tree" model="ir.ui.view">
+ <field name="name">mailing.trace.view.tree.inherit.sms</field>
+ <field name="model">mailing.trace</field>
+ <field name="inherit_id" ref="mass_mailing.mailing_trace_view_tree"/>
+ <field name="arch" type="xml">
+ <xpath expr="//field[@name='email']" position="before">
+ <field name="trace_type"/>
+ </xpath>
+ <xpath expr="//field[@name='email']" position="after">
+ <field name="sms_number"/>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="mailing_trace_view_tree_sms" model="ir.ui.view">
+ <field name="name">mailing.trace.view.tree.sms</field>
+ <field name="model">mailing.trace</field>
+ <field name="priority">20</field>
+ <field name="arch" type="xml">
+ <tree string="SMS Traces" create="0">
+ <field name="sms_number"/>
+ <field name="state"/>
+ <field name="scheduled"/>
+ <field name="sent"/>
+ <field name="clicked"/>
+ <field name="bounced"/>
+ <field name="exception"/>
+ <field name="ignored"/>
+ <field name="failure_type"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="mailing_trace_view_form" model="ir.ui.view">
+ <field name="name">mailing.trace.view.form.inherit.sms</field>
+ <field name="model">mailing.trace</field>
+ <field name="inherit_id" ref="mass_mailing.mailing_trace_view_form"/>
+ <field name="arch" type="xml">
+ <xpath expr="//span[@name='trace_type_name_mail']" position="attributes">
+ <attribute name="attrs">{'invisible': [('trace_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//span[@name='trace_type_name_mail']" position="after">
+ <span name="trace_type_name_sms" attrs="{'invisible': [('trace_type', '!=', 'sms')]}">This sms</span>
+ </xpath>
+ <xpath expr="//field[@name='email']" position="attributes">
+ <attribute name="attrs">{'invisible': [('trace_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//field[@name='mail_mail_id_int']" position="attributes">
+ <attribute name="attrs">{'invisible': [('trace_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//field[@name='message_id']" position="attributes">
+ <attribute name="attrs">{'invisible': [('trace_type', '!=', 'mail')]}</attribute>
+ </xpath>
+ <xpath expr="//field[@name='opened']" position="attributes">
+ <attribute name="attrs">{'invisible': [('trace_type', '=', 'sms')]}</attribute>
+ </xpath>
+ <xpath expr="//field[@name='replied']" position="attributes">
+ <attribute name="attrs">{'invisible': [('trace_type', '=', 'sms')]}</attribute>
+ </xpath>
+ <xpath expr="//field[@name='email']" position="after">
+ <field name="sms_number" attrs="{'invisible': [('trace_type', '!=', 'sms')]}"/>
+ <field name="sms_sms_id_int" attrs="{'invisible': [('trace_type', '!=', 'sms')]}"/>
+ <field name="sms_code" attrs="{'invisible': [('trace_type', '!=', 'sms')]}"/>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="mailing_trace_view_form_sms" model="ir.ui.view">
+ <field name="name">mailing.trace.view.form.sms</field>
+ <field name="model">mailing.trace</field>
+ <field name="priority">20</field>
+ <field name="arch" type="xml">
+ <form string="SMS Trace" create="0">
+ <header>
+ <field name="state" widget="statusbar"/>
+ </header>
+ <sheet>
+ <div class="alert alert-info text-center" attrs="{'invisible': [('exception', '=', False)]}" role="alert">
+ <strong>This SMS could not be sent.</strong>
+ </div>
+ <div class="alert alert-info text-center" attrs="{'invisible': [('bounced', '=', False)]}" role="alert">
+ <strong>This number appears to be invalid.</strong>
+ </div>
+ <group>
+ <group>
+ <field name="sms_number"/>
+ <field name="mass_mailing_id"/>
+ <field name="campaign_id" groups="mass_mailing.group_mass_mailing_campaign"/>
+ <field name="sms_sms_id_int" groups="base.group_no_one"/>
+ <field name="model" groups="base.group_no_one"/>
+ <field name="res_id" groups="base.group_no_one"/>
+ </group>
+ <group>
+ <field name="scheduled"/>
+ <field name="sent"/>
+ <field name="clicked"/>
+ <field name="bounced"/>
+ <field name="exception"/>
+ <field name="ignored"/>
+ </group>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+</odoo>
diff --git a/addons/mass_mailing_sms/views/mass_mailing_sms_templates_portal.xml b/addons/mass_mailing_sms/views/mass_mailing_sms_templates_portal.xml
new file mode 100644
index 00000000000..bd1f927eb9d
--- /dev/null
+++ b/addons/mass_mailing_sms/views/mass_mailing_sms_templates_portal.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <template id="blacklist_main" name="Unsubscribed">
+ <t t-call="portal.frontend_layout">
+ <div class="container mb64">
+ <div class="row">
+ <div class="col-lg-6 offset-lg-3">
+ <h3>SMS Subscription</h3>
+
+ <form t-att-action="'/sms/%s/unsubscribe/%s' % (mailing_id, trace_code)" method="post">
+ <p>Please enter your phone number</p>
+ <div class="form-group row">
+ <label for="sms_number" class="col-sm-2 col-form-label">Number</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" name="sms_number" id="sms_number"/>
+ </div>
+ </div>
+ <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
+ <input type="hidden" name="trace_code" t-att-value="trace_code"/>
+ <input type="hidden" name="mailing_id" t-att-value="mailing_id"/>
+ <div class="form-group row">
+ <div class="col-sm-10 offset-sm-2">
+ <button type="submit" class="btn btn-primary">Unsubscribe me</button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </t>
+ </template>
+
+ <template id="blacklist_number" name="Unsubscribed">
+ <t t-call="portal.frontend_layout">
+ <div class="container mb64">
+ <div class="row">
+ <div class="col-lg-6 offset-lg-3">
+ <h3>SMS Subscription</h3>
+
+ <div t-if="unsubscribe_error" class="alert alert-danger text-center" role="alert">
+ <p>There was an error when trying to unsubscribe <strong t-esc="sms_number"/></p>
+ <p t-esc="unsubscribe_error"/>
+ </div>
+ <div t-else="" class="alert alert-success text-center" role="status">
+ <t t-if="lists_optout">
+ <p><strong t-esc="sms_number"/> has been successfully removed from</p>
+ <t t-foreach="lists_optout" t-as="list_id">
+ <strong t-esc="list_id.name"/><br />
+ </t>
+ </t>
+ <p t-else="">
+ <strong t-esc="sms_number"/> has been successfully blacklisted
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </t>
+ </template>
+</odoo>