From abaae1e46357f41905a5e20535576984023e7b5b Mon Sep 17 00:00:00 2001 From: "Tiffany Chang (tic)" Date: Mon, 13 Jan 2020 09:32:54 +0000 Subject: [PATCH 1/3] [IMP] mass_mailing_(sms): split systray activities Due to 'mass_mailing_sms' inheriting mailing.mailing from 'mass_mailing', activities for these two modules would show up as one "Mass Mailing" line in the systray. This commit adds additional logic to remove this "Mass Mailing" line and replace it with 2 lines: "Email Marketing" and "SMS Marketing" with their appropriately matching module icon. For consistency, when only the 'mass_mailing' module is installed, it will still display "Email Marketing". Task: 2169498 --- addons/mass_mailing/models/__init__.py | 1 + addons/mass_mailing/models/res_users.py | 21 +++++++ addons/mass_mailing_sms/models/__init__.py | 1 + addons/mass_mailing_sms/models/res_users.py | 67 +++++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 addons/mass_mailing/models/res_users.py create mode 100644 addons/mass_mailing_sms/models/res_users.py diff --git a/addons/mass_mailing/models/__init__.py b/addons/mass_mailing/models/__init__.py index 9797d43aeff..64b451ac37b 100644 --- a/addons/mass_mailing/models/__init__.py +++ b/addons/mass_mailing/models/__init__.py @@ -10,4 +10,5 @@ from . import mail_mail from . import mail_template from . import mail_thread from . import res_config_settings +from . import res_users from . import utm diff --git a/addons/mass_mailing/models/res_users.py b/addons/mass_mailing/models/res_users.py new file mode 100644 index 00000000000..04b1cb74910 --- /dev/null +++ b/addons/mass_mailing/models/res_users.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, models, _ + + +class Users(models.Model): + _name = 'res.users' + _inherit = ['res.users'] + + @api.model + def systray_get_activities(self): + """ Update systray name of mailing.mailing from "Mass Mailing" + to "Email Marketing". + """ + activities = super(Users, self).systray_get_activities() + for activity in activities: + if activity.get('model') == 'mailing.mailing': + activity['name'] = _('Email Marketing') + break + return activities diff --git a/addons/mass_mailing_sms/models/__init__.py b/addons/mass_mailing_sms/models/__init__.py index 76457e3bdf4..1f0a7eb2c86 100644 --- a/addons/mass_mailing_sms/models/__init__.py +++ b/addons/mass_mailing_sms/models/__init__.py @@ -5,5 +5,6 @@ from . import mailing_contact from . import mailing_list from . import mailing_mailing from . import mailing_trace +from . import res_users from . import sms_sms from . import utm diff --git a/addons/mass_mailing_sms/models/res_users.py b/addons/mass_mailing_sms/models/res_users.py new file mode 100644 index 00000000000..cc095e7e397 --- /dev/null +++ b/addons/mass_mailing_sms/models/res_users.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, modules, _ + + +class Users(models.Model): + _name = 'res.users' + _inherit = ['res.users'] + + @api.model + def systray_get_activities(self): + """ Split mass_mailing and mass_mailing_sms activities in systray by + removing the single mailing.mailing activity represented and + doing a new query to split them by mailing_type. + """ + activities = super(Users, self).systray_get_activities() + for activity in activities: + if activity.get('model') == 'mailing.mailing': + activities.remove(activity) + query = """SELECT m.mailing_type, count(*), act.res_model as model, + CASE + WHEN %(today)s::date - act.date_deadline::date = 0 Then 'today' + WHEN %(today)s::date - act.date_deadline::date > 0 Then 'overdue' + WHEN %(today)s::date - act.date_deadline::date < 0 Then 'planned' + END AS states + FROM mail_activity AS act + JOIN mailing_mailing AS m ON act.res_id = m.id + WHERE act.res_model = 'mailing.mailing' AND act.user_id = %(user_id)s + GROUP BY m.mailing_type, states, act.res_model; + """ + self.env.cr.execute(query, { + 'today': fields.Date.context_today(self), + 'user_id': self.env.uid, + }) + activity_data = self.env.cr.dictfetchall() + + user_activities = {} + for act in activity_data: + if not user_activities.get(act['mailing_type']): + if act['mailing_type'] == 'sms': + module = 'mass_mailing_sms' + name = _('SMS Marketing') + else: + module = 'mass_mailing' + name = _('Email Marketing') + icon = module and modules.module.get_module_icon(module) + user_activities[act['mailing_type']] = { + 'name': name, + 'model': 'mailing.mailing', + 'type': 'activity', + 'icon': icon, + 'total_count': 0, 'today_count': 0, 'overdue_count': 0, 'planned_count': 0, + } + user_activities[act['mailing_type']]['%s_count' % act['states']] += act['count'] + if act['states'] in ('today', 'overdue'): + user_activities[act['mailing_type']]['total_count'] += act['count'] + + for mailing_type in user_activities.keys(): + user_activities[mailing_type].update({ + 'actions': [{'icon': 'fa-clock-o', 'name': 'Summary',}], + }) + + activities.extend(list(user_activities.values())) + break + + return activities From b786adf2e922dce30987acfa0172c3d1f162cf59 Mon Sep 17 00:00:00 2001 From: "Tiffany Chang (tic)" Date: Tue, 14 Jan 2020 09:55:14 +0000 Subject: [PATCH 2/3] [IMP] Mail: Add optional activity domain for systray Addition of this optional 'domain' value for systray activity related lines allows the restriction of which activities will be included in the view opened when the line is clicked on. One use case is when a model is split between 2 systray activity lines. In this case we most likely do not want the same activities of the model to show up when we click on either line. For example, say we have 2 modules using the same model, but the module instances of that model are distingushed by a field.Selection value. Then we would only want to show the activities related to each module when we click on their appropriate systray activity lines based on that field.Selection value. Task: 2169498 --- .../src/js/systray/systray_activity_menu.js | 15 +++++++++++++-- addons/mail/static/src/xml/systray.xml | 5 +++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/addons/mail/static/src/js/systray/systray_activity_menu.js b/addons/mail/static/src/js/systray/systray_activity_menu.js index 14a3ff7e513..8edad417456 100644 --- a/addons/mail/static/src/js/systray/systray_activity_menu.js +++ b/addons/mail/static/src/js/systray/systray_activity_menu.js @@ -111,13 +111,18 @@ var ActivityMenu = Widget.extend({ if (actionXmlid) { this.do_action(actionXmlid); } else { + var domain = [['activity_ids.user_id', '=', session.uid]] + if (targetAction.data('domain')) { + domain = domain.concat(targetAction.data('domain')) + } + this.do_action({ type: 'ir.actions.act_window', name: targetAction.data('model_name'), views: [[false, 'activity'], [false, 'kanban'], [false, 'list']], view_mode: 'activity', res_model: targetAction.data('res_model'), - domain: [['activity_ids.user_id', '=', session.uid]], + domain: domain, }); } }, @@ -140,13 +145,19 @@ var ActivityMenu = Widget.extend({ // Necessary because activity_ids of mail.activity.mixin has auto_join // So, duplicates are faking the count and "Load more" doesn't show up context['force_search_count'] = 1; + + var domain = [['activity_ids.user_id', '=', session.uid]] + if (data.domain) { + domain = domain.concat(data.domain) + } + this.do_action({ type: 'ir.actions.act_window', name: data.model_name, res_model: data.res_model, views: [[false, 'kanban'], [false, 'list'], [false, 'form']], search_view_id: [false], - domain: [['activity_user_id', '=', session.uid]], + domain: domain, context:context, }); }, diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml index dc275079e28..b10ef51a429 100644 --- a/addons/mail/static/src/xml/systray.xml +++ b/addons/mail/static/src/xml/systray.xml @@ -71,7 +71,7 @@ -
+
Activity
@@ -87,7 +87,8 @@ t-att-class="'o_mail_activity_action btn btn-link fa ' + action.icon" t-att-data-action_xmlid="action.action_xmlid" t-att-data-res_model="activity.model" - t-att-data-model_name="activity.name"> + t-att-data-model_name="activity.name" + t-att-data-domain="activity.domain">
From dced1d2f701b69725a998fce48fd1df3a6be11a6 Mon Sep 17 00:00:00 2001 From: "Tiffany Chang (tic)" Date: Tue, 14 Jan 2020 10:15:45 +0000 Subject: [PATCH 3/3] [IMP] mass_mailing_sms: Add mailing_type domain activity restriction Restrict the displayed activities when clicking on "Email Marketing" and "SMS Marketing" modules in the activity systray. Due to their activities being linked to the same model, we need to distinguish which activities belong to which module based on their assigned mailing_type value. Without this domain restriction, users can still filter based on mailing_type, but it is much less intuitive this way due to them being separate apps. Task: 2169498 --- addons/mass_mailing_sms/models/res_users.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/addons/mass_mailing_sms/models/res_users.py b/addons/mass_mailing_sms/models/res_users.py index cc095e7e397..8c23887c537 100644 --- a/addons/mass_mailing_sms/models/res_users.py +++ b/addons/mass_mailing_sms/models/res_users.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +import json + from odoo import api, fields, models, modules, _ @@ -18,7 +20,7 @@ class Users(models.Model): for activity in activities: if activity.get('model') == 'mailing.mailing': activities.remove(activity) - query = """SELECT m.mailing_type, count(*), act.res_model as model, + query = """SELECT m.mailing_type, count(*), act.res_model as model, act.res_id, CASE WHEN %(today)s::date - act.date_deadline::date = 0 Then 'today' WHEN %(today)s::date - act.date_deadline::date > 0 Then 'overdue' @@ -27,7 +29,7 @@ class Users(models.Model): FROM mail_activity AS act JOIN mailing_mailing AS m ON act.res_id = m.id WHERE act.res_model = 'mailing.mailing' AND act.user_id = %(user_id)s - GROUP BY m.mailing_type, states, act.res_model; + GROUP BY m.mailing_type, states, act.res_model, act.res_id; """ self.env.cr.execute(query, { 'today': fields.Date.context_today(self), @@ -45,13 +47,16 @@ class Users(models.Model): module = 'mass_mailing' name = _('Email Marketing') icon = module and modules.module.get_module_icon(module) + res_ids = set() user_activities[act['mailing_type']] = { 'name': name, 'model': 'mailing.mailing', 'type': 'activity', 'icon': icon, 'total_count': 0, 'today_count': 0, 'overdue_count': 0, 'planned_count': 0, + 'res_ids': res_ids, } + user_activities[act['mailing_type']]['res_ids'].add(act['res_id']) user_activities[act['mailing_type']]['%s_count' % act['states']] += act['count'] if act['states'] in ('today', 'overdue'): user_activities[act['mailing_type']]['total_count'] += act['count'] @@ -59,8 +64,8 @@ class Users(models.Model): for mailing_type in user_activities.keys(): user_activities[mailing_type].update({ 'actions': [{'icon': 'fa-clock-o', 'name': 'Summary',}], + 'domain': json.dumps([['activity_ids.res_id', 'in', list(user_activities[mailing_type]['res_ids'])]]) }) - activities.extend(list(user_activities.values())) break