From 75306bb38e3a5ba4a7f9862c0d0c5deab0df8a99 Mon Sep 17 00:00:00 2001 From: Atchuthan Ubendran Date: Thu, 13 Jan 2022 18:33:42 +0530 Subject: [PATCH] [MIG] mail_activity_team: Migration to 14.0 --- mail_activity_team/README.rst | 11 +- mail_activity_team/__manifest__.py | 13 +- mail_activity_team/i18n/fr.po | 146 ------------------ mail_activity_team/i18n/it.po | 5 - .../i18n/mail_activity_team.pot | 5 - mail_activity_team/models/mail_activity.py | 37 +++-- .../models/mail_activity_mixin.py | 19 ++- .../models/mail_activity_team.py | 9 +- mail_activity_team/models/res_users.py | 65 +++++++- mail_activity_team/readme/CONTRIBUTORS.rst | 6 +- .../static/description/index.html | 12 +- mail_activity_team/static/src/js/systray.js | 102 ++++++++++++ mail_activity_team/static/src/xml/systray.xml | 25 +++ .../tests/test_mail_activity_team.py | 11 +- mail_activity_team/views/assets_backend.xml | 11 ++ 15 files changed, 262 insertions(+), 215 deletions(-) delete mode 100644 mail_activity_team/i18n/fr.po create mode 100644 mail_activity_team/static/src/js/systray.js create mode 100644 mail_activity_team/static/src/xml/systray.xml create mode 100644 mail_activity_team/views/assets_backend.xml diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index 15d829c..4a3ce63 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -69,19 +69,16 @@ Credits Authors ~~~~~~~ -* ForgeFlow +* Eficent Contributors ~~~~~~~~~~~~ -* `ForgeFlow `_: +* `Eficent `_: - * Jordi Ballester Alomar (jordi.ballester@forgeflow.com) - * Miquel Raïch (miquel.raich@forgeflow.com) + * Jordi Ballester Alomar (jordi.ballester@eficent.com) + * Miquel Raïch (miquel.raich@eficent.com) * Pedro Gonzalez (pedro.gonzalez@pesol.es) -* `Tecnativa `_: - - * David Vidal Maintainers ~~~~~~~~~~~ diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index af7632c..87fede2 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -1,21 +1,26 @@ -# Copyright 2018 ForgeFlow, S.L. +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# Copyright 2021 Sodexis # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Mail Activity Team", "summary": "Add Teams to Activities", - "version": "13.0.1.0.2", - "development_status": "Beta", + "version": "14.0.1.0.0", + "development_status": "Alpha", "category": "Social Network", "website": "https://github.com/OCA/social", - "author": "ForgeFlow, Odoo Community Association (OCA)", + "author": "Eficent, Sodexis, Odoo Community Association (OCA)", "license": "AGPL-3", "installable": True, "depends": ["mail_activity_board"], "data": [ + "views/assets_backend.xml", "security/ir.model.access.csv", "security/mail_activity_team_security.xml", "views/mail_activity_team_views.xml", "views/mail_activity_views.xml", "views/res_users_views.xml", ], + "qweb": [ + "static/src/xml/systray.xml", + ], } diff --git a/mail_activity_team/i18n/fr.po b/mail_activity_team/i18n/fr.po deleted file mode 100644 index e2b7dec..0000000 --- a/mail_activity_team/i18n/fr.po +++ /dev/null @@ -1,146 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * mail_activity_team -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 13.0\n" -"Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2022-01-13 12:40+0000\n" -"Last-Translator: tfo \n" -"Language-Team: none\n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.3.2\n" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active -msgid "Active" -msgstr "Actif" - -#. module: mail_activity_team -#: model:ir.model,name:mail_activity_team.model_mail_activity -msgid "Activity" -msgstr "Activité" - -#. module: mail_activity_team -#: model:ir.model,name:mail_activity_team.model_mail_activity_mixin -msgid "Activity Mixin" -msgstr "Combinaison d'activités" - -#. module: mail_activity_team -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_team_view_form -msgid "Activity Team" -msgstr "Equipe d'activité" - -#. module: mail_activity_team -#: model:ir.actions.act_window,name:mail_activity_team.mail_activity_team_action -#: model:ir.model.fields,field_description:mail_activity_team.field_res_users__activity_team_ids -#: model:ir.ui.menu,name:mail_activity_team.menu_mail_activity_team -msgid "Activity Teams" -msgstr "Equipes d'activité" - -#. module: mail_activity_team -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_team_view_form -msgid "Assign to missing activities" -msgstr "Assigner une équipe aux activités manquantes" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__create_uid -msgid "Created by" -msgstr "Créé par" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__create_date -msgid "Created on" -msgstr "Créé le" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__display_name -msgid "Display Name" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__id -msgid "ID" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team____last_update -msgid "Last Modified on" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_uid -msgid "Last Updated by" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_date -msgid "Last Updated on" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model,name:mail_activity_team.model_mail_activity_team -msgid "Mail Activity Team" -msgstr "" - -#. module: mail_activity_team -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_team_view_form -msgid "Members" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__count_missing_activities -msgid "Missing Activities" -msgstr "" - -#. module: mail_activity_team -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search -msgid "My Team Activities" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__name -msgid "Name" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search -msgid "Team" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__user_id -msgid "Team Leader" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__member_ids -msgid "Team Members" -msgstr "" - -#. module: mail_activity_team -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban -msgid "Team:" -msgstr "" - -#. module: mail_activity_team -#: code:addons/mail_activity_team/models/mail_activity.py:0 -#, python-format -msgid "The assigned user is not member of the team." -msgstr "" - -#. module: mail_activity_team -#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__res_model_ids -msgid "Used models" -msgstr "" - -#. module: mail_activity_team -#: model:ir.model,name:mail_activity_team.model_res_users -msgid "Users" -msgstr "" diff --git a/mail_activity_team/i18n/it.po b/mail_activity_team/i18n/it.po index dc71342..244576c 100644 --- a/mail_activity_team/i18n/it.po +++ b/mail_activity_team/i18n/it.po @@ -26,11 +26,6 @@ msgstr "Attivo" msgid "Activity" msgstr "Attività" -#. module: mail_activity_team -#: model:ir.model,name:mail_activity_team.model_mail_activity_mixin -msgid "Activity Mixin" -msgstr "" - #. module: mail_activity_team #: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_team_view_form msgid "Activity Team" diff --git a/mail_activity_team/i18n/mail_activity_team.pot b/mail_activity_team/i18n/mail_activity_team.pot index 430dcec..f073a58 100644 --- a/mail_activity_team/i18n/mail_activity_team.pot +++ b/mail_activity_team/i18n/mail_activity_team.pot @@ -23,11 +23,6 @@ msgstr "" msgid "Activity" msgstr "" -#. module: mail_activity_team -#: model:ir.model,name:mail_activity_team.model_mail_activity_mixin -msgid "Activity Mixin" -msgstr "" - #. module: mail_activity_team #: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_team_view_form msgid "Activity Team" diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index 7dc7e86..1d77149 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -1,4 +1,4 @@ -# Copyright 2018 ForgeFlow, S.L. +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import SUPERUSER_ID, _, api, fields, models from odoo.exceptions import ValidationError @@ -57,18 +57,23 @@ class MailActivity(models.Model): @api.constrains("team_id", "user_id") def _check_team_and_user(self): - # SUPERUSER is used to put mail.activity on some objects - # like sale.order coming from stock.picking - # (for example with exception type activity, with no backorder). - # SUPERUSER is inactive and then even if you add it - # to member_ids it's not taken account - # To not be blocked we must add it to constraint condition - # We must consider also users that could be archived but come from - # an automatic scheduled activity - for _activity in self.filtered( - lambda a: a.user_id.id != SUPERUSER_ID - and a.team_id - and a.user_id - and a.user_id not in a.team_id.with_context(active_test=True).member_ids - ): - raise ValidationError(_("The assigned user is not member of the team.")) + for activity in self: + # SUPERUSER is used to put mail.activity on some objects + # like sale.order coming from stock.picking + # (for example with exception type activity, with no backorder). + # SUPERUSER is inactive and then even if you add it + # to member_ids it's not taken account + # To not be blocked we must add it to constraint condition. + # We must consider also users that could be archived but come from + # an automatic scheduled activity + if ( + activity.user_id.id != SUPERUSER_ID + and activity.team_id + and activity.user_id + and activity.user_id + not in activity.team_id.with_context(active_test=False).member_ids + ): + raise ValidationError( + _("The assigned user %s is not member of the team %s.") + % (activity.user_id.name, activity.team_id.name) + ) diff --git a/mail_activity_team/models/mail_activity_mixin.py b/mail_activity_team/models/mail_activity_mixin.py index b45cd1f..fca47e8 100644 --- a/mail_activity_team/models/mail_activity_mixin.py +++ b/mail_activity_team/models/mail_activity_mixin.py @@ -1,11 +1,27 @@ # Copyright 2021 Tecnativa - David Vidal # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import models +from odoo import api, fields, models class MailActivityMixin(models.AbstractModel): _inherit = "mail.activity.mixin" + activity_team_user_ids = fields.Many2many( + comodel_name="res.users", + string="test field", + compute="_compute_activity_team_user_ids", + search="_search_activity_team_user_ids", + ) + + @api.depends("activity_ids") + def _compute_activity_team_user_ids(self): + for rec in self: + rec.activity_team_user_ids = rec.activity_ids.mapped("team_id.member_ids") + + @api.model + def _search_activity_team_user_ids(self, operator, operand): + return [("activity_ids.team_id.member_ids", operator, operand)] + def activity_schedule( self, act_type_xmlid="", date_deadline=None, summary="", note="", **act_values ): @@ -23,7 +39,6 @@ class MailActivityMixin(models.AbstractModel): ) ._get_default_team_id(user_id=user_id) ) - # Even if it comes empty, we don't want to mismatch the user's team act_values.update({"team_id": team.id}) return super().activity_schedule( act_type_xmlid=act_type_xmlid, diff --git a/mail_activity_team/models/mail_activity_team.py b/mail_activity_team/models/mail_activity_team.py index 7a34e66..e49f8d8 100644 --- a/mail_activity_team/models/mail_activity_team.py +++ b/mail_activity_team/models/mail_activity_team.py @@ -1,4 +1,5 @@ -# Copyright 2018 ForgeFlow, S.L. +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# Copyright 2021 Sodexis # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import api, fields, models @@ -48,12 +49,6 @@ class MailActivityTeam(models.Model): string="Missing Activities", compute="_compute_missing_activities", default=0 ) - @api.onchange("member_ids") - def _onchange_member_ids(self): - """Remove team leader in case is not a member anymore""" - if self.user_id and self.user_id not in self.member_ids: - self.user_id = False - @api.onchange("user_id") def _onchange_user_id(self): if self.user_id and self.user_id not in self.member_ids: diff --git a/mail_activity_team/models/res_users.py b/mail_activity_team/models/res_users.py index b30bfa1..8990fb8 100644 --- a/mail_activity_team/models/res_users.py +++ b/mail_activity_team/models/res_users.py @@ -1,6 +1,6 @@ -# Copyright 2018 ForgeFlow, S.L. +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import fields, models +from odoo import api, fields, models, modules class ResUsers(models.Model): @@ -11,3 +11,64 @@ class ResUsers(models.Model): relation="mail_activity_team_users_rel", string="Activity Teams", ) + + @api.model + def systray_get_activities(self): + if not self._context.get("team_activities", False): + return super().systray_get_activities() + query = """SELECT m.id, 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, act.user_id as user_id + FROM mail_activity AS act + JOIN ir_model AS m ON act.res_model_id = m.id + WHERE team_id in ( + SELECT mail_activity_team_id + FROM mail_activity_team_users_rel + WHERE res_users_id = %(user_id)s + ) + GROUP BY m.id, states, act.res_model, act.user_id;""" + user = self.env.uid + self.env.cr.execute( + query, + { + "today": fields.Date.context_today(self), + "user_id": user, + }, + ) + activity_data = self.env.cr.dictfetchall() + model_ids = [a["id"] for a in activity_data] + model_names = { + n[0]: n[1] for n in self.env["ir.model"].browse(model_ids).name_get() + } + user_activities = {} + for activity in activity_data: + if not user_activities.get(activity["model"]): + user_activities[activity["model"]] = { + "name": model_names[activity["id"]], + "model": activity["model"], + "type": "activity", + "icon": modules.module.get_module_icon( + self.env[activity["model"]]._original_module + ), + "total_count": 0, + "today_count": 0, + "overdue_count": 0, + "planned_count": 0, + } + user_activities[activity["model"]][ + "%s_count" % activity["states"] + ] += activity["count"] + if activity["states"] in ("today", "overdue"): + user_activities[activity["model"]]["total_count"] += activity["count"] + if activity["user_id"] == user and activity["states"] in ( + "today", + "overdue", + ): + user_activities[activity["model"]]["total_count"] -= activity["count"] + return list(user_activities.values()) diff --git a/mail_activity_team/readme/CONTRIBUTORS.rst b/mail_activity_team/readme/CONTRIBUTORS.rst index 692e142..f52e9e0 100644 --- a/mail_activity_team/readme/CONTRIBUTORS.rst +++ b/mail_activity_team/readme/CONTRIBUTORS.rst @@ -1,7 +1,7 @@ -* `ForgeFlow `_: +* `Eficent `_: - * Jordi Ballester Alomar (jordi.ballester@forgeflow.com) - * Miquel Raïch (miquel.raich@forgeflow.com) + * Jordi Ballester Alomar (jordi.ballester@eficent.com) + * Miquel Raïch (miquel.raich@eficent.com) * Pedro Gonzalez (pedro.gonzalez@pesol.es) * `Tecnativa `_: diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index 4b495c1..1db9b62 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -413,22 +413,18 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

Authors

    -
  • ForgeFlow
  • +
  • Eficent

Contributors

diff --git a/mail_activity_team/static/src/js/systray.js b/mail_activity_team/static/src/js/systray.js new file mode 100644 index 0000000..dbf5f75 --- /dev/null +++ b/mail_activity_team/static/src/js/systray.js @@ -0,0 +1,102 @@ +odoo.define("mail_activity_team.systray.ActivityMenu", function (require) { + "use strict"; + + var ActivityMenu = require("mail.systray.ActivityMenu"); + var session = require("web.session"); + + ActivityMenu.include({ + events: _.extend({}, ActivityMenu.prototype.events, { + "click .o_filter_button": "_onClickFilterButton", + }), + start: function () { + this._super.apply(this, arguments); + this.$filter_buttons = this.$(".o_filter_button"); + this.$my_activities = this.$filter_buttons.first(); + this.filter = "my"; + session.user_context = _.extend({}, session.user_context, { + team_activities: false, + }); + }, + + _updateCounter: function () { + this._super.apply(this, arguments); + this.$(".o_notification_counter").text(this.activityCounter); + }, + + _onClickFilterButton: function (event) { + var self = this; + event.stopPropagation(); + self.$filter_buttons.removeClass("active"); + var $target = $(event.currentTarget); + $target.addClass("active"); + self.filter = $target.data("filter"); + + session.user_context = _.extend({}, session.user_context, { + team_activities: self.filter === "team", + }); + + self._updateActivityPreview(); + }, + _onActivityFilterClick: function (event) { + if (this.filter === "my") { + this._super.apply(this, arguments); + } + if (this.filter === "team") { + var data = _.extend( + {}, + $(event.currentTarget).data(), + $(event.target).data() + ); + var context = {}; + if (data.filter === "my") { + context.search_default_activities_overdue = 1; + context.search_default_activities_today = 1; + } else { + context["search_default_activities_" + data.filter] = 1; + } + this.do_action({ + type: "ir.actions.act_window", + name: data.model_name, + res_model: data.res_model, + views: [ + [false, "kanban"], + [false, "form"], + ], + search_view_id: [false], + domain: [["activity_team_user_ids", "in", session.uid]], + context: context, + }); + } + }, + _getActivityData: function () { + var self = this; + return self._super.apply(self, arguments).then(function () { + session.user_context = _.extend({}, session.user_context, { + team_activities: !session.user_context.team_activities, + }); + + self._rpc({ + model: "res.users", + method: "systray_get_activities", + args: [], + kwargs: { + context: session.user_context, + }, + }).then(function (data) { + self.activityCounter += _.reduce( + data, + function (total_count, p_data) { + return total_count + p_data.total_count || 0; + }, + 0 + ); + self.$(".o_notification_counter").text(self.activityCounter); + self.$el.toggleClass("o_no_notification", !self.activityCounter); + session.user_context = _.extend({}, session.user_context, { + team_activities: !session.user_context.team_activities, + }); + }); + }); + }, + }); +}); diff --git a/mail_activity_team/static/src/xml/systray.xml b/mail_activity_team/static/src/xml/systray.xml new file mode 100644 index 0000000..dadf02c --- /dev/null +++ b/mail_activity_team/static/src/xml/systray.xml @@ -0,0 +1,25 @@ + + + + + +
+
+ + +
+
+
+
+ +
diff --git a/mail_activity_team/tests/test_mail_activity_team.py b/mail_activity_team/tests/test_mail_activity_team.py index 82faedd..201c816 100644 --- a/mail_activity_team/tests/test_mail_activity_team.py +++ b/mail_activity_team/tests/test_mail_activity_team.py @@ -1,4 +1,4 @@ -# Copyright 2018 ForgeFlow, S.L. +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo.exceptions import ValidationError from odoo.tests.common import TransactionCase @@ -139,15 +139,6 @@ class TestMailActivityTeam(TransactionCase): self.assertEqual(self.team1.count_missing_activities, 0) self.assertEqual(self.act1.team_id, self.team1) - def test_team_onchanges(self): - self.assertFalse( - self.team2.user_id, "Error: Team 2 should not have a Team Leader yet." - ) - self.team2.user_id = self.employee - self.team2.member_ids = [(3, self.employee.id)] - self.team2._onchange_member_ids() - self.assertFalse(self.team2.user_id) - def test_leader_onchange(self): self.team2.user_id = self.employee3 self.team2._onchange_user_id() diff --git a/mail_activity_team/views/assets_backend.xml b/mail_activity_team/views/assets_backend.xml new file mode 100644 index 0000000..f5f3eee --- /dev/null +++ b/mail_activity_team/views/assets_backend.xml @@ -0,0 +1,11 @@ + + +