diff --git a/base_tier_validation_server_action/README.rst b/base_tier_validation_server_action/README.rst new file mode 100644 index 0000000000..a7c73e1bb1 --- /dev/null +++ b/base_tier_validation_server_action/README.rst @@ -0,0 +1,100 @@ +==================================== +Base Tier Validation - Server Action +==================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:d00b3ef08eaf5700c0470546ab8455b68a36e0b846660fa76f245af7f97dfed0 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fserver--ux-lightgray.png?logo=github + :target: https://github.com/OCA/server-ux/tree/17.0/base_tier_validation_server_action + :alt: OCA/server-ux +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-ux-17-0/server-ux-17-0-base_tier_validation_server_action + :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/server-ux&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module add option to call "Server Action" when a tier definition is +approved or rejected + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +On each Tier Definition + +- Choose server action you want to call as soon this definition is + approved or rejected + +- Select "Auto Validate", if you want this definition to get validated + by cron job based on "if pass condition" criteria, + + - If no user specified, use job's system user to validate + - If 1 user matched as reviewer, use the user to validate + - If > 1 user matched as reviewer, do not auto validate + +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 +------- + +* Ecosoft + +Contributors +------------ + +- Kitti U. + +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. + +.. |maintainer-kittiu| image:: https://github.com/kittiu.png?size=40px + :target: https://github.com/kittiu + :alt: kittiu + +Current `maintainer `__: + +|maintainer-kittiu| + +This module is part of the `OCA/server-ux `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_tier_validation_server_action/__init__.py b/base_tier_validation_server_action/__init__.py new file mode 100644 index 0000000000..31660d6a96 --- /dev/null +++ b/base_tier_validation_server_action/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import models diff --git a/base_tier_validation_server_action/__manifest__.py b/base_tier_validation_server_action/__manifest__.py new file mode 100644 index 0000000000..d006ac9bde --- /dev/null +++ b/base_tier_validation_server_action/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright 2017-19 ForgeFlow S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Base Tier Validation - Server Action", + "summary": "Add option to call server action when a tier is validated", + "version": "17.0.1.0.0", + "category": "Tools", + "website": "https://github.com/OCA/server-ux", + "author": "Ecosoft, Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": ["base_tier_validation"], + "data": [ + "data/cron_data.xml", + "views/tier_definition_view.xml", + ], + "maintainers": ["kittiu"], + "development_status": "Beta", +} diff --git a/base_tier_validation_server_action/data/cron_data.xml b/base_tier_validation_server_action/data/cron_data.xml new file mode 100644 index 0000000000..27256a5a25 --- /dev/null +++ b/base_tier_validation_server_action/data/cron_data.xml @@ -0,0 +1,17 @@ + + + + Automatic Tier Validation + 1 + hours + -1 + + + + model._cron_auto_tier_validation() + code + + diff --git a/base_tier_validation_server_action/i18n/base_tier_validation_server_action.pot b/base_tier_validation_server_action/i18n/base_tier_validation_server_action.pot new file mode 100644 index 0000000000..f929a9a309 --- /dev/null +++ b/base_tier_validation_server_action/i18n/base_tier_validation_server_action.pot @@ -0,0 +1,74 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_tier_validation_server_action +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__auto_validate +msgid "Auto Validate" +msgstr "" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__auto_validate_domain +msgid "Auto Validate Domain" +msgstr "" + +#. module: base_tier_validation_server_action +#: model:ir.actions.server,name:base_tier_validation_server_action.ir_cron_auto_tier_validation_ir_actions_server +#: model:ir.cron,cron_name:base_tier_validation_server_action.ir_cron_auto_tier_validation +msgid "Automatic Tier Validation" +msgstr "" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__server_action_id +msgid "Post Approve Action" +msgstr "" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__rejected_server_action_id +msgid "Post Reject Action" +msgstr "" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,help:base_tier_validation_server_action.field_tier_definition__server_action_id +msgid "Server action triggered as soon as this step is approved" +msgstr "" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,help:base_tier_validation_server_action.field_tier_definition__rejected_server_action_id +msgid "Server action triggered as soon as this step is rejected" +msgstr "" + +#. module: base_tier_validation_server_action +#: model:ir.model,name:base_tier_validation_server_action.model_tier_definition +msgid "Tier Definition" +msgstr "" + +#. module: base_tier_validation_server_action +#: model:ir.model,name:base_tier_validation_server_action.model_tier_validation +msgid "Tier Validation (abstract)" +msgstr "" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,help:base_tier_validation_server_action.field_tier_definition__auto_validate +msgid "" +"Use schedule job to auto validate if condition is met.\n" +"- If no user specified, use job's system user to validate\n" +"- If 1 user matched as reviewer, use the user to validate\n" +"- If > 1 user matched as reviewer, do not auto validate" +msgstr "" + +#. module: base_tier_validation_server_action +#: model_terms:ir.ui.view,arch_db:base_tier_validation_server_action.tier_definition_view_form +msgid "if pass condition" +msgstr "" diff --git a/base_tier_validation_server_action/i18n/es.po b/base_tier_validation_server_action/i18n/es.po new file mode 100644 index 0000000000..011ddd7bb7 --- /dev/null +++ b/base_tier_validation_server_action/i18n/es.po @@ -0,0 +1,102 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_tier_validation_server_action +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-09 15:35+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__auto_validate +msgid "Auto Validate" +msgstr "Auto-validar" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__auto_validate_domain +msgid "Auto Validate Domain" +msgstr "Auto-validar dominio" + +#. module: base_tier_validation_server_action +#: model:ir.actions.server,name:base_tier_validation_server_action.ir_cron_auto_tier_validation_ir_actions_server +#: model:ir.cron,cron_name:base_tier_validation_server_action.ir_cron_auto_tier_validation +#: model:ir.cron,name:base_tier_validation_server_action.ir_cron_auto_tier_validation +msgid "Automatic Tier Validation" +msgstr "Validación Automática de Niveles" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__display_name +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_review__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__id +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_review__id +msgid "ID" +msgstr "ID" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition____last_update +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_review____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__server_action_id +msgid "Post Approve Action" +msgstr "Post Aprobar Acción" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__rejected_server_action_id +msgid "Post Reject Action" +msgstr "Acción Post Rechazo" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,help:base_tier_validation_server_action.field_tier_definition__server_action_id +msgid "Server action triggered as soon as this step is approved" +msgstr "La acción del servidor se activa en cuanto se aprueba este paso" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,help:base_tier_validation_server_action.field_tier_definition__rejected_server_action_id +msgid "Server action triggered as soon as this step is rejected" +msgstr "Acción del servidor activada en cuanto se rechaza este paso" + +#. module: base_tier_validation_server_action +#: model:ir.model,name:base_tier_validation_server_action.model_tier_definition +msgid "Tier Definition" +msgstr "Definición del Nivel" + +#. module: base_tier_validation_server_action +#: model:ir.model,name:base_tier_validation_server_action.model_tier_review +msgid "Tier Review" +msgstr "Revisión del Nivel" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,help:base_tier_validation_server_action.field_tier_definition__auto_validate +msgid "" +"Use schedule job to auto validate if condition is met.\n" +"- If no user specified, use job's system user to validate\n" +"- If 1 user matched as reviewer, use the user to validate\n" +"- If > 1 user matched as reviewer, do not auto validate" +msgstr "" +"Utiliza el trabajo programado para validar automáticamente si se cumple la " +"condición.\n" +"- Si no se especifica ningún usuario, utilizar el usuario del sistema del " +"trabajo para validar.\n" +"- Si 1 usuario coincide como revisor, utilizar el usuario para validar\n" +"- Si > 1 usuario coincide como revisor, no validar automáticamente" + +#. module: base_tier_validation_server_action +#: model_terms:ir.ui.view,arch_db:base_tier_validation_server_action.tier_definition_view_form +msgid "if pass condition" +msgstr "si pasa la condición" diff --git a/base_tier_validation_server_action/i18n/it.po b/base_tier_validation_server_action/i18n/it.po new file mode 100644 index 0000000000..924021b365 --- /dev/null +++ b/base_tier_validation_server_action/i18n/it.po @@ -0,0 +1,82 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_tier_validation_server_action +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-05 10:36+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__auto_validate +msgid "Auto Validate" +msgstr "Auto validazione" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__auto_validate_domain +msgid "Auto Validate Domain" +msgstr "Dominio auto validazione" + +#. module: base_tier_validation_server_action +#: model:ir.actions.server,name:base_tier_validation_server_action.ir_cron_auto_tier_validation_ir_actions_server +#: model:ir.cron,cron_name:base_tier_validation_server_action.ir_cron_auto_tier_validation +msgid "Automatic Tier Validation" +msgstr "Validazione automatica livello" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__server_action_id +msgid "Post Approve Action" +msgstr "Invio azione approvazione" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,field_description:base_tier_validation_server_action.field_tier_definition__rejected_server_action_id +msgid "Post Reject Action" +msgstr "Invio azione rifiuto" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,help:base_tier_validation_server_action.field_tier_definition__server_action_id +msgid "Server action triggered as soon as this step is approved" +msgstr "Azione del server attivata appena questa fase è approvata" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,help:base_tier_validation_server_action.field_tier_definition__rejected_server_action_id +msgid "Server action triggered as soon as this step is rejected" +msgstr "Azione del server attivata appena questa fase è respinta" + +#. module: base_tier_validation_server_action +#: model:ir.model,name:base_tier_validation_server_action.model_tier_definition +msgid "Tier Definition" +msgstr "Definizione livello" + +#. module: base_tier_validation_server_action +#: model:ir.model,name:base_tier_validation_server_action.model_tier_validation +msgid "Tier Validation (abstract)" +msgstr "Validazione livello (sintesi)" + +#. module: base_tier_validation_server_action +#: model:ir.model.fields,help:base_tier_validation_server_action.field_tier_definition__auto_validate +msgid "" +"Use schedule job to auto validate if condition is met.\n" +"- If no user specified, use job's system user to validate\n" +"- If 1 user matched as reviewer, use the user to validate\n" +"- If > 1 user matched as reviewer, do not auto validate" +msgstr "" +"Utilizzare il lavoro schedulato per auto validare se la condizione è " +"soddisfatta.\n" +"- Se non è secificato l'utente, utilizzare l'utente di sistema per validare\n" +"- Se un utente corrisponde come revisore, utilizzare l'utente per validare\n" +"- Se più di un utente corrsponde come revisore, non eseguire auto validazione" + +#. module: base_tier_validation_server_action +#: model_terms:ir.ui.view,arch_db:base_tier_validation_server_action.tier_definition_view_form +msgid "if pass condition" +msgstr "se supera la condizione" diff --git a/base_tier_validation_server_action/models/__init__.py b/base_tier_validation_server_action/models/__init__.py new file mode 100644 index 0000000000..98c81adcbd --- /dev/null +++ b/base_tier_validation_server_action/models/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import tier_definition +from . import tier_validation diff --git a/base_tier_validation_server_action/models/tier_definition.py b/base_tier_validation_server_action/models/tier_definition.py new file mode 100644 index 0000000000..fa01960661 --- /dev/null +++ b/base_tier_validation_server_action/models/tier_definition.py @@ -0,0 +1,66 @@ +# Copyright 2020 Ecosoft (http://ecosoft.co.th) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import logging +from ast import literal_eval + +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) + + +class TierDefinition(models.Model): + _inherit = "tier.definition" + + server_action_id = fields.Many2one( + comodel_name="ir.actions.server", + string="Post Approve Action", + domain=[("usage", "=", "ir_actions_server")], + help="Server action triggered as soon as this step is approved", + ) + rejected_server_action_id = fields.Many2one( + comodel_name="ir.actions.server", + string="Post Reject Action", + domain=[("usage", "=", "ir_actions_server")], + help="Server action triggered as soon as this step is rejected", + ) + auto_validate = fields.Boolean( + help="Use schedule job to auto validate if condition is met.\n" + "- If no user specified, use job's system user to validate\n" + "- If 1 user matched as reviewer, use the user to validate\n" + "- If > 1 user matched as reviewer, do not auto validate", + ) + auto_validate_domain = fields.Char() + + def _evaluate_review(self, review): + doc = self.env[review.model].browse(review.res_id) + domain = review.definition_id.auto_validate_domain or "[]" + return doc.filtered_domain(literal_eval(domain)) + + @api.model + def _cron_auto_tier_validation(self): + reviews = self.env["tier.review"].search( + [ + ("status", "in", ("waiting", "pending")), + ("definition_id.auto_validate", "=", True), + ] + ) + for review in reviews: + doc = self._evaluate_review(review) + if not doc: + continue + try: + reviewer = review.reviewer_ids or self.env.user + if len(reviewer) > 1: + _logger.warning( + f"Cannot auto tier validate {doc}: " "too many reviewers" + ) + continue + review_doc = doc.with_user(reviewer) + if review_doc.can_review: + sequences = review_doc._get_sequences_to_approve(reviewer) + if review.sequence in sequences: + review_doc._validate_tier(review) + review_doc._update_counter({"review_deleted": True}) + _logger.info("Auto tier validate on %s" % review_doc) + except Exception as e: + _logger.error(f"Cannot auto tier validate {doc}: {e}") diff --git a/base_tier_validation_server_action/models/tier_validation.py b/base_tier_validation_server_action/models/tier_validation.py new file mode 100644 index 0000000000..d148345161 --- /dev/null +++ b/base_tier_validation_server_action/models/tier_validation.py @@ -0,0 +1,40 @@ +# Copyright 2023 Ecosoft (http://ecosoft.co.th) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class TierValidation(models.AbstractModel): + _inherit = "tier.validation" + + def _server_action_tier(self, reviews, status): + for review in reviews: + if status == "approved": + server_action = review.definition_id.server_action_id + if status == "rejected": + server_action = review.definition_id.rejected_server_action_id + server_action_tier = self.env.context.get("server_action_tier") + # Don't allow reentrant server action as it will lead to + # recursive behaviour + if server_action and ( + not server_action_tier or server_action_tier != server_action.id + ): + server_action.with_context( + server_action_tier=server_action.id, + active_model=self._name, + active_id=self.id, + ).sudo().run() + + def _validate_tier(self, tiers=False): + self.ensure_one() + res = super()._validate_tier(tiers) + reviews = self.review_ids.filtered(lambda r: r.status == "approved") + self._server_action_tier(reviews, "approved") + return res + + def _rejected_tier(self, tiers=False): + self.ensure_one() + res = super()._rejected_tier(tiers) + reviews = self.review_ids.filtered(lambda r: r.status == "rejected") + self._server_action_tier(reviews, "rejected") + return res diff --git a/base_tier_validation_server_action/pyproject.toml b/base_tier_validation_server_action/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/base_tier_validation_server_action/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/base_tier_validation_server_action/readme/CONFIGURE.md b/base_tier_validation_server_action/readme/CONFIGURE.md new file mode 100644 index 0000000000..86e27b91a1 --- /dev/null +++ b/base_tier_validation_server_action/readme/CONFIGURE.md @@ -0,0 +1,9 @@ +On each Tier Definition + +- Choose server action you want to call as soon this definition is + approved or rejected + +- Select "Auto Validate", if you want this definition to get validated by cron job based on "if pass condition" criteria, + - If no user specified, use job's system user to validate + - If 1 user matched as reviewer, use the user to validate + - If \> 1 user matched as reviewer, do not auto validate diff --git a/base_tier_validation_server_action/readme/CONTRIBUTORS.md b/base_tier_validation_server_action/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..db1787028b --- /dev/null +++ b/base_tier_validation_server_action/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Kitti U. \<\> diff --git a/base_tier_validation_server_action/readme/DESCRIPTION.md b/base_tier_validation_server_action/readme/DESCRIPTION.md new file mode 100644 index 0000000000..02161a9c8c --- /dev/null +++ b/base_tier_validation_server_action/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module add option to call "Server Action" when a tier definition is +approved or rejected diff --git a/base_tier_validation_server_action/static/description/icon.png b/base_tier_validation_server_action/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/base_tier_validation_server_action/static/description/icon.png differ diff --git a/base_tier_validation_server_action/static/description/index.html b/base_tier_validation_server_action/static/description/index.html new file mode 100644 index 0000000000..e6eed6b344 --- /dev/null +++ b/base_tier_validation_server_action/static/description/index.html @@ -0,0 +1,442 @@ + + + + + +Base Tier Validation - Server Action + + + +
+

Base Tier Validation - Server Action

+ + +

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

+

This module add option to call “Server Action” when a tier definition is +approved or rejected

+

Table of contents

+ +
+

Configuration

+

On each Tier Definition

+
    +
  • Choose server action you want to call as soon this definition is +approved or rejected
  • +
  • Select “Auto Validate”, if you want this definition to get validated +by cron job based on “if pass condition” criteria,
      +
    • If no user specified, use job’s system user to validate
    • +
    • If 1 user matched as reviewer, use the user to validate
    • +
    • If > 1 user matched as reviewer, do not auto validate
    • +
    +
  • +
+
+
+

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

+
    +
  • Ecosoft
  • +
+
+ +
+

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.

+

Current maintainer:

+

kittiu

+

This module is part of the OCA/server-ux project on GitHub.

+

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

+
+
+
+ + diff --git a/base_tier_validation_server_action/tests/__init__.py b/base_tier_validation_server_action/tests/__init__.py new file mode 100644 index 0000000000..f39596410e --- /dev/null +++ b/base_tier_validation_server_action/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_tier_validation diff --git a/base_tier_validation_server_action/tests/test_tier_validation.py b/base_tier_validation_server_action/tests/test_tier_validation.py new file mode 100644 index 0000000000..57d35b6f4a --- /dev/null +++ b/base_tier_validation_server_action/tests/test_tier_validation.py @@ -0,0 +1,208 @@ +# Copyright 2020 Ecosoft (http://ecosoft.co.th) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +from odoo_test_helper import FakeModelLoader + +from odoo.tests import common +from odoo.tests.common import tagged + + +@tagged("post_install", "-at_install") +class TierTierValidation(common.TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + from .tier_validation_tester import TierValidationTester + + cls.loader.update_registry((TierValidationTester,)) + cls.test_model = cls.env[TierValidationTester._name] + cls.tester_model = cls.env["ir.model"].search( + [("model", "=", "tier.validation.tester")] + ) + + # Access record: + cls.env["ir.model.access"].create( + { + "name": "access.tester", + "model_id": cls.tester_model.id, + "perm_read": 1, + "perm_write": 1, + "perm_create": 1, + "perm_unlink": 1, + } + ) + + # Create users: + cls.group_system = cls.env.ref("base.group_system") + group_ids = cls.group_system.ids + cls.test_user_1 = cls.env["res.users"].create( + {"name": "John", "login": "test1", "groups_id": [(6, 0, group_ids)]} + ) + cls.test_user_2 = cls.env["res.users"].create( + {"name": "Mike", "login": "test2"} + ) + cls.test_user_3 = cls.env["res.users"].create( + {"name": "John Wick", "login": "test3", "groups_id": [(6, 0, group_ids)]} + ) + + # Create tier definitions: + cls.tier_def_obj = cls.env["tier.definition"] + 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', '>', 1.0)]", + "sequence": 30, + } + ) + + cls.test_record = cls.test_model.create({"test_field": 2.5}) + + @classmethod + def tearDownClass(cls): + cls.loader.restore_registry() + super().tearDownClass() + + def test_1_auto_validation(self): + # Create new test record + test_record = self.test_model.create({"test_field": 2.5}) + # Create tier definitions + self.tier_def_obj.create( + { + "model_id": self.tester_model.id, + "review_type": "individual", + "reviewer_id": self.test_user_1.id, + "sequence": 20, + "approve_sequence": True, + "auto_validate": True, + } + ) + self.tier_def_obj.create( + { + "model_id": self.tester_model.id, + "review_type": "individual", + "reviewer_id": self.test_user_1.id, + "sequence": 10, + "approve_sequence": True, + "auto_validate": True, + "auto_validate_domain": "[('test_field', '>', 3)]", + } + ) + # Request validation + test_record.with_user(self.test_user_2).request_validation() + record = test_record.with_user(self.test_user_1) + record.invalidate_recordset() + # Auto validate, 1st tier, not auto validated + self.tier_def_obj._cron_auto_tier_validation() + self.assertEqual( + record.review_ids.mapped("status"), ["waiting", "waiting", "waiting"] + ) + # Manual validate 2nd tier -> OK + record.validate_tier() + self.assertEqual( + record.review_ids.mapped("status"), ["approved", "pending", "waiting"] + ) + # Auto validate, 2nd tier -> OK + self.tier_def_obj._cron_auto_tier_validation() + self.assertEqual( + record.review_ids.mapped("status"), ["approved", "approved", "pending"] + ) + # Auto validate, 3rd tier -> Not pass validate domain + self.tier_def_obj._cron_auto_tier_validation() + self.assertEqual( + record.review_ids.mapped("status"), ["approved", "approved", "pending"] + ) + # Manual validate 3rd tier -> OK + record.validate_tier() + self.assertEqual( + record.review_ids.mapped("status"), ["approved", "approved", "approved"] + ) + + def test_2_auto_validation_exception(self): + # Create new test record + test_record = self.test_model.create({"test_field": 2.5}) + # Create tier definitions + self.tier_def_obj.create( + { + "model_id": self.tester_model.id, + "review_type": "individual", + "reviewer_group_id": self.group_system.id, + "sequence": 20, + "approve_sequence": True, + "auto_validate": True, + } + ) + # Request validation + test_record.with_user(self.test_user_2).request_validation() + record = test_record.with_user(self.test_user_1) + record.invalidate_recordset() + # Auto validate, 1st tier, not auto validated + self.tier_def_obj._cron_auto_tier_validation() + self.assertEqual(record.review_ids.mapped("status"), ["waiting", "waiting"]) + # Manual validate 2nd tier -> OK + record.validate_tier() + self.assertEqual(record.review_ids.mapped("status"), ["approved", "pending"]) + # Auto validate, 2nd tier -> Not OK, before len(reviewers) > 1 + self.tier_def_obj._cron_auto_tier_validation() + self.assertEqual(record.review_ids.mapped("status"), ["approved", "pending"]) + + def test_3_trigger_server_action(self): + # Create new test record + test_record = self.test_model.create({"test_field": 2.5}) + # Create server action + server_action = self.env["ir.actions.server"].create( + { + "name": "Set test_bool = True", + "model_id": self.tester_model.id, + "state": "code", + "code": "record.write({'test_bool': True})", + } + ) + # Create tier definitions + self.tier_def_obj.create( + { + "model_id": self.tester_model.id, + "review_type": "individual", + "reviewer_id": self.test_user_1.id, + "sequence": 20, + "server_action_id": server_action.id, # Server Action + } + ) + # Request validation + test_record.with_user(self.test_user_2).request_validation() + record = test_record.with_user(self.test_user_1) + record.invalidate_recordset() + record.validate_tier() + self.assertTrue(record.test_bool) + + def test_4_trigger_rejected_server_action(self): + # Create new test record + test_record = self.test_model.create({"test_field": 2.5}) + # Create rejected server action + rejected_server_action = self.env["ir.actions.server"].create( + { + "name": "Set test_bool = True", + "model_id": self.tester_model.id, + "state": "code", + "code": "record.write({'test_bool': True})", + } + ) + # Create tier definitions + self.tier_def_obj.create( + { + "model_id": self.tester_model.id, + "review_type": "individual", + "reviewer_id": self.test_user_1.id, + "sequence": 20, + "rejected_server_action_id": rejected_server_action.id, + } + ) + # Request rejection + test_record.with_user(self.test_user_2).request_validation() + record = test_record.with_user(self.test_user_1) + record.invalidate_recordset() + record.reject_tier() + self.assertTrue(record.test_bool) diff --git a/base_tier_validation_server_action/tests/tier_validation_tester.py b/base_tier_validation_server_action/tests/tier_validation_tester.py new file mode 100644 index 0000000000..36c533e6a2 --- /dev/null +++ b/base_tier_validation_server_action/tests/tier_validation_tester.py @@ -0,0 +1,25 @@ +# Copyright 2020 Ecosoft (http://ecosoft.co.th) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class TierValidationTester(models.Model): + _name = "tier.validation.tester" + _description = "Tier Validation Tester" + _inherit = ["tier.validation"] + + state = fields.Selection( + selection=[ + ("draft", "Draft"), + ("confirmed", "Confirmed"), + ("cancel", "Cancel"), + ], + default="draft", + ) + test_field = fields.Float() + user_id = fields.Many2one(string="Assigned to:", comodel_name="res.users") + test_bool = fields.Boolean() + + def _get_under_validation_exceptions(self): + return super()._get_under_validation_exceptions() + ["test_bool"] diff --git a/base_tier_validation_server_action/views/tier_definition_view.xml b/base_tier_validation_server_action/views/tier_definition_view.xml new file mode 100644 index 0000000000..af37ae6b12 --- /dev/null +++ b/base_tier_validation_server_action/views/tier_definition_view.xml @@ -0,0 +1,26 @@ + + + + + tier.definition.form + tier.definition + + + + + + + + + + + + +