From 8b31c5ef84e75c50299decd23e3b77f057a06b14 Mon Sep 17 00:00:00 2001 From: manu Date: Wed, 9 Oct 2024 10:39:48 +0200 Subject: [PATCH] [ADD]mute_notification_user_autosubscribe: Do not send notification to users autosubscribed through user_id field --- .../README.rst | 125 +++++ .../__init__.py | 4 + .../__manifest__.py | 21 + .../data/mail_message_subtype_data.xml | 8 + .../models/__init__.py | 6 + .../models/mail_thread.py | 31 ++ .../models/res_users.py | 25 + .../models/user_autosubscribe_mute.py | 37 ++ .../pyproject.toml | 3 + .../readme/CONFIGURE.md | 9 + .../readme/CONTRIBUTORS.md | 3 + .../readme/DESCRIPTION.md | 1 + .../readme/ROADMAP.md | 1 + .../readme/USAGE.md | 1 + .../security/ir.model.access.csv | 3 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 473 ++++++++++++++++++ .../tests/__init__.py | 4 + .../tests/test_mute_user_sutosubscribe.py | 119 +++++ .../views/user_autosubscribe_mute_views.xml | 75 +++ 20 files changed, 949 insertions(+) create mode 100644 mute_notification_user_autosubscribe/README.rst create mode 100644 mute_notification_user_autosubscribe/__init__.py create mode 100644 mute_notification_user_autosubscribe/__manifest__.py create mode 100644 mute_notification_user_autosubscribe/data/mail_message_subtype_data.xml create mode 100644 mute_notification_user_autosubscribe/models/__init__.py create mode 100644 mute_notification_user_autosubscribe/models/mail_thread.py create mode 100644 mute_notification_user_autosubscribe/models/res_users.py create mode 100644 mute_notification_user_autosubscribe/models/user_autosubscribe_mute.py create mode 100644 mute_notification_user_autosubscribe/pyproject.toml create mode 100644 mute_notification_user_autosubscribe/readme/CONFIGURE.md create mode 100644 mute_notification_user_autosubscribe/readme/CONTRIBUTORS.md create mode 100644 mute_notification_user_autosubscribe/readme/DESCRIPTION.md create mode 100644 mute_notification_user_autosubscribe/readme/ROADMAP.md create mode 100644 mute_notification_user_autosubscribe/readme/USAGE.md create mode 100644 mute_notification_user_autosubscribe/security/ir.model.access.csv create mode 100644 mute_notification_user_autosubscribe/static/description/icon.png create mode 100644 mute_notification_user_autosubscribe/static/description/index.html create mode 100644 mute_notification_user_autosubscribe/tests/__init__.py create mode 100644 mute_notification_user_autosubscribe/tests/test_mute_user_sutosubscribe.py create mode 100644 mute_notification_user_autosubscribe/views/user_autosubscribe_mute_views.xml diff --git a/mute_notification_user_autosubscribe/README.rst b/mute_notification_user_autosubscribe/README.rst new file mode 100644 index 0000000000..43739e2fd1 --- /dev/null +++ b/mute_notification_user_autosubscribe/README.rst @@ -0,0 +1,125 @@ +==================================== +Mute Notification User Autosubscribe +==================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:a4066de365398f1629027be5bf5dd6fcc6fdc886eb81465f8f8224f603dd1333 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github + :target: https://github.com/OCA/social/tree/17.0/mute_notification_user_autosubscribe + :alt: OCA/social +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/social-17-0/social-17-0-mute_notification_user_autosubscribe + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to select users and/or groups whose members do not +have to be sent notifications through the chatter. The models in which +these rules have to be applied can also be selected. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +To configure this module you need to: + +- Go to Settings > Technical > Auto Subscribe Mute +- Create a new instance or edit an exiting one. The following fields + are available: + + - **Name**. The name of the rule. + - **Model**. Model in which the rule is applied. Only models with a + user_id field can be selected. + - **Users**. List of users which the rule will be applied to. The + users in this field will be autosubscribed to the document when + they are set in the user_id field but only with the "Muted" + subtype, which notifies nothing. Note that this rule will not be + applied when the user in the list set itself in the user_id field, + as the subscription in this case depends on the creation of the + document, not the autosubscription. + - **Groups**. List of groups which the rule will be applied to. The + users that belong to the groups in this field will be + autosubscribed to the document when they are set in the user_id + field but only with the "Muted" subtype, which notifies nothing. + Note that this rule will not be applied when a user in any of the + groups in the list set itself in the user_id field, as the + subscription in this case depends on the creation of the document, + not the autosubscription. + - **Notes**. Text field. + +Usage +===== + +In case a user that has been automatically applied the "Mute" message +subtype in a subscription through one of the rules provided in this +module needs to be sent notifications in a specific document, just edit +the subscription and select the subtypes for which the user has to be +sent notifications. + +Known issues / Roadmap +====================== + +- If a and "Auto Subscribe Mute" rule is modified, created or deleted, + changes will not affect existing documents, so their users subtypes + will keep the current configuration. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Sygel + +Contributors +------------ + +- Manuel Regidor +- Valentín Vinagre +- Harald Panten + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/social `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mute_notification_user_autosubscribe/__init__.py b/mute_notification_user_autosubscribe/__init__.py new file mode 100644 index 0000000000..a6aeb406c0 --- /dev/null +++ b/mute_notification_user_autosubscribe/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2024 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import models diff --git a/mute_notification_user_autosubscribe/__manifest__.py b/mute_notification_user_autosubscribe/__manifest__.py new file mode 100644 index 0000000000..1c7a1da6fc --- /dev/null +++ b/mute_notification_user_autosubscribe/__manifest__.py @@ -0,0 +1,21 @@ +# Copyright 2024 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Mute Notification User Autosubscribe", + "summary": "Do not send notifications to users autosubcribed through user_id field", + "version": "17.0.1.0.0", + "category": "Social", + "website": "https://github.com/OCA/social", + "author": "Sygel,Odoo Community Association (OCA)", + "license": "AGPL-3", + "installable": True, + "depends": [ + "mail", + ], + "data": [ + "data/mail_message_subtype_data.xml", + "security/ir.model.access.csv", + "views/user_autosubscribe_mute_views.xml", + ], +} diff --git a/mute_notification_user_autosubscribe/data/mail_message_subtype_data.xml b/mute_notification_user_autosubscribe/data/mail_message_subtype_data.xml new file mode 100644 index 0000000000..693792823f --- /dev/null +++ b/mute_notification_user_autosubscribe/data/mail_message_subtype_data.xml @@ -0,0 +1,8 @@ + + + + Mute + + 999 + + diff --git a/mute_notification_user_autosubscribe/models/__init__.py b/mute_notification_user_autosubscribe/models/__init__.py new file mode 100644 index 0000000000..5ca893076f --- /dev/null +++ b/mute_notification_user_autosubscribe/models/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2024 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import user_autosubscribe_mute +from . import mail_thread +from . import res_users diff --git a/mute_notification_user_autosubscribe/models/mail_thread.py b/mute_notification_user_autosubscribe/models/mail_thread.py new file mode 100644 index 0000000000..efc24eefbd --- /dev/null +++ b/mute_notification_user_autosubscribe/models/mail_thread.py @@ -0,0 +1,31 @@ +# Copyright 2024 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class MailThread(models.AbstractModel): + _inherit = "mail.thread" + + def _message_auto_subscribe_followers(self, updated_values, default_subtype_ids): + user_id = updated_values.get("user_id") + if user_id: + model = self.env["ir.model"]._get(self._name) + user = self.env["res.users"].browse(user_id) + partner_id = user.partner_id.id + # Do nothing in case the user is already subscribe. + # It happes, for example, when it is the user_id who creates + # the document + if ( + partner_id not in self.message_partner_ids.ids + and user + and model + and user._is_muted(model) + ): + default_subtype_ids = [ + self.env.ref("mute_notification_user_autosubscribe.muted").id + ] + vals = super()._message_auto_subscribe_followers( + updated_values, default_subtype_ids + ) + return vals diff --git a/mute_notification_user_autosubscribe/models/res_users.py b/mute_notification_user_autosubscribe/models/res_users.py new file mode 100644 index 0000000000..f956a0a50a --- /dev/null +++ b/mute_notification_user_autosubscribe/models/res_users.py @@ -0,0 +1,25 @@ +# Copyright 2024 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class ResUsers(models.Model): + _inherit = "res.users" + + def _is_muted(self, model): + self.ensure_one() + muted = False + user_autosubscribe_mute = self.env["user.autosubscribe.mute"].search( + [("model_id", "=", model.id)], limit=1 + ) + if user_autosubscribe_mute: + groups = ( + ",".join(user_autosubscribe_mute.group_ids.get_external_id().values()) + or "" + ) + if self.id in user_autosubscribe_mute.user_ids.ids or ( + groups and self.user_has_groups(groups) + ): + muted = True + return muted diff --git a/mute_notification_user_autosubscribe/models/user_autosubscribe_mute.py b/mute_notification_user_autosubscribe/models/user_autosubscribe_mute.py new file mode 100644 index 0000000000..f7b0451848 --- /dev/null +++ b/mute_notification_user_autosubscribe/models/user_autosubscribe_mute.py @@ -0,0 +1,37 @@ +# Copyright 2024 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, fields, models + + +class UserAutosubscribeMute(models.Model): + _name = "user.autosubscribe.mute" + _description = "User Autosubscribe Mute" + + def _get_user_models_domain(self): + models = ( + self.env["ir.model.fields"] + .search([("name", "=", "user_id"), ("relation", "=", "res.users")]) + .mapped("model_id") + ) + return f"[('id', 'in', {models.ids})]" + + name = fields.Char(required=True) + active = fields.Boolean(default=True) + model_id = fields.Many2one( + comodel_name="ir.model", + domain=_get_user_models_domain, + ondelete="cascade", + required=True, + ) + user_ids = fields.Many2many(comodel_name="res.users", string="Users") + group_ids = fields.Many2many(comodel_name="res.groups", string="Groups") + notes = fields.Text() + + _sql_constraints = [ + ( + "unique_model_id", + "UNIQUE(model_id)", + _("Model must be unique in User Autosubscribe Mute instances."), + ) + ] diff --git a/mute_notification_user_autosubscribe/pyproject.toml b/mute_notification_user_autosubscribe/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/mute_notification_user_autosubscribe/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mute_notification_user_autosubscribe/readme/CONFIGURE.md b/mute_notification_user_autosubscribe/readme/CONFIGURE.md new file mode 100644 index 0000000000..f10cf827d7 --- /dev/null +++ b/mute_notification_user_autosubscribe/readme/CONFIGURE.md @@ -0,0 +1,9 @@ +To configure this module you need to: + +- Go to Settings > Technical > Auto Subscribe Mute +- Create a new instance or edit an exiting one. The following fields are available: + - **Name**. The name of the rule. + - **Model**. Model in which the rule is applied. Only models with a user_id field can be selected. + - **Users**. List of users which the rule will be applied to. The users in this field will be autosubscribed to the document when they are set in the user_id field but only with the "Muted" subtype, which notifies nothing. Note that this rule will not be applied when the user in the list set itself in the user_id field, as the subscription in this case depends on the creation of the document, not the autosubscription. + - **Groups**. List of groups which the rule will be applied to. The users that belong to the groups in this field will be autosubscribed to the document when they are set in the user_id field but only with the "Muted" subtype, which notifies nothing. Note that this rule will not be applied when a user in any of the groups in the list set itself in the user_id field, as the subscription in this case depends on the creation of the document, not the autosubscription. + - **Notes**. Text field. diff --git a/mute_notification_user_autosubscribe/readme/CONTRIBUTORS.md b/mute_notification_user_autosubscribe/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..6e25ae445d --- /dev/null +++ b/mute_notification_user_autosubscribe/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- Manuel Regidor \<\> +- Valentín Vinagre \<\> +- Harald Panten \<\> diff --git a/mute_notification_user_autosubscribe/readme/DESCRIPTION.md b/mute_notification_user_autosubscribe/readme/DESCRIPTION.md new file mode 100644 index 0000000000..e452723ac8 --- /dev/null +++ b/mute_notification_user_autosubscribe/readme/DESCRIPTION.md @@ -0,0 +1 @@ +This module allows to select users and/or groups whose members do not have to be sent notifications through the chatter. The models in which these rules have to be applied can also be selected. diff --git a/mute_notification_user_autosubscribe/readme/ROADMAP.md b/mute_notification_user_autosubscribe/readme/ROADMAP.md new file mode 100644 index 0000000000..d6f2aba903 --- /dev/null +++ b/mute_notification_user_autosubscribe/readme/ROADMAP.md @@ -0,0 +1 @@ +- If a and "Auto Subscribe Mute" rule is modified, created or deleted, changes will not affect existing documents, so their users subtypes will keep the current configuration. diff --git a/mute_notification_user_autosubscribe/readme/USAGE.md b/mute_notification_user_autosubscribe/readme/USAGE.md new file mode 100644 index 0000000000..4356a5ef01 --- /dev/null +++ b/mute_notification_user_autosubscribe/readme/USAGE.md @@ -0,0 +1 @@ +In case a user that has been automatically applied the "Mute" message subtype in a subscription through one of the rules provided in this module needs to be sent notifications in a specific document, just edit the subscription and select the subtypes for which the user has to be sent notifications. diff --git a/mute_notification_user_autosubscribe/security/ir.model.access.csv b/mute_notification_user_autosubscribe/security/ir.model.access.csv new file mode 100644 index 0000000000..53269bf430 --- /dev/null +++ b/mute_notification_user_autosubscribe/security/ir.model.access.csv @@ -0,0 +1,3 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"user_autosubscribe_mute_access","user.autosubscribe.mute.access","model_user_autosubscribe_mute",base.group_user,1,0,0,0 +"user_autosubscribe_mute_manage","user.autosubscribe.mute.manage","model_user_autosubscribe_mute",base.group_system,1,1,1,1 diff --git a/mute_notification_user_autosubscribe/static/description/icon.png b/mute_notification_user_autosubscribe/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/mute_notification_user_autosubscribe/static/description/index.html b/mute_notification_user_autosubscribe/static/description/index.html new file mode 100644 index 0000000000..a8d5fb2438 --- /dev/null +++ b/mute_notification_user_autosubscribe/static/description/index.html @@ -0,0 +1,473 @@ + + + + + +Mute Notification User Autosubscribe + + + +
+

Mute Notification User Autosubscribe

+ + +

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runboat

+

This module allows to select users and/or groups whose members do not +have to be sent notifications through the chatter. The models in which +these rules have to be applied can also be selected.

+

Table of contents

+ +
+

Configuration

+

To configure this module you need to:

+
    +
  • Go to Settings > Technical > Auto Subscribe Mute
  • +
  • Create a new instance or edit an exiting one. The following fields +are available:
      +
    • Name. The name of the rule.
    • +
    • Model. Model in which the rule is applied. Only models with a +user_id field can be selected.
    • +
    • Users. List of users which the rule will be applied to. The +users in this field will be autosubscribed to the document when +they are set in the user_id field but only with the “Muted” +subtype, which notifies nothing. Note that this rule will not be +applied when the user in the list set itself in the user_id field, +as the subscription in this case depends on the creation of the +document, not the autosubscription.
    • +
    • Groups. List of groups which the rule will be applied to. The +users that belong to the groups in this field will be +autosubscribed to the document when they are set in the user_id +field but only with the “Muted” subtype, which notifies nothing. +Note that this rule will not be applied when a user in any of the +groups in the list set itself in the user_id field, as the +subscription in this case depends on the creation of the document, +not the autosubscription.
    • +
    • Notes. Text field.
    • +
    +
  • +
+
+
+

Usage

+

In case a user that has been automatically applied the “Mute” message +subtype in a subscription through one of the rules provided in this +module needs to be sent notifications in a specific document, just edit +the subscription and select the subtypes for which the user has to be +sent notifications.

+
+
+

Known issues / Roadmap

+
    +
  • If a and “Auto Subscribe Mute” rule is modified, created or deleted, +changes will not affect existing documents, so their users subtypes +will keep the current configuration.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Sygel
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/social project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/mute_notification_user_autosubscribe/tests/__init__.py b/mute_notification_user_autosubscribe/tests/__init__.py new file mode 100644 index 0000000000..19ad0c5b2b --- /dev/null +++ b/mute_notification_user_autosubscribe/tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2024 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_mute_user_sutosubscribe diff --git a/mute_notification_user_autosubscribe/tests/test_mute_user_sutosubscribe.py b/mute_notification_user_autosubscribe/tests/test_mute_user_sutosubscribe.py new file mode 100644 index 0000000000..1290e32cd2 --- /dev/null +++ b/mute_notification_user_autosubscribe/tests/test_mute_user_sutosubscribe.py @@ -0,0 +1,119 @@ +# Copyright 2024 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests import new_test_user + +from odoo.addons.mail.tests.common import MailCommon + + +class TestMuteUserAutosubscribe(MailCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.user_1 = new_test_user( + cls.env, login="user_1", groups="base.group_partner_manager,base.group_user" + ) + cls.user_2 = new_test_user( + cls.env, login="user_2", groups="base.group_partner_manager,base.group_user" + ) + cls.user_autosubscribe_mute = cls.env["user.autosubscribe.mute"].create( + { + "name": "Mute Contact Notification", + "model_id": cls.env["ir.model"]._get("res.partner").id, + } + ) + + def send_email_mute_autosubscribe(cls, doc, user_id, body): + with cls.mock_mail_gateway(): + return doc.with_user(user_id.id).message_post( + body=body, subtype_xmlid="mail.mt_comment" + ) + + def test_do_not_mute_user_field(self): + user_2_partner = self.user_2.partner_id + # Create new contact with user_1. + contact = ( + self.env["res.partner"] + .with_user(self.user_1.id) + .create({"name": "Contact"}) + ) + # Check user_2 is not subscribed + self.assertFalse(user_2_partner.id in contact.message_partner_ids.ids) + # Set user_2 as the Salesperson + # Check user_2 is now subscribed + contact.write({"user_id": self.user_2.id}) + self.assertTrue(user_2_partner.id in contact.message_partner_ids.ids) + # Post message with user_1 + message = self.send_email_mute_autosubscribe(contact, self.user_1, "Test-1") + # user_2 has been sent a notification + receivers = message.notification_ids.mapped("res_partner_id") + self.assertTrue(user_2_partner.id in receivers.ids) + + def test_mute_users_field(self): + user_2_partner = self.user_2.partner_id + # Mute user_2 from salesperson autosubscription in res.partner + self.user_autosubscribe_mute.write({"user_ids": [self.user_2.id]}) + # Create new contact with user_1 and set user_2 and set user_2 as the + # salesperson + contact = ( + self.env["res.partner"] + .with_user(self.user_1.id) + .create({"name": "Contact", "user_id": self.user_2.id}) + ) + # Check user_2 is subscribed + self.assertTrue(user_2_partner.id in contact.message_partner_ids.ids) + # Post message with user_1 + message = self.send_email_mute_autosubscribe(contact, self.user_1, "Test-2") + # user_2 has NOT been sent a notification + receivers = message.notification_ids.mapped("res_partner_id") + self.assertFalse(user_2_partner.id in receivers.ids) + # user_2 subscription only contains "Mute" subtype + follower = self.env["mail.followers"].search( + [ + ("res_model", "=", "res.partner"), + ("res_id", "=", contact.id), + ("partner_id", "=", user_2_partner.id), + ], + limit=1, + ) + self.assertEqual(len(follower.subtype_ids), 1) + self.assertEqual( + follower.subtype_ids[0], + self.env.ref("mute_notification_user_autosubscribe.muted"), + ) + + def test_mute_groups_field(self): + user_2_partner = self.user_2.partner_id + # Mute group base.group_partner_manager from salesperson + # autosubscription in res.partner + self.user_autosubscribe_mute.write( + {"group_ids": [self.env.ref("base.group_partner_manager").id]} + ) + # Create new contact with user_1 and set user_2 and set user_2 as the + # salesperson + contact = ( + self.env["res.partner"] + .with_user(self.user_1.id) + .create({"name": "Contact", "user_id": self.user_2.id}) + ) + # Check user_2 is subscribed + self.assertTrue(user_2_partner.id in contact.message_partner_ids.ids) + # Post message with user_1 + message = self.send_email_mute_autosubscribe(contact, self.user_1, "Test-2") + # user_2 has NOT been sent a notification + receivers = message.notification_ids.mapped("res_partner_id") + self.assertFalse(user_2_partner.id in receivers.ids) + # user_2 subscription only contains "Mute" subtype + follower = self.env["mail.followers"].search( + [ + ("res_model", "=", "res.partner"), + ("res_id", "=", contact.id), + ("partner_id", "=", user_2_partner.id), + ], + limit=1, + ) + self.assertEqual(len(follower.subtype_ids), 1) + self.assertEqual( + follower.subtype_ids[0], + self.env.ref("mute_notification_user_autosubscribe.muted"), + ) diff --git a/mute_notification_user_autosubscribe/views/user_autosubscribe_mute_views.xml b/mute_notification_user_autosubscribe/views/user_autosubscribe_mute_views.xml new file mode 100644 index 0000000000..d4df67c278 --- /dev/null +++ b/mute_notification_user_autosubscribe/views/user_autosubscribe_mute_views.xml @@ -0,0 +1,75 @@ + + + + + user.autosubscribe.mute.form.view + user.autosubscribe.mute + +
+ + +
+
+ + + + + + + + + + + + + +
+
+
+
+ + user.autosubscribe.mute.tree.view + user.autosubscribe.mute + + + + + + + + + + + User Autosubscribe Mute + user.autosubscribe.mute + tree,form + + +