Skip to content

[16.0][WIP] base_tier_validation: Proper notifications on reviews #1083

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 16.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base_tier_validation/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"name": "Base Tier Validation",
"summary": "Implement a validation process based on tiers.",
"version": "16.0.2.6.0",
"version": "16.0.2.7.0",
"development_status": "Mature",
"maintainers": ["LoisRForgeFlow"],
"category": "Tools",
Expand Down
8 changes: 4 additions & 4 deletions base_tier_validation/data/mail_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
forcecreate="1"
>
<field name="name">Tier Validation Requested</field>
<field name="default" eval="True" />
<field name="default" eval="False" />
<field name="internal" eval="True" />
<field name="hidden" eval="True" />
</record>
Expand All @@ -16,7 +16,7 @@
forcecreate="1"
>
<field name="name">Tier Validation Accepted Notification</field>
<field name="default" eval="True" />
<field name="default" eval="False" />
<field name="internal" eval="True" />
<field name="hidden" eval="True" />
</record>
Expand All @@ -26,7 +26,7 @@
forcecreate="1"
>
<field name="name">Tier Validation Rejected Notification</field>
<field name="default" eval="True" />
<field name="default" eval="False" />
<field name="internal" eval="True" />
<field name="hidden" eval="True" />
</record>
Expand All @@ -36,7 +36,7 @@
forcecreate="1"
>
<field name="name">Tier Validation Restarted</field>
<field name="default" eval="True" />
<field name="default" eval="False" />
<field name="internal" eval="True" />
<field name="hidden" eval="True" />
</record>
Expand Down
15 changes: 15 additions & 0 deletions base_tier_validation/migrations/16.0.2.7.0/noupdate_changes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="mt_tier_validation_requested" model="mail.message.subtype">
<field name="default" eval="False" />
</record>
<record id="mt_tier_validation_accepted" model="mail.message.subtype">
<field name="default" eval="False" />
</record>
<record id="mt_tier_validation_rejected" model="mail.message.subtype">
<field name="default" eval="False" />
</record>
<record id="mt_tier_validation_restarted" model="mail.message.subtype">
<field name="default" eval="False" />
</record>
</odoo>
10 changes: 10 additions & 0 deletions base_tier_validation/migrations/16.0.2.7.0/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright 2025 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openupgradelib import openupgrade


@openupgrade.migrate()
def migrate(env, version):
openupgrade.load_data(
env.cr, "base_tier_validation", "migrations/16.0.2.7.0/noupdate_changes.xml"
)
48 changes: 44 additions & 4 deletions base_tier_validation/models/tier_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,13 +479,29 @@
reviews_to_notify = user_reviews.filtered(
lambda r: r.definition_id.notify_on_accepted
)
# We need to notify all pending users if there is approve sequence
if tier_reviews and any(review.approve_sequence for review in tier_reviews):
reviews_to_notify = self.review_ids.filtered(
lambda r: r.status == "pending" and r.definition_id.notify_on_accepted
)
# If there are approve sequence, only the following should be
# considered to notify
if reviews_to_notify and any(
review.approve_sequence for review in reviews_to_notify
):
reviews_to_notify = reviews_to_notify.filtered(
lambda x: x.approve_sequence
)[0]
if reviews_to_notify:
subscribe = "message_subscribe"
if hasattr(self, subscribe):
getattr(self, subscribe)(
partner_ids=reviews_to_notify.mapped("reviewer_ids")
.mapped("partner_id")
.ids
.ids,
subtype_ids=self.env.ref(
self._get_accepted_notification_subtype()
).ids,
)
for review in reviews_to_notify:
rec = self.env[review.model].browse(review.res_id)
Expand Down Expand Up @@ -600,13 +616,29 @@
reviews_to_notify = user_reviews.filtered(
lambda r: r.definition_id.notify_on_rejected
)
# We need to notify all pending users if there is approve sequence
if tier_reviews and any(review.approve_sequence for review in tier_reviews):
reviews_to_notify = self.review_ids.filtered(

Check warning on line 621 in base_tier_validation/models/tier_validation.py

View check run for this annotation

Codecov / codecov/patch

base_tier_validation/models/tier_validation.py#L621

Added line #L621 was not covered by tests
lambda r: r.status == "pending" and r.definition_id.notify_on_rejected
)
# If there are approve sequence, only the following should be
# considered to notify
if reviews_to_notify and any(
review.approve_sequence for review in reviews_to_notify
):
reviews_to_notify = reviews_to_notify.filtered(

Check warning on line 629 in base_tier_validation/models/tier_validation.py

View check run for this annotation

Codecov / codecov/patch

base_tier_validation/models/tier_validation.py#L629

Added line #L629 was not covered by tests
lambda x: x.approve_sequence
)[0]
if reviews_to_notify:
subscribe = "message_subscribe"
if hasattr(self, subscribe):
getattr(self, subscribe)(
partner_ids=reviews_to_notify.mapped("reviewer_ids")
.mapped("partner_id")
.ids
.ids,
subtype_ids=self.env.ref(
self._get_rejected_notification_subtype()
).ids,
)
for review in reviews_to_notify:
rec = self.env[review.model].browse(review.res_id)
Expand All @@ -626,7 +658,10 @@
# Subscribe reviewers and notify
if len(users_to_notify) > 0:
getattr(rec, subscribe)(
partner_ids=users_to_notify.mapped("partner_id").ids
partner_ids=users_to_notify.mapped("partner_id").ids,
subtype_ids=self.env.ref(
self._get_requested_notification_subtype()
).ids,
)
getattr(rec, post)(
subtype_xmlid=self._get_requested_notification_subtype(),
Expand Down Expand Up @@ -716,7 +751,12 @@
lambda r: r.definition_id.notify_on_restarted
)
if hasattr(self, subscribe):
getattr(self, subscribe)(partner_ids=partners_to_notify_ids)
getattr(self, subscribe)(
partner_ids=partners_to_notify_ids,
subtype_ids=self.env.ref(
self._get_restarted_notification_subtype()
).ids,
)
rec._notify_restarted_review()

def reevaluate_reviews(self):
Expand Down
1 change: 0 additions & 1 deletion base_tier_validation/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import common
from . import test_tier_validation
from . import test_tier_validation_reminder
87 changes: 87 additions & 0 deletions base_tier_validation/tests/test_tier_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,93 @@ def test_29_request_validation_same_company(self):

self.assertEqual(len(reviews), 2)

def test_30_request_validation(self):
# Create new test record
test_record = self.test_model.create({"test_field": 2.5})
# Create tier definitions for both tester models
self.tier_definition.write(
{
"approve_sequence": True,
"notify_on_create": True,
}
)
def_2 = self.tier_def_obj.create(
{
"model_id": self.tester_model.id,
"review_type": "individual",
"reviewer_id": self.test_user_2.id,
"sequence": 20,
"approve_sequence": True,
"notify_on_accepted": True,
}
)
def_3 = self.tier_def_obj.create(
{
"model_id": self.tester_model.id,
"review_type": "individual",
"reviewer_id": self.test_user_3_multi_company.id,
"sequence": 10,
"approve_sequence": True,
"notify_on_accepted": True,
}
)
mt_tier_validation_requested = self.env.ref(
"base_tier_validation.mt_tier_validation_requested"
)
mt_tier_validation_accepted = self.env.ref(
"base_tier_validation.mt_tier_validation_accepted"
)
test_record.request_validation()
review_1 = test_record.review_ids.filtered(
lambda x: x.definition_id == self.tier_definition
)
self.assertEqual(review_1.status, "pending")
review_2 = test_record.review_ids.filtered(lambda x: x.definition_id == def_2)
self.assertEqual(review_2.status, "pending")
review_3 = test_record.review_ids.filtered(lambda x: x.definition_id == def_3)
self.assertEqual(review_3.status, "pending")
followers = test_record.message_follower_ids
self.assertIn(self.test_user_1.partner_id, followers.mapped("partner_id"))
follower_1 = followers.filtered(
lambda x: x.partner_id == self.test_user_1.partner_id
)
self.assertIn(mt_tier_validation_requested, follower_1.subtype_ids)
self.assertNotIn(mt_tier_validation_accepted, follower_1.subtype_ids)
self.assertNotIn(self.test_user_2.partner_id, followers.mapped("partner_id"))
self.assertNotIn(
self.test_user_3_multi_company.partner_id, followers.mapped("partner_id")
)
test_record.with_user(self.test_user_1).validate_tier()
self.assertEqual(review_1.status, "approved")
self.assertEqual(review_2.status, "pending")
self.assertEqual(review_3.status, "pending")
followers = test_record.message_follower_ids
self.assertIn(self.test_user_1.partner_id, followers.mapped("partner_id"))
self.assertIn(self.test_user_2.partner_id, followers.mapped("partner_id"))
follower_2 = followers.filtered(
lambda x: x.partner_id == self.test_user_2.partner_id
)
self.assertNotIn(mt_tier_validation_requested, follower_2.subtype_ids)
self.assertIn(mt_tier_validation_accepted, follower_2.subtype_ids)
self.assertNotIn(
self.test_user_3_multi_company.partner_id, followers.mapped("partner_id")
)
test_record.with_user(self.test_user_2).validate_tier()
self.assertEqual(review_1.status, "approved")
self.assertEqual(review_2.status, "approved")
self.assertEqual(review_3.status, "pending")
followers = test_record.message_follower_ids
self.assertIn(self.test_user_1.partner_id, followers.mapped("partner_id"))
self.assertIn(self.test_user_2.partner_id, followers.mapped("partner_id"))
self.assertIn(
self.test_user_3_multi_company.partner_id, followers.mapped("partner_id")
)
follower_3 = followers.filtered(
lambda x: x.partner_id == self.test_user_3_multi_company.partner_id
)
self.assertNotIn(mt_tier_validation_requested, follower_3.subtype_ids)
self.assertIn(mt_tier_validation_accepted, follower_3.subtype_ids)


@tagged("at_install")
class TierTierValidationView(CommonTierValidation):
Expand Down