Skip to content

Commit

Permalink
[IMP] base_tier_validation: Add subscription mode in tier definition
Browse files Browse the repository at this point in the history
Sometimes we may use Tier Validation for records that are communicating with the customer, and we don't want validators to receive notifications for the entire discussion. We introduce a new field 'Subscription mode' that allows to configure if we only want to receive Tier Validation notifications.
  • Loading branch information
BernatPForgeFlow committed Jul 4, 2024
1 parent 31b4705 commit 057798f
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 70 deletions.
13 changes: 11 additions & 2 deletions base_tier_validation/models/tier_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ def _get_tier_validation_model_names(self):
string="Company",
default=lambda self: self.env.company,
)
subscription_mode = fields.Selection(
[
("standard", "Standard subscription mode"),
("tier_validation", "Subscribe only to Tier Validation notifications"),
],
default="standard",
required=True,
change_default=True,
)
notify_on_create = fields.Boolean(
string="Notify Reviewers on Creation",
help="If set, all possible reviewers will be notified by email when "
Expand All @@ -79,8 +88,8 @@ def _get_tier_validation_model_names(self):
)
notify_on_restarted = fields.Boolean(
string="Notify Reviewers on Restarted",
help="If set, reviewers will be notified by email when a reviews related "
"to this definition are restarted.",
help="If set, reviewers will be notified by email when a review related "
"to this definition is restarted.",
)
has_comment = fields.Boolean(string="Comment", default=False)
approve_sequence = fields.Boolean(
Expand Down
162 changes: 94 additions & 68 deletions base_tier_validation/models/tier_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,20 @@ def _check_state_conditions(self, vals):
and vals.get(self._state_field) in self._state_to
)

def _notify_review_accepted(self, tier_reviews):
subscribe = "message_subscribe"
post = "message_post"
if hasattr(self, post) and hasattr(self, subscribe):
reviews_to_notify = tier_reviews.filtered(
lambda r: r.definition_id.notify_on_accepted
)
if reviews_to_notify:
self._subscribe_review(tier_reviews)
getattr(self.sudo(), post)(
subtype_xmlid=self._get_accepted_notification_subtype(),
body=self._notify_accepted_reviews_body(),
)

def _validate_tier(self, tiers=False):
self.ensure_one()
tier_reviews = tiers or self.review_ids
Expand All @@ -436,20 +450,56 @@ def _validate_tier(self, tiers=False):
"reviewed_date": fields.Datetime.now(),
}
)
reviews_to_notify = user_reviews.filtered(
lambda r: r.definition_id.notify_on_accepted
self._notify_review_accepted(user_reviews)

def _subscribe_review(self, tier_reviews):
subtype_ids = self._get_notification_subtypes(tier_reviews)
partners_to_notify_ids = (
self._get_partners_to_notify(tier_reviews)
if subtype_ids
else tier_reviews.mapped("reviewer_ids.partner_id.id")
)
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
)
for review in reviews_to_notify:
rec = self.env[review.model].browse(review.res_id)
rec._notify_accepted_reviews()
if subtype_ids is None or subtype_ids:
self.message_subscribe(
partner_ids=partners_to_notify_ids,
subtype_ids=subtype_ids,
)

def _get_partners_to_notify(self, tier_reviews):
partner_ids = list(
set(tier_reviews.mapped("reviewer_ids.partner_id.id"))
- set(self.mapped("message_follower_ids.partner_id.id"))
)
return partner_ids

def _get_notification_subtypes(self, tier_reviews):
subtype_ids = self.env["mail.message.subtype"]
default_subscription_mode = tier_reviews.filtered(
lambda x: "standard" in x.definition_id.subscription_mode
)
if default_subscription_mode:
return None
notify_on_create = tier_reviews.filtered(
lambda r: r.definition_id.notify_on_create and r.res_id == self.id
)
if notify_on_create:
subtype_ids += self.env.ref(self._get_requested_notification_subtype())
notify_on_accepted = tier_reviews.filtered(
lambda r: r.definition_id.notify_on_accepted and r.res_id == self.id
)
if notify_on_accepted:
subtype_ids += self.env.ref(self._get_accepted_notification_subtype())

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

View check run for this annotation

Codecov / codecov/patch

base_tier_validation/models/tier_validation.py#L491

Added line #L491 was not covered by tests
notify_on_rejected = tier_reviews.filtered(
lambda r: r.definition_id.notify_on_rejected and r.res_id == self.id
)
if notify_on_rejected:
subtype_ids += self.env.ref(self._get_rejected_notification_subtype())

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

View check run for this annotation

Codecov / codecov/patch

base_tier_validation/models/tier_validation.py#L496

Added line #L496 was not covered by tests
notify_on_restarted = tier_reviews.filtered(
lambda r: r.definition_id.notify_on_restarted and r.res_id == self.id
)
if notify_on_restarted:
subtype_ids += self.env.ref(self._get_restarted_notification_subtype())

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

View check run for this annotation

Codecov / codecov/patch

base_tier_validation/models/tier_validation.py#L501

Added line #L501 was not covered by tests
return subtype_ids.ids

def _get_requested_notification_subtype(self):
return "base_tier_validation.mt_tier_validation_requested"
Expand Down Expand Up @@ -534,14 +584,19 @@ def _notify_rejected_review_body(self):
}
return _("A review was rejected by %s.") % (self.env.user.name)

def _notify_rejected_review(self):
def _notify_rejected_review(self, tier_reviews):
subscribe = "message_subscribe"
post = "message_post"
if hasattr(self, post):
# Notify state change
getattr(self.sudo(), post)(
subtype_xmlid=self._get_rejected_notification_subtype(),
body=self._notify_rejected_review_body(),
if hasattr(self, post) and hasattr(self, subscribe):
reviews_to_notify = tier_reviews.filtered(
lambda r: r.definition_id.notify_on_rejected
)
if reviews_to_notify:
self.sudo()._subscribe_review(tier_reviews)
getattr(self.sudo(), post)(
subtype_xmlid=self._get_rejected_notification_subtype(),
body=self._notify_rejected_review_body(),
)

def _rejected_tier(self, tiers=False):
self.ensure_one()
Expand All @@ -556,21 +611,7 @@ def _rejected_tier(self, tiers=False):
"reviewed_date": fields.Datetime.now(),
}
)

reviews_to_notify = user_reviews.filtered(
lambda r: r.definition_id.notify_on_rejected
)
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
)
for review in reviews_to_notify:
rec = self.env[review.model].browse(review.res_id)
rec._notify_rejected_review()
self._notify_rejected_review(user_reviews)

def _notify_requested_review_body(self):
return _("A review has been requested by %s.") % (self.env.user.name)
Expand All @@ -580,14 +621,11 @@ def _notify_review_requested(self, tier_reviews):
post = "message_post"
if hasattr(self, post) and hasattr(self, subscribe):
for rec in self.sudo():
users_to_notify = tier_reviews.filtered(
lambda r: r.definition_id.notify_on_create and r.res_id == rec.id
).mapped("reviewer_ids")
# Subscribe reviewers and notify
if len(users_to_notify) > 0:
getattr(rec, subscribe)(
partner_ids=users_to_notify.mapped("partner_id").ids
)
reviews_to_notify = tier_reviews.filtered(
lambda r: r.definition_id.notify_on_create
)
if reviews_to_notify:
rec._subscribe_review(tier_reviews)
getattr(rec, post)(
subtype_xmlid=self._get_requested_notification_subtype(),
body=rec._notify_requested_review_body(),
Expand Down Expand Up @@ -629,42 +667,30 @@ def _notify_restarted_review_body(self):
return _("The review has been reset by %s.") % (self.env.user.name)

def _notify_restarted_review(self):
subscribe = "message_subscribe"
post = "message_post"
if hasattr(self, post):
getattr(self.sudo(), post)(
subtype_xmlid=self._get_restarted_notification_subtype(),
body=self._notify_restarted_review_body(),
if hasattr(self, post) and hasattr(self, subscribe):
tier_reviews = self.mapped("review_ids")
reviews_to_notify = tier_reviews.filtered(
lambda r: r.definition_id.notify_on_restarted
)
if reviews_to_notify:
self._subscribe_review(tier_reviews)
getattr(self.sudo(), post)(
subtype_xmlid=self._get_restarted_notification_subtype(),
body=self._notify_restarted_review_body(),
)

def restart_validation(self):
for rec in self:
partners_to_notify_ids = False
if getattr(rec, self._state_field) in self._state_from:
to_update_counter = (
rec.mapped("review_ids").filtered(lambda a: a.status == "pending")
and True
or False
to_update_counter = rec.mapped("review_ids").filtered(
lambda a: a.status == "pending"
)
reviews_to_notify = rec.review_ids.filtered(
lambda r: r.definition_id.notify_on_restarted
)
if reviews_to_notify:
partners_to_notify_ids = (
reviews_to_notify.mapped("reviewer_ids")
.mapped("partner_id")
.ids
)
rec.mapped("review_ids").unlink()
if to_update_counter:
self._update_counter({"review_deleted": True})
if partners_to_notify_ids:
subscribe = "message_subscribe"
reviews_to_notify = rec.review_ids.filtered(
lambda r: r.definition_id.notify_on_restarted
)
if hasattr(self, subscribe):
getattr(self, subscribe)(partner_ids=partners_to_notify_ids)
rec._notify_restarted_review()
rec.mapped("review_ids").unlink()

@api.model
def _update_counter(self, review_counter):
Expand Down
79 changes: 79 additions & 0 deletions base_tier_validation/tests/test_tier_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,85 @@ def test_25_change_field_exception_validation(self):
)
self.assertEqual(self.test_record.test_validation_field, 4)

def test_26_notify_only_tier_validation(self):
tier_definition = self.env["tier.definition"].search([])
tier_definition.write(
{
"subscription_mode": "standard",
"notify_on_create": True,
"notify_on_accepted": False,
"notify_on_rejected": False,
"notify_on_restarted": False,
"review_type": "group",
"reviewer_group_id": self.env.ref("base.group_system").id,
}
)
# notify on create
test_record_1 = self.test_model.create({"test_field": 2.5})
notifications_no_1 = len(
self.env["mail.notification"].search(
[("res_partner_id", "=", self.test_user_1.partner_id.id)]
)
)
test_record_1.request_validation()
notifications_no_2 = len(
self.env["mail.notification"].search(
[("res_partner_id", "=", self.test_user_1.partner_id.id)]
)
)
self.assertEqual(notifications_no_2, notifications_no_1 + 1)

# notify on message post
notifications_no_1 = len(
self.env["mail.notification"].search(
[("res_partner_id", "=", self.test_user_1.partner_id.id)]
)
)
test_record_1.message_post(
body="Message post on test_record.",
subtype_id=self.env.ref("mail.mt_comment").id,
)
notifications_no_2 = len(
self.env["mail.notification"].search(
[("res_partner_id", "=", self.test_user_1.partner_id.id)]
)
)
self.assertEqual(notifications_no_2, notifications_no_1 + 1)

tier_definition.write({"subscription_mode": "tier_validation"})

# notify on create
test_record_2 = self.test_model.create({"test_field": 2.5})
notifications_no_1 = len(
self.env["mail.notification"].search(
[("res_partner_id", "=", self.test_user_1.partner_id.id)]
)
)
test_record_2.request_validation()
notifications_no_2 = len(
self.env["mail.notification"].search(
[("res_partner_id", "=", self.test_user_1.partner_id.id)]
)
)
self.assertEqual(notifications_no_2, notifications_no_1 + 1)

# do not notify on message post
notifications_no_1 = len(
self.env["mail.notification"].search(
[("res_partner_id", "=", self.test_user_1.partner_id.id)]
)
)
test_record_2.message_post(
body="Message post on test_record.",
subtype_id=self.env.ref("mail.mt_comment").id,
)
notifications_no_2 = len(
self.env["mail.notification"].search(
[("res_partner_id", "=", self.test_user_1.partner_id.id)]
)
)
self.assertEqual(notifications_no_2, notifications_no_1)


@tagged("at_install")
class TierTierValidationView(CommonTierValidation):
Expand Down
1 change: 1 addition & 0 deletions base_tier_validation/views/tier_definition_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
<page name="options" string="More Options">
<group name="more_option">
<group name="notify">
<field name="subscription_mode" />
<field name="notify_on_create" />
<field name="notify_on_accepted" />
<field name="notify_on_rejected" />
Expand Down

0 comments on commit 057798f

Please sign in to comment.