diff --git a/base_tier_validation/README.rst b/base_tier_validation/README.rst index 1071e4531..fdba1c441 100644 --- a/base_tier_validation/README.rst +++ b/base_tier_validation/README.rst @@ -142,6 +142,21 @@ UI improvement: ``to_validate_message`` Html field, which was previously defined on the model but never rendered. +19.0.1.0.3 (2026-05-13) +----------------------- + +Improvements: + +- ``notify_on_pending`` chatter body now names the assignee(s) so the + recipient can tell at a glance that the message is for them. Reuses + ``tier.review.todo_by`` so every review type (individual user, group, + ``res.users`` / ``res.groups`` field) is handled uniformly. +- ``notify_on_pending`` chatter body now attributes the request to + ``review.requested_by`` (the user who actually pressed *Request + Validation*) instead of ``env.user``. On second-and-later tier + promotions ``env.user`` is the previous-tier approver, which was the + wrong person to credit. + 19.0.1.0.1 (2026-05-12) ----------------------- diff --git a/base_tier_validation/models/tier_validation.py b/base_tier_validation/models/tier_validation.py index 782cca05d..e2ee8de9d 100644 --- a/base_tier_validation/models/tier_validation.py +++ b/base_tier_validation/models/tier_validation.py @@ -746,8 +746,34 @@ def _notify_created_review_body(self): self.env.user.name, ) - def _notify_requested_review_body(self): - return self.env._("A review has been requested by %s.", self.env.user.name) + def _notify_requested_review_body(self, tier_reviews=None): + """Chatter body for a tier reaching ``pending``. + + Sources the requester from the review's ``requested_by`` rather + than ``env.user`` -- on second-and-later tier promotions + ``env.user`` is the previous-tier *approver*, which is the wrong + person to attribute the request to. + + Names the assignee(s) in the body so the recipient sees at a + glance that the message is meant for them (chatter notifications + do not render the "Notified to" pill, so the body has to carry + that information itself). Reuses ``tier.review.todo_by`` so the + wording is consistent with the Reviews table and handles every + review type out of the box -- individual user, group, or field. + """ + if tier_reviews: + requester = tier_reviews[:1].requested_by or self.env.user + assignees = ", ".join( + filter(None, tier_reviews.mapped("todo_by")) + ) or self.env._("the assigned reviewer") + return self.env._( + "Review pending for %(assignees)s, requested by %(requester)s.", + assignees=assignees, + requester=requester.display_name, + ) + return self.env._( + "A review has been requested by %s.", self.env.user.display_name + ) def _notify_review_requested(self, tier_reviews): """method to notify when tier validation is created""" @@ -980,7 +1006,7 @@ def _notify_review_available(self, tier_reviews): ) rec.message_post( subtype_xmlid=self._get_requested_notification_subtype(), - body=rec._notify_requested_review_body(), + body=rec._notify_requested_review_body(tier_reviews), ) diff --git a/base_tier_validation/readme/HISTORY.md b/base_tier_validation/readme/HISTORY.md index d0d5ab671..a186210ee 100644 --- a/base_tier_validation/readme/HISTORY.md +++ b/base_tier_validation/readme/HISTORY.md @@ -15,6 +15,20 @@ UI improvement: field, which was previously defined on the model but never rendered. +## 19.0.1.0.3 (2026-05-13) + +Improvements: + +- ``notify_on_pending`` chatter body now names the assignee(s) so the + recipient can tell at a glance that the message is for them. Reuses + ``tier.review.todo_by`` so every review type (individual user, + group, ``res.users`` / ``res.groups`` field) is handled uniformly. +- ``notify_on_pending`` chatter body now attributes the request to + ``review.requested_by`` (the user who actually pressed *Request + Validation*) instead of ``env.user``. On second-and-later tier + promotions ``env.user`` is the previous-tier approver, which was the + wrong person to credit. + ## 19.0.1.0.1 (2026-05-12) Fixes: diff --git a/base_tier_validation/static/description/index.html b/base_tier_validation/static/description/index.html index c51bc4a0c..e98a4056a 100644 --- a/base_tier_validation/static/description/index.html +++ b/base_tier_validation/static/description/index.html @@ -399,30 +399,31 @@

Base Tier Validation

  • Known issues / Roadmap
  • Changelog
  • -
  • Bug Tracker
  • -
  • Credits @@ -508,7 +509,22 @@

    19.0.1.0.4 (2026-05-13)

    -

    19.0.1.0.1 (2026-05-12)

    +

    19.0.1.0.3 (2026-05-13)

    +

    Improvements:

    + +
    +
    +

    19.0.1.0.1 (2026-05-12)

    Fixes:

    -
    -

    17.0.1.0.0 (2024-01-10)

    +
    +

    17.0.1.0.0 (2024-01-10)

    Migrated to Odoo 17. Merged module with tier_validation_waiting. To support sending messages in a validation sequence when it is their turn to validate.

    -
    -

    14.0.1.0.0 (2020-11-19)

    +
    +

    14.0.1.0.0 (2020-11-19)

    Migrated to Odoo 14.

    -
    -

    13.0.1.2.2 (2020-08-30)

    +
    +

    13.0.1.2.2 (2020-08-30)

    Fixes:

    • When using approve_sequence option in any tier.definition there can be @@ -550,84 +566,84 @@

      13.0.1.2.2 (2020-08-30)

      sequence, but also other sequence for the same approver
    -
    -

    12.0.3.3.1 (2019-12-02)

    +
    +

    12.0.3.3.1 (2019-12-02)

    Fixes:

    • Show comment on Reviews Table.
    • Edit notification with approve_sequence.
    -
    -

    12.0.3.3.0 (2019-11-27)

    +
    +

    12.0.3.3.0 (2019-11-27)

    New features:

    • Add comment on Reviews Table.
    • Approve by sequence.
    -
    -

    12.0.3.2.1 (2019-11-26)

    +
    +

    12.0.3.2.1 (2019-11-26)

    Fixes:

    • Remove message_subscribe_users
    -
    -

    12.0.3.2.0 (2019-11-25)

    +
    +

    12.0.3.2.0 (2019-11-25)

    New features:

    • Notify reviewers
    -
    -

    12.0.3.1.0 (2019-07-08)

    +
    +

    12.0.3.1.0 (2019-07-08)

    Fixes:

    • Singleton error
    -
    -

    12.0.3.0.0 (2019-12-02)

    +
    +

    12.0.3.0.0 (2019-12-02)

    Fixes:

    • Edit Reviews Table
    -
    -

    12.0.2.1.0 (2019-05-29)

    +
    +

    12.0.2.1.0 (2019-05-29)

    Fixes:

    • Edit drop-down style width and position
    -
    -

    12.0.2.0.0 (2019-05-28)

    +
    +

    12.0.2.0.0 (2019-05-28)

    New features:

    • Pass parameters as functions.
    • Add Systray.
    -
    -

    12.0.1.0.0 (2019-02-18)

    +
    +

    12.0.1.0.0 (2019-02-18)

    Migrated to Odoo 12.

    -
    -

    11.0.1.0.0 (2018-05-09)

    +
    +

    11.0.1.0.0 (2018-05-09)

    Migrated to Odoo 11.

    -
    -

    10.0.1.0.0 (2018-03-26)

    +
    +

    10.0.1.0.0 (2018-03-26)

    Migrated to Odoo 10.

    -
    -

    Bug Tracker

    +

    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 @@ -635,15 +651,15 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • ForgeFlow
    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association diff --git a/base_tier_validation/tests/test_tier_validation.py b/base_tier_validation/tests/test_tier_validation.py index 63f11dd09..b27c300c0 100644 --- a/base_tier_validation/tests/test_tier_validation.py +++ b/base_tier_validation/tests/test_tier_validation.py @@ -727,6 +727,12 @@ def test_19a_notify_on_pending_sequence_negative(self): # subscribed yet and must not have been notified. self.assertEqual(len(test_record.message_ids), 1) first_message = test_record.message_ids + # The body must name the assignee (so the recipient sees at a glance + # that the message is for them, since chatter does not render the + # "Notified to" pill for system notifications) and attribute the + # request to the original requester. + self.assertIn(review_first.todo_by, first_message.body) + self.assertIn(self.env.user.display_name, first_message.body) followers = test_record.message_follower_ids self.assertIn(self.test_user_1.partner_id, followers.mapped("partner_id")) self.assertNotIn( @@ -756,6 +762,20 @@ def test_19a_notify_on_pending_sequence_negative(self): new_messages.mapped("notified_partner_ids"), "Second-tier reviewer must be notified once promoted to pending.", ) + # Regression guard for the attribution bug: ``env.user`` at second- + # tier promotion time is the tier-1 approver (``test_user_1``), but + # the body must attribute the request to the original requester + # (the env user when ``request_validation`` was called). The body + # must also name the second-tier assignee. + second_body = new_messages[0].body + self.assertIn(review_second.todo_by, second_body) + self.assertIn(self.env.user.display_name, second_body) + self.assertNotIn( + self.test_user_1.display_name, + second_body, + "Second-tier message must not attribute the request to the " + "tier-1 approver -- that's the wrong person.", + ) def test_19b_notify_review_available_no_op_when_no_users(self): """``_notify_review_available`` must short-circuit (no follower @@ -848,8 +868,12 @@ def test_20_no_sequence(self): review_1.invalidate_model() self.assertTrue(review_1.status == "pending") msg2 = test_record2.message_ids[0].body - request = test_record2._notify_requested_review_body() + # The promotion body now carries the assignee + the original + # requester (sourced from ``review.requested_by``, not env.user). + request = test_record2._notify_requested_review_body(review_1) self.assertIn(request, msg2) + self.assertIn(review_1.todo_by, msg2) + self.assertIn(review_1.requested_by.display_name, msg2) def test_21_notify_on_create(self): # notify on create