From 6232c834630838d0f2698c92a1645cb06b0b31e9 Mon Sep 17 00:00:00 2001 From: bosd Date: Wed, 10 Jan 2024 18:38:00 +0100 Subject: [PATCH 1/2] [IMP] base_tier_validation: Merge with base_tier_validation_waiting --- base_tier_validation/README.rst | 14 +++ base_tier_validation/__manifest__.py | 2 +- .../models/tier_definition.py | 7 ++ base_tier_validation/models/tier_review.py | 27 +++- .../models/tier_validation.py | 69 +++++++++-- base_tier_validation/readme/CONFIGURE.md | 2 + base_tier_validation/readme/CONTRIBUTORS.md | 2 + base_tier_validation/readme/HISTORY.md | 6 + .../static/description/index.html | 116 ++++++++++-------- base_tier_validation/tests/common.py | 44 ++++++- .../tests/test_tier_validation.py | 85 ++++++++++--- .../views/tier_definition_view.xml | 1 + 12 files changed, 292 insertions(+), 83 deletions(-) diff --git a/base_tier_validation/README.rst b/base_tier_validation/README.rst index fc8c351ce9..d8a84e945e 100644 --- a/base_tier_validation/README.rst +++ b/base_tier_validation/README.rst @@ -62,6 +62,10 @@ To configure this module, you need to: - If check *Notify Reviewers on Creation*, all possible reviewers will be notified by email when this definition is triggered. +- If check *Notify reviewers on reaching pending* if you want to send a + notification when pending status is reached. This is usefull in a + approve by sequence scenario to only notify reviewers when it is + their turn in the sequence. - If check *Comment*, reviewers can comment after click Validate or Reject. - If check *Approve by sequence*, reviewers is forced to review by @@ -96,6 +100,13 @@ improvement will be very valuable. Changelog ========= +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) ----------------------- @@ -206,6 +217,7 @@ Credits Authors ------- +* brain-tec AG * ForgeFlow Contributors @@ -219,6 +231,8 @@ Contributors - Kitti U. - Saran Lim. - Carlos Lopez +- Javier Colmeiro +- bosd Maintainers ----------- diff --git a/base_tier_validation/__manifest__.py b/base_tier_validation/__manifest__.py index 2cb64df90c..b60b9b0822 100644 --- a/base_tier_validation/__manifest__.py +++ b/base_tier_validation/__manifest__.py @@ -8,7 +8,7 @@ "maintainers": ["LoisRForgeFlow"], "category": "Tools", "website": "https://github.com/OCA/server-ux", - "author": "ForgeFlow, Odoo Community Association (OCA)", + "author": "brain-tec AG, ForgeFlow, Odoo Community Association (OCA)", "license": "AGPL-3", "application": False, "installable": True, diff --git a/base_tier_validation/models/tier_definition.py b/base_tier_validation/models/tier_definition.py index df9c930d68..533608cec1 100644 --- a/base_tier_validation/models/tier_definition.py +++ b/base_tier_validation/models/tier_definition.py @@ -67,6 +67,13 @@ def _get_tier_validation_model_names(self): help="If set, all possible reviewers will be notified by email when " "this definition is triggered.", ) + notify_on_pending = fields.Boolean( + string="Notify Reviewers on reaching Pending", + help="If set, all possible reviewers will be notified by email when " + "this status is reached." + "Usefull in an Approve by sequence scenario. " + "An notification request to review is sent out when it's their turn to review.", + ) has_comment = fields.Boolean(string="Comment", default=False) approve_sequence = fields.Boolean( string="Approve by sequence", diff --git a/base_tier_validation/models/tier_review.py b/base_tier_validation/models/tier_review.py index 8d72c527ea..07cc0e6e94 100644 --- a/base_tier_validation/models/tier_review.py +++ b/base_tier_validation/models/tier_review.py @@ -13,12 +13,13 @@ class TierReview(models.Model): name = fields.Char(related="definition_id.name", readonly=True) status = fields.Selection( - selection=[ + [ + ("waiting", "Waiting"), ("pending", "Pending"), ("rejected", "Rejected"), ("approved", "Approved"), ], - default="pending", + default="waiting", ) model = fields.Char(string="Related Document Model", index=True) res_id = fields.Integer(string="Related Document ID", index=True) @@ -77,11 +78,26 @@ def _compute_reviewed_formated_date(self): @api.depends("definition_id.approve_sequence") def _compute_can_review(self): + reviews = self.filtered(lambda rev: rev.status in ["waiting", "pending"]) + if reviews: + # get minimum sequence of all to prevent jumps + next_seq = min(reviews.mapped("sequence")) + for record in reviews: + # if approve by sequence, check sequence has been reached + if record.approve_sequence: + if record.sequence == next_seq: + record.status = "pending" + # if there is no approval sequence go directly to pending state + elif not record.approve_sequence: + record.status = "pending" + if record.status == "pending": + if record.definition_id.notify_on_pending: + record._notify_pending_status(record) for record in self: record.can_review = record._can_review_value() def _can_review_value(self): - if self.status != "pending": + if self.status not in ("pending", "waiting"): return False if not self.approve_sequence: return True @@ -126,3 +142,8 @@ def _get_reviewers(self): if not reviewer_field or not reviewer_field._name == "res.users": raise ValidationError(_("There are no res.users in the selected field")) return reviewer_field + + def _notify_pending_status(self, review_ids): + """Method to call and reuse abstract notification method""" + resource = self.env[self.model].browse(self.res_id) + resource._notify_review_available(review_ids) diff --git a/base_tier_validation/models/tier_validation.py b/base_tier_validation/models/tier_validation.py index f3be022c2e..a4bd36cd6c 100644 --- a/base_tier_validation/models/tier_validation.py +++ b/base_tier_validation/models/tier_validation.py @@ -22,8 +22,6 @@ class TierValidation(models.AbstractModel): _state_to = ["confirmed"] _cancel_state = "cancel" - # TODO: step by step validation? - review_ids = fields.One2many( comodel_name="tier.review", inverse_name="res_id", @@ -47,6 +45,7 @@ class TierValidation(models.AbstractModel): validation_status = fields.Selection( selection=[ ("no", "Without validation"), + ("waiting", "Waiting"), ("pending", "Pending"), ("rejected", "Rejected"), ("validated", "Validated"), @@ -70,12 +69,15 @@ class TierValidation(models.AbstractModel): def _compute_has_comment(self): for rec in self: has_comment = rec.review_ids.filtered( - lambda r: r.status == "pending" and (self.env.user in r.reviewer_ids) + lambda r: r.status in ("waiting", "pending") + and (self.env.user in r.reviewer_ids) ).mapped("has_comment") rec.has_comment = True in has_comment def _get_sequences_to_approve(self, user): - all_reviews = self.review_ids.filtered(lambda r: r.status == "pending") + all_reviews = self.review_ids.filtered( + lambda r: r.status in ("waiting", "pending") + ) my_reviews = all_reviews.filtered(lambda r: user in r.reviewer_ids) # Include all my_reviews with approve_sequence = False sequences = my_reviews.filtered(lambda r: not r.approve_sequence).mapped( @@ -98,7 +100,7 @@ def _compute_can_review(self): def _search_can_review(self, operator, value): domain = [ ("review_ids.reviewer_ids", "=", self.env.user.id), - ("review_ids.status", "=", "pending"), + ("review_ids.status", "in", ["pending", "waiting"]), ("review_ids.can_review", "=", True), ("rejected", "=", False), ] @@ -111,7 +113,7 @@ def _search_can_review(self, operator, value): def _compute_reviewer_ids(self): for rec in self: rec.reviewer_ids = rec.review_ids.filtered( - lambda r: r.status == "pending" + lambda r: r.status in ("waiting", "pending") ).mapped("reviewer_ids") @api.model @@ -145,7 +147,6 @@ def _search_reviewer_ids(self, operator, value): ("model", "=", self._name), ("reviewer_ids", operator, value), ("can_review", "=", True), - ("status", "=", "pending"), ] ) return [("id", model_operator, list(set(reviews.mapped("res_id"))))] @@ -192,6 +193,12 @@ def _compute_validation_status(self): and any(item.review_ids.filtered(lambda x: x.status == "pending")) ): item.validation_status = "pending" + elif ( + not item.validated + and not item.rejected + and any(item.review_ids.filtered(lambda x: x.status == "waiting")) + ): + item.validation_status = "waiting" else: item.validation_status = "no" @@ -320,6 +327,20 @@ def _check_state_conditions(self, vals): def _validate_tier(self, tiers=False): self.ensure_one() tier_reviews = tiers or self.review_ids + waiting_reviews = tier_reviews.filtered( + lambda r: r.status == "waiting" + or r.approve_sequence_bypass + and (self.env.user in r.reviewer_ids) + ) + if waiting_reviews: + waiting_reviews.write( + { + "status": "pending", + "done_by": self.env.user.id, + "reviewed_date": fields.Datetime.now(), + } + ) + user_reviews = tier_reviews.filtered( lambda r: r.status == "pending" and (self.env.user in r.reviewer_ids) ) @@ -427,7 +448,8 @@ def _rejected_tier(self, tiers=False): self.ensure_one() tier_reviews = tiers or self.review_ids user_reviews = tier_reviews.filtered( - lambda r: r.status == "pending" and (self.env.user in r.reviewer_ids) + lambda r: r.status in ("waiting", "pending") + and (self.env.user in r.reviewer_ids) ) user_reviews.write( { @@ -440,10 +462,16 @@ def _rejected_tier(self, tiers=False): rec = self.env[review.model].browse(review.res_id) rec._notify_rejected_review() + def _notify_created_review_body(self): + return _("A record to be reviewed has been created by %s.") % ( + self.env.user.name + ) + def _notify_requested_review_body(self): return _("A review has been requested by %s.") % (self.env.user.name) def _notify_review_requested(self, tier_reviews): + """method to notify when tier validation is created""" subscribe = "message_subscribe" post = "message_post" if hasattr(self, post) and hasattr(self, subscribe): @@ -459,7 +487,7 @@ def _notify_review_requested(self, tier_reviews): ) getattr(rec, post)( subtype_xmlid=self._get_requested_notification_subtype(), - body=rec._notify_requested_review_body(), + body=rec._notify_created_review_body(), ) def _prepare_tier_review_vals(self, definition, sequence): @@ -509,7 +537,9 @@ def restart_validation(self): for rec in self: if getattr(rec, self._state_field) in self._state_from: to_update_counter = ( - rec.mapped("review_ids").filtered(lambda a: a.status == "pending") + rec.mapped("review_ids").filtered( + lambda a: a.status in ("waiting", "pending") + ) and True or False ) @@ -594,3 +624,22 @@ def get_view(self, view_id=None, view_type="form", **options): res["arch"] = etree.tostring(doc) res["models"] = frozendict(all_models) return res + + def _notify_review_available(self, tier_reviews): + """method to notify when reaching pending""" + subscribe = "message_subscribe" + post = "message_post" + if hasattr(self, post) and hasattr(self, subscribe): + for rec in self.sudo(): + users_to_notify = tier_reviews.filtered( + lambda r, x=rec: r.definition_id.notify_on_pending + and r.res_id == x.id + ).mapped("reviewer_ids") + # Subscribe reviewers and notify + getattr(rec, subscribe)( + partner_ids=users_to_notify.mapped("partner_id").ids + ) + getattr(rec, post)( + subtype_xmlid=self._get_requested_notification_subtype(), + body=rec._notify_requested_review_body(), + ) diff --git a/base_tier_validation/readme/CONFIGURE.md b/base_tier_validation/readme/CONFIGURE.md index 03e909fe0b..e7ba817dcf 100644 --- a/base_tier_validation/readme/CONFIGURE.md +++ b/base_tier_validation/readme/CONFIGURE.md @@ -9,6 +9,8 @@ To configure this module, you need to: - If check *Notify Reviewers on Creation*, all possible reviewers will be notified by email when this definition is triggered. +- If check *Notify reviewers on reaching pending* if you want to send a notification when pending status is reached. + This is usefull in a approve by sequence scenario to only notify reviewers when it is their turn in the sequence. - If check *Comment*, reviewers can comment after click Validate or Reject. - If check *Approve by sequence*, reviewers is forced to review by diff --git a/base_tier_validation/readme/CONTRIBUTORS.md b/base_tier_validation/readme/CONTRIBUTORS.md index 7dbba4a06f..7caebcb960 100644 --- a/base_tier_validation/readme/CONTRIBUTORS.md +++ b/base_tier_validation/readme/CONTRIBUTORS.md @@ -6,3 +6,5 @@ - Kitti U. \<\> - Saran Lim. \<\> - Carlos Lopez \<\> +- Javier Colmeiro \<\> +- bosd diff --git a/base_tier_validation/readme/HISTORY.md b/base_tier_validation/readme/HISTORY.md index 5d17c0dd6a..3d438da687 100644 --- a/base_tier_validation/readme/HISTORY.md +++ b/base_tier_validation/readme/HISTORY.md @@ -1,3 +1,9 @@ +## 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) Migrated to Odoo 14. diff --git a/base_tier_validation/static/description/index.html b/base_tier_validation/static/description/index.html index f5a8760652..c653be0ea3 100644 --- a/base_tier_validation/static/description/index.html +++ b/base_tier_validation/static/description/index.html @@ -387,27 +387,28 @@

Base Tier Validation

  • Configuration
  • Known issues / Roadmap
  • Changelog
  • -
  • Bug Tracker
  • -
  • Credits @@ -424,6 +425,10 @@

    Configuration

    • If check Notify Reviewers on Creation, all possible reviewers will be notified by email when this definition is triggered.
    • +
    • If check Notify reviewers on reaching pending if you want to send a +notification when pending status is reached. This is usefull in a +approve by sequence scenario to only notify reviewers when it is +their turn in the sequence.
    • If check Comment, reviewers can comment after click Validate or Reject.
    • If check Approve by sequence, reviewers is forced to review by @@ -456,11 +461,17 @@

      Known issues / Roadmap

      Changelog

      -

      14.0.1.0.0 (2020-11-19)

      -

      Migrated to Odoo 14.

      +

      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.

      +
      +

      13.0.1.2.2 (2020-08-30)

      Fixes:

      • When using approve_sequence option in any tier.definition there can @@ -469,84 +480,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 @@ -554,15 +565,16 @@

      Bug Tracker

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

      -

      Credits

      +

      Credits

      -

      Authors

      +

      Authors

        +
      • brain-tec AG
      • ForgeFlow
      -

      Contributors

      +

      Contributors

      -

      Maintainers

      +

      Maintainers

      This module is maintained by the OCA.

      Odoo Community Association

      OCA, or the Odoo Community Association, is a nonprofit organization whose diff --git a/base_tier_validation/tests/common.py b/base_tier_validation/tests/common.py index 586e010c23..a72932d807 100644 --- a/base_tier_validation/tests/common.py +++ b/base_tier_validation/tests/common.py @@ -78,13 +78,51 @@ def setUpClass(cls): "model_id": cls.tester_model.id, "review_type": "individual", "reviewer_id": cls.test_user_1.id, - "definition_domain": "[('test_field', '>', 1.0)]", + "definition_domain": "[('test_field', '=', 1.0)]", "sequence": 30, } ) - cls.test_record = cls.test_model.create({"test_field": 2.5}) - cls.test_record_2 = cls.test_model_2.create({"test_field": 2.5}) + cls.test_record = cls.test_model.create({"test_field": 1.0}) + cls.test_record_2 = cls.test_model_2.create({"test_field": 1.0}) + + cls.tier_def_obj.create( + { + "model_id": cls.tester_model.id, + "review_type": "individual", + "reviewer_id": cls.test_user_1.id, + "definition_domain": "[('test_field', '>', 3.0)]", + "approve_sequence": True, + "notify_on_pending": False, + "sequence": 20, + "name": "Definition for test 19 - sequence - user 1", + } + ) + cls.tier_def_obj.create( + { + "model_id": cls.tester_model.id, + "review_type": "individual", + "reviewer_id": cls.test_user_2.id, + "definition_domain": "[('test_field', '>', 3.0)]", + "approve_sequence": True, + "notify_on_pending": True, + "sequence": 10, + "name": "Definition for test 19 - sequence - user 2", + } + ) + # Create definition for test 20 + cls.tier_def_obj.create( + { + "model_id": cls.tester_model.id, + "review_type": "individual", + "reviewer_id": cls.test_user_1.id, + "definition_domain": "[('test_field', '=', 0.9)]", + "approve_sequence": False, + "notify_on_pending": True, + "sequence": 10, + "name": "Definition for test 20 - no sequence - user 1 - no sequence", + } + ) @classmethod def tearDownClass(cls): diff --git a/base_tier_validation/tests/test_tier_validation.py b/base_tier_validation/tests/test_tier_validation.py index e5f4f65969..3daa872520 100644 --- a/base_tier_validation/tests/test_tier_validation.py +++ b/base_tier_validation/tests/test_tier_validation.py @@ -1,4 +1,5 @@ # Copyright 2018-19 ForgeFlow S.L. (https://www.forgeflow.com) +# Copyright (c) 2022 brain-tec AG (https://braintec.com) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). from lxml import etree @@ -73,6 +74,7 @@ def test_07_search_reviewers(self): self.assertTrue(reviews) record = self.test_record.with_user(self.test_user_1.id) record.invalidate_model() + record.invalidate_recordset() self.assertIn(self.test_user_1, record.reviewer_ids) res = self.test_model.search([("reviewer_ids", "in", self.test_user_1.id)]) self.assertTrue(res) @@ -291,17 +293,23 @@ def test_12_approve_sequence_same_user(self): self.assertTrue(record1.can_review) # Validation will be all by sequence self.assertEqual( - 3, len(record1.review_ids.filtered(lambda x: x.status == "pending")) + 2, len(record1.review_ids.filtered(lambda x: x.status == "waiting")) ) - record1.validate_tier() self.assertEqual( - 2, len(record1.review_ids.filtered(lambda x: x.status == "pending")) + 0, len(record1.review_ids.filtered(lambda x: x.status == "pending")) ) record1.validate_tier() + self.assertEqual( + 0, len(record1.review_ids.filtered(lambda x: x.status == "waiting")) + ) self.assertEqual( 1, len(record1.review_ids.filtered(lambda x: x.status == "pending")) ) record1.validate_tier() + self.assertEqual( + 0, len(record1.review_ids.filtered(lambda x: x.status == "waiting")) + ) + record1.validate_tier() self.assertEqual( 0, len(record1.review_ids.filtered(lambda x: x.status == "pending")) ) @@ -344,12 +352,18 @@ def test_12_approve_sequence_same_user_bypassed(self): self.assertTrue(record1.can_review) # When the first tier is validated, all the rest will be approved. self.assertEqual( - 3, len(record1.review_ids.filtered(lambda x: x.status == "pending")) + 2, len(record1.review_ids.filtered(lambda x: x.status == "waiting")) + ) + self.assertEqual( + 0, len(record1.review_ids.filtered(lambda x: x.status == "pending")) ) record1.validate_tier() self.assertEqual( 0, len(record1.review_ids.filtered(lambda x: x.status == "pending")) ) + self.assertEqual( + 0, len(record1.review_ids.filtered(lambda x: x.status == "waiting")) + ) def test_13_onchange_review_type(self): tier_def_id = self.tier_def_obj.create( @@ -413,18 +427,18 @@ def test_15_review_user_count(self): def test_16_review_user_count_on_rejected(self): """If document is rejected, it should always removed from tray""" # Create new test record - test_record = self.test_model.create({"test_field": 2.5}) + test_record3 = self.test_model.create({"test_field": 1.0}) # Create tier definitions self.tier_def_obj.create( { "model_id": self.tester_model.id, "review_type": "individual", "reviewer_id": self.test_user_2.id, - "definition_domain": "[('test_field', '>', 1.0)]", + "definition_domain": "[('test_field', '=', 1.0)]", } ) - test_record.with_user(self.test_user_2).request_validation() - record1 = test_record.with_user(self.test_user_1) + test_record3.with_user(self.test_user_2).request_validation() + record1 = test_record3.with_user(self.test_user_1) record1.invalidate_model() self.assertTrue(record1.can_review) self.assertTrue( @@ -451,13 +465,11 @@ def test_17_search_records_no_validation(self): [("reviewer_ids", "=", False)] ) self.assertEqual(len(records), 1) - self.test_record.with_user(self.test_user_2.id).request_validation() - record = self.test_record.with_user(self.test_user_1.id) - record.invalidate_model() - records = self.env["tier.validation.tester"].search( - [("reviewer_ids", "=", False)] - ) - self.assertEqual(len(records), 0) + review = self.test_record.with_user(self.test_user_2.id).request_validation() + self.assertTrue(review) + self.assertTrue(self.test_user_1.get_reviews({"res_ids": review.ids})) + self.assertTrue(self.test_user_1.review_ids) + self.test_record.with_user(self.test_user_1.id).request_validation() def test_18_test_review_by_res_users_field(self): selected_field = self.env["ir.model.fields"].search( @@ -482,6 +494,49 @@ def test_18_test_review_by_res_users_field(self): self.assertTrue(review) self.assertEqual(review.reviewer_ids, self.test_user_2) + def test_19_waiting_tier(self): + # Create new test record + tier_review_obj = self.env["tier.review"] + test_record = self.test_model.create({"test_field": 3.5}) + # Request validation + review = test_record.request_validation() + + self.assertTrue(review) + # both reviews should be waiting when created + review_1 = tier_review_obj.browse(review.ids[0]) + review_2 = tier_review_obj.browse(review.ids[1]) + self.assertTrue(review_1.status == "waiting") + self.assertTrue(review_2.status == "waiting") + # and then normal workflow will follow... + review_1.invalidate_model() + review_1._compute_can_review() + self.assertTrue(review_1.status == "pending") + # first reviewer does not want notifications + # chatter should be empty + self.assertFalse(test_record.message_ids) + self.assertTrue(review_2.status == "waiting") + record = test_record.with_user(self.test_user_1.id) + record.invalidate_model() + record.validate_tier() + self.assertTrue(review_1.status == "approved") + self.assertTrue(review_2.status == "pending") + + def test_20_no_sequence(self): + # Create new test record + tier_review_obj = self.env["tier.review"] + test_record2 = self.test_model.create({"test_field": 0.9}) + # request validation + review = test_record2.request_validation() + self.assertTrue(review) + review_1 = tier_review_obj.browse(review.ids[0]) + self.assertTrue(review_1.status == "waiting") + review_1.invalidate_model() + review_1._compute_can_review() + self.assertTrue(review_1.status == "pending") + msg2 = test_record2.message_ids[0].body + request = test_record2._notify_requested_review_body() + self.assertIn(request, msg2) + @tagged("at_install") class TierTierValidationView(CommonTierValidation): diff --git a/base_tier_validation/views/tier_definition_view.xml b/base_tier_validation/views/tier_definition_view.xml index 95cb420f06..838332238d 100644 --- a/base_tier_validation/views/tier_definition_view.xml +++ b/base_tier_validation/views/tier_definition_view.xml @@ -99,6 +99,7 @@ + From 395c4a213a8f1be6609bb6ac2794f99961c8ea64 Mon Sep 17 00:00:00 2001 From: bosd Date: Thu, 11 Jan 2024 07:00:14 +0100 Subject: [PATCH 2/2] [IMP] base_tier_validation: review comments Co-authored-by: Carlos Lopez --- base_tier_validation/models/tier_validation.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/base_tier_validation/models/tier_validation.py b/base_tier_validation/models/tier_validation.py index a4bd36cd6c..064adc2047 100644 --- a/base_tier_validation/models/tier_validation.py +++ b/base_tier_validation/models/tier_validation.py @@ -70,7 +70,7 @@ def _compute_has_comment(self): for rec in self: has_comment = rec.review_ids.filtered( lambda r: r.status in ("waiting", "pending") - and (self.env.user in r.reviewer_ids) + and self.env.user in r.reviewer_ids ).mapped("has_comment") rec.has_comment = True in has_comment @@ -330,7 +330,7 @@ def _validate_tier(self, tiers=False): waiting_reviews = tier_reviews.filtered( lambda r: r.status == "waiting" or r.approve_sequence_bypass - and (self.env.user in r.reviewer_ids) + and self.env.user in r.reviewer_ids ) if waiting_reviews: waiting_reviews.write( @@ -449,7 +449,7 @@ def _rejected_tier(self, tiers=False): tier_reviews = tiers or self.review_ids user_reviews = tier_reviews.filtered( lambda r: r.status in ("waiting", "pending") - and (self.env.user in r.reviewer_ids) + and self.env.user in r.reviewer_ids ) user_reviews.write( { @@ -636,10 +636,10 @@ def _notify_review_available(self, tier_reviews): and r.res_id == x.id ).mapped("reviewer_ids") # Subscribe reviewers and notify - getattr(rec, subscribe)( + rec.message_subscribe( partner_ids=users_to_notify.mapped("partner_id").ids ) - getattr(rec, post)( + rec.message_post( subtype_xmlid=self._get_requested_notification_subtype(), body=rec._notify_requested_review_body(), )