diff --git a/base_tier_validation_formula/README.rst b/base_tier_validation_formula/README.rst new file mode 100644 index 0000000000..4ba415a047 --- /dev/null +++ b/base_tier_validation_formula/README.rst @@ -0,0 +1,86 @@ +============================ +Base Tier Validation Formula +============================ + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/14.0/base_tier_validation_formula + :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-14-0/server-ux-14-0-base_tier_validation_formula + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/250/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module includes the ability to define the tier definition domain +and the tier reviewers using python code. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To define the domain, +* By python code choose the **Formula** option in the Definition field. +* By both domain and python code, choose the **Domain & Formula** option in the Definition field. + +To define the reviewers by python code choose **Python Expression** option in the Validated by field. + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Creu Blanca + +Contributors +~~~~~~~~~~~~ + +* Enric Tobella +* Adrià Gil Sorribes +* Pedro Gonzalez +* Pimolnat Suntian + +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. + +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_formula/__init__.py b/base_tier_validation_formula/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/base_tier_validation_formula/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/base_tier_validation_formula/__manifest__.py b/base_tier_validation_formula/__manifest__.py new file mode 100644 index 0000000000..73bb195b47 --- /dev/null +++ b/base_tier_validation_formula/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2019 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Base Tier Validation Formula", + "summary": """ + Formulas for Base tier validation""", + "version": "15.0.1.0.0", + "license": "AGPL-3", + "author": "Creu Blanca,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/server-ux", + "depends": ["base_tier_validation"], + "data": ["views/tier_definition_view.xml"], + "demo": [], +} diff --git a/base_tier_validation_formula/i18n/base_tier_validation_formula.pot b/base_tier_validation_formula/i18n/base_tier_validation_formula.pot new file mode 100644 index 0000000000..3745ffd2fe --- /dev/null +++ b/base_tier_validation_formula/i18n/base_tier_validation_formula.pot @@ -0,0 +1,119 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_tier_validation_formula +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.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_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__definition_type +msgid "Definition" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__display_name +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_review__display_name +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_validation__display_name +msgid "Display Name" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__definition_type__domain_formula +msgid "Domain & Formula" +msgstr "" + +#. module: base_tier_validation_formula +#: code:addons/base_tier_validation_formula/models/tier_review.py:0 +#: code:addons/base_tier_validation_formula/models/tier_validation.py:0 +#, python-format +msgid "" +"Error evaluating tier validation conditions.\n" +" %s" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__definition_type__formula +msgid "Formula" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__id +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_review__id +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_validation__id +msgid "ID" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition____last_update +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_review____last_update +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_validation____last_update +msgid "Last Modified on" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__review_type__expression +msgid "Python Expression" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__reviewer_expression +msgid "Review Expression" +msgstr "" + +#. module: base_tier_validation_formula +#: code:addons/base_tier_validation_formula/models/tier_review.py:0 +#, python-format +msgid "Reviewer python expression must return a res.users recordset." +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_review__python_reviewer_ids +msgid "Reviewers from Python expression" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_definition +msgid "Tier Definition" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__python_code +msgid "Tier Definition Expression" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_review +msgid "Tier Review" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_validation +msgid "Tier Validation (abstract)" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__review_type +msgid "Validated by" +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,help:base_tier_validation_formula.field_tier_definition__reviewer_expression +msgid "" +"Write Python code that defines the reviewer. The result of executing the " +"expression must be a res.users recordset." +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,help:base_tier_validation_formula.field_tier_definition__python_code +msgid "" +"Write Python code that defines when this tier confirmation will be needed. " +"The result of executing the expresion must be a boolean." +msgstr "" diff --git a/base_tier_validation_formula/i18n/es.po b/base_tier_validation_formula/i18n/es.po new file mode 100644 index 0000000000..7af953674a --- /dev/null +++ b/base_tier_validation_formula/i18n/es.po @@ -0,0 +1,118 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_tier_validation_formula +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-03-16 11:46+0000\n" +"Last-Translator: Ana Suárez \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.3.2\n" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__definition_type +msgid "Definition" +msgstr "Definición" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__definition_type__domain_formula +msgid "Domain & Formula" +msgstr "Dominio & Fórmula" + +#. module: base_tier_validation_formula +#: code:addons/base_tier_validation_formula/models/tier_review.py:0 +#: code:addons/base_tier_validation_formula/models/tier_validation.py:0 +#, python-format +msgid "" +"Error evaluating tier validation conditions.\n" +" %s" +msgstr "" +"Error evaluando las condiciones de validación de nivel.\n" +"%s" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__definition_type__formula +msgid "Formula" +msgstr "Fórmula" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__review_type__expression +msgid "Python Expression" +msgstr "Expresión Python" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__reviewer_expression +msgid "Review Expression" +msgstr "Expresión de Revisión" + +#. module: base_tier_validation_formula +#: code:addons/base_tier_validation_formula/models/tier_review.py:0 +#, python-format +msgid "Reviewer python expression must return a res.users recordset." +msgstr "" +"La expresión python del revisor debe retornar un conjunto de registros de " +"res.users." + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_review__python_reviewer_ids +msgid "Reviewers from Python expression" +msgstr "Revisores desde una expresión Python" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_definition +msgid "Tier Definition" +msgstr "Definición de Nivel" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__python_code +msgid "Tier Definition Expression" +msgstr "Expresión de Definición de Nivel" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_review +msgid "Tier Review" +msgstr "Definición de nivel" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_validation +msgid "Tier Validation (abstract)" +msgstr "Validación de Nivel (abstracto)" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__review_type +msgid "Validated by" +msgstr "Validado por" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,help:base_tier_validation_formula.field_tier_definition__reviewer_expression +msgid "" +"Write Python code that defines the reviewer. The result of executing the " +"expression must be a res.users recordset." +msgstr "" +"Escribe código Python que defina al revisor. El resultado de ejecutar la " +"expresión debe devolver un conjunto de registros de res.users." + +#. module: base_tier_validation_formula +#: model:ir.model.fields,help:base_tier_validation_formula.field_tier_definition__python_code +msgid "" +"Write Python code that defines when this tier confirmation will be needed. " +"The result of executing the expresion must be a boolean." +msgstr "" +"Escribe código Python que defina si la confirmación de nivel es necesaria. " +"El resultado de ejecutar la expresión debe ser un booleano." + +#~ msgid "Any user in a specific group." +#~ msgstr "Cualquier usuario de un grupo específico." + +#~ msgid "Domain" +#~ msgstr "Dominio" + +#~ msgid "Specific user" +#~ msgstr "Usuario específico" diff --git a/base_tier_validation_formula/i18n/it.po b/base_tier_validation_formula/i18n/it.po new file mode 100644 index 0000000000..6f9bc4f0f7 --- /dev/null +++ b/base_tier_validation_formula/i18n/it.po @@ -0,0 +1,103 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_tier_validation_formula +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2020-11-04 10:08+0000\n" +"Last-Translator: Alessandro Fiorino \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 3.10\n" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__definition_type +msgid "Definition" +msgstr "Definizione" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__definition_type__domain_formula +msgid "Domain & Formula" +msgstr "Dominio e Formula" + +#. module: base_tier_validation_formula +#: code:addons/base_tier_validation_formula/models/tier_review.py:0 +#: code:addons/base_tier_validation_formula/models/tier_validation.py:0 +#, python-format +msgid "" +"Error evaluating tier validation conditions.\n" +" %s" +msgstr "" +"Errore valutando le condizioni di validazione del livello.\n" +" %s" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__definition_type__formula +msgid "Formula" +msgstr "Formula" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__review_type__expression +msgid "Python Expression" +msgstr "Espressione Python" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__reviewer_expression +msgid "Review Expression" +msgstr "Espressione Approvazione" + +#. module: base_tier_validation_formula +#: code:addons/base_tier_validation_formula/models/tier_review.py:0 +#, python-format +msgid "Reviewer python expression must return a res.users recordset." +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_review__python_reviewer_ids +msgid "Reviewers from Python expression" +msgstr "Approvatori da espressione Python" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_definition +msgid "Tier Definition" +msgstr "Definizione Livello" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__python_code +msgid "Tier Definition Expression" +msgstr "Espressione Definizione Livello" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_review +msgid "Tier Review" +msgstr "Livello Approvazione" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_validation +msgid "Tier Validation (abstract)" +msgstr "Livello Approvazione (astratto)" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__review_type +msgid "Validated by" +msgstr "Approvato da" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,help:base_tier_validation_formula.field_tier_definition__reviewer_expression +msgid "" +"Write Python code that defines the reviewer. The result of executing the " +"expression must be a res.users recordset." +msgstr "" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,help:base_tier_validation_formula.field_tier_definition__python_code +msgid "" +"Write Python code that defines when this tier confirmation will be needed. " +"The result of executing the expresion must be a boolean." +msgstr "" diff --git a/base_tier_validation_formula/i18n/zh_CN.po b/base_tier_validation_formula/i18n/zh_CN.po new file mode 100644 index 0000000000..0dae7b0e45 --- /dev/null +++ b/base_tier_validation_formula/i18n/zh_CN.po @@ -0,0 +1,112 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_tier_validation_formula +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2020-03-28 16:13+0000\n" +"Last-Translator: Dong \n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.10\n" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__definition_type +msgid "Definition" +msgstr "定义" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__definition_type__domain_formula +msgid "Domain & Formula" +msgstr "域和公式" + +#. module: base_tier_validation_formula +#: code:addons/base_tier_validation_formula/models/tier_review.py:0 +#: code:addons/base_tier_validation_formula/models/tier_validation.py:0 +#, python-format +msgid "" +"Error evaluating tier validation conditions.\n" +" %s" +msgstr "" +"错误的层级审批条件。\n" +" %s" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__definition_type__formula +msgid "Formula" +msgstr "公式" + +#. module: base_tier_validation_formula +#: model:ir.model.fields.selection,name:base_tier_validation_formula.selection__tier_definition__review_type__expression +msgid "Python Expression" +msgstr "Python表达式" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__reviewer_expression +msgid "Review Expression" +msgstr "审核表达式" + +#. module: base_tier_validation_formula +#: code:addons/base_tier_validation_formula/models/tier_review.py:0 +#, python-format +msgid "Reviewer python expression must return a res.users recordset." +msgstr "审核者python表达式必须返回res.users记录集。" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_review__python_reviewer_ids +msgid "Reviewers from Python expression" +msgstr "来自Python表达式的审查者" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_definition +msgid "Tier Definition" +msgstr "层级定义" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__python_code +msgid "Tier Definition Expression" +msgstr "层级定义表达式" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_review +msgid "Tier Review" +msgstr "多层级审批" + +#. module: base_tier_validation_formula +#: model:ir.model,name:base_tier_validation_formula.model_tier_validation +msgid "Tier Validation (abstract)" +msgstr "多层级审批(抽象)" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,field_description:base_tier_validation_formula.field_tier_definition__review_type +msgid "Validated by" +msgstr "审批人" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,help:base_tier_validation_formula.field_tier_definition__reviewer_expression +msgid "" +"Write Python code that defines the reviewer. The result of executing the " +"expression must be a res.users recordset." +msgstr "编写定义审核者的Python代码。执行表达式的结果必须是res.users记录集。" + +#. module: base_tier_validation_formula +#: model:ir.model.fields,help:base_tier_validation_formula.field_tier_definition__python_code +msgid "" +"Write Python code that defines when this tier confirmation will be needed. " +"The result of executing the expresion must be a boolean." +msgstr "编写Python代码,定义何时需要此层确认。执行表达式的结果必须是布尔值。" + +#~ msgid "Any user in a specific group." +#~ msgstr "特定组中的任何用户。" + +#~ msgid "Domain" +#~ msgstr "域" + +#~ msgid "Specific user" +#~ msgstr "具体用户" diff --git a/base_tier_validation_formula/models/__init__.py b/base_tier_validation_formula/models/__init__.py new file mode 100644 index 0000000000..928b46c886 --- /dev/null +++ b/base_tier_validation_formula/models/__init__.py @@ -0,0 +1,3 @@ +from . import tier_definition +from . import tier_validation +from . import tier_review diff --git a/base_tier_validation_formula/models/tier_definition.py b/base_tier_validation_formula/models/tier_definition.py new file mode 100644 index 0000000000..b9d0e5069f --- /dev/null +++ b/base_tier_validation_formula/models/tier_definition.py @@ -0,0 +1,39 @@ +# Copyright 2019 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class TierDefinition(models.Model): + _inherit = "tier.definition" + + python_code = fields.Text( + string="Tier Definition Expression", + help="Write Python code that defines when this tier confirmation " + "will be needed. The result of executing the expresion must be " + "a boolean.", + default="""# Available locals:\n# - rec: current record\nTrue""", + ) + definition_type = fields.Selection( + selection_add=[("formula", "Formula"), ("domain_formula", "Domain & Formula")] + ) + reviewer_expression = fields.Text( + string="Review Expression", + help="Write Python code that defines the reviewer. " + "The result of executing the expression must be a res.users " + "recordset.", + default="# Available locals:\n# - rec: current record\n" + "# - Expects a recordset of res.users\nrec.env.user", + ) + review_type = fields.Selection(selection_add=[("expression", "Python Expression")]) + + @api.onchange("review_type") + def onchange_review_type(self): + res = super(TierDefinition, self).onchange_review_type() + self.reviewer_expression = ( + "# Available locals:\n" + "# - rec: current record\n" + "# - Expects a recordset of res.users\n" + "rec.env.user" + ) + return res diff --git a/base_tier_validation_formula/models/tier_review.py b/base_tier_validation_formula/models/tier_review.py new file mode 100644 index 0000000000..f94f869275 --- /dev/null +++ b/base_tier_validation_formula/models/tier_review.py @@ -0,0 +1,57 @@ +# Copyright 2019 ForgeFlow S.L. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import UserError +from odoo.tools.safe_eval import safe_eval + + +class TierReview(models.Model): + _inherit = "tier.review" + + python_reviewer_ids = fields.Many2many( + comodel_name="res.users", + relation="tier_review_python_reviewer_rel", + column1="tier_review_id", + column2="user_id", + string="Reviewers from Python expression", + compute="_compute_python_reviewer_ids", + store=True, + ) + + @api.model + def _get_reviewer_fields(self): + res = super()._get_reviewer_fields() + return res + ["python_reviewer_ids"] + + def _get_reviewers(self): + return super()._get_reviewers() + self.python_reviewer_ids + + @api.depends("definition_id.reviewer_expression", "review_type", "model", "res_id") + def _compute_python_reviewer_ids(self): + for rec in self: + if rec.review_type != "expression": + rec.python_reviewer_ids = self.env["res.users"].browse() + continue + record = rec.env[rec.model].browse(rec.res_id).exists() + try: + reviewer_ids = safe_eval( + rec.definition_id.reviewer_expression, globals_dict={"rec": record} + ) + except Exception as error: + raise UserError( + _("Error evaluating tier validation " "conditions.\n %s") % error + ) from error + # Check if python expression returns 'res.users' recordset + if ( + not isinstance(reviewer_ids, models.Model) + or reviewer_ids._name != "res.users" + ): + raise UserError( + _( + "Reviewer python expression must return a " + "res.users recordset." + ) + ) + else: + rec.python_reviewer_ids = reviewer_ids diff --git a/base_tier_validation_formula/models/tier_validation.py b/base_tier_validation_formula/models/tier_validation.py new file mode 100644 index 0000000000..d5a07a45b7 --- /dev/null +++ b/base_tier_validation_formula/models/tier_validation.py @@ -0,0 +1,27 @@ +# Copyright 2019 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, models +from odoo.exceptions import UserError +from odoo.tools.safe_eval import safe_eval + + +class TierValidation(models.AbstractModel): + _inherit = "tier.validation" + + def evaluate_formula_tier(self, tier): + try: + res = safe_eval(tier.python_code, globals_dict={"rec": self}) + except Exception as error: + raise UserError( + _("Error evaluating tier validation conditions.\n %s") % error + ) from error + return res + + def evaluate_tier(self, tier): + res = super().evaluate_tier(tier) + if tier.definition_type == "formula": + return self.evaluate_formula_tier(tier) + if tier.definition_type == "domain_formula": + return res and self.evaluate_formula_tier(tier) + return res diff --git a/base_tier_validation_formula/readme/CONTRIBUTORS.rst b/base_tier_validation_formula/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..4390a8e273 --- /dev/null +++ b/base_tier_validation_formula/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* Enric Tobella +* Adrià Gil Sorribes +* Pedro Gonzalez +* Pimolnat Suntian diff --git a/base_tier_validation_formula/readme/DESCRIPTION.rst b/base_tier_validation_formula/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..cbaee80714 --- /dev/null +++ b/base_tier_validation_formula/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module includes the ability to define the tier definition domain +and the tier reviewers using python code. diff --git a/base_tier_validation_formula/readme/USAGE.rst b/base_tier_validation_formula/readme/USAGE.rst new file mode 100644 index 0000000000..e06bb49ae3 --- /dev/null +++ b/base_tier_validation_formula/readme/USAGE.rst @@ -0,0 +1,5 @@ +To define the domain, +* By python code choose the **Formula** option in the Definition field. +* By both domain and python code, choose the **Domain & Formula** option in the Definition field. + +To define the reviewers by python code choose **Python Expression** option in the Validated by field. diff --git a/base_tier_validation_formula/static/description/icon.png b/base_tier_validation_formula/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/base_tier_validation_formula/static/description/icon.png differ diff --git a/base_tier_validation_formula/static/description/index.html b/base_tier_validation_formula/static/description/index.html new file mode 100644 index 0000000000..3eed422715 --- /dev/null +++ b/base_tier_validation_formula/static/description/index.html @@ -0,0 +1,431 @@ + + + + + + +Base Tier Validation Formula + + + +
+

Base Tier Validation Formula

+ + +

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

+

This module includes the ability to define the tier definition domain +and the tier reviewers using python code.

+

Table of contents

+ +
+

Usage

+

To define the domain, +* By python code choose the Formula option in the Definition field. +* By both domain and python code, choose the Domain & Formula option in the Definition field.

+

To define the reviewers by python code choose Python Expression option in the Validated by field.

+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Creu Blanca
  • +
+
+
+

Contributors

+ +
+
+

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.

+

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_formula/tests/__init__.py b/base_tier_validation_formula/tests/__init__.py new file mode 100644 index 0000000000..f39596410e --- /dev/null +++ b/base_tier_validation_formula/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_formula/tests/test_tier_validation.py b/base_tier_validation_formula/tests/test_tier_validation.py new file mode 100644 index 0000000000..88eb6e5f26 --- /dev/null +++ b/base_tier_validation_formula/tests/test_tier_validation.py @@ -0,0 +1,162 @@ +# Copyright 2018 ForgeFlow S.L. +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +from odoo_test_helper import FakeModelLoader + +from odoo.exceptions import UserError +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(TierTierValidation, cls).setUpClass() + + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + from odoo.addons.base_tier_validation.tests.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: + group_ids = cls.env.ref("base.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": "Mary", "login": "test3"} + ) + + # 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)]", + } + ) + + cls.test_record = cls.test_model.create({"test_field": 2.5}) + + @classmethod + def tearDownClass(cls): + cls.loader.restore_registry() + return super(TierTierValidation, cls).tearDownClass() + + def test_01_reviewer_from_python_expression(self): + tier_definition = self.tier_def_obj.create( + { + "model_id": self.tester_model.id, + "review_type": "individual", + "reviewer_id": self.test_user_1.id, + "definition_type": "formula", + "python_code": "rec.test_field > 1.0", + } + ) + tier_definition.write( + { + "model_id": self.tester_model.id, + "review_type": "expression", + "python_code": "rec.test_field > 3.0", + } + ) + tier_definition.onchange_review_type() + tier_definition.write({"reviewer_expression": "rec.user_id"}) + self.test_record.write({"test_field": 3.5, "user_id": self.test_user_2.id}) + reviews = self.test_record.with_user(self.test_user_3.id).request_validation() + self.assertTrue(reviews) + self.assertEqual(len(reviews), 2) + record = self.test_record.with_user(self.test_user_1.id) + self.test_record.invalidate_cache() + record.invalidate_cache() + self.assertIn(self.test_user_1, record.reviewer_ids) + self.assertIn(self.test_user_2, record.reviewer_ids) + res = self.test_model.search([("reviewer_ids", "in", self.test_user_2.id)]) + self.assertTrue(res) + + def test_02_wrong_reviewer_expression(self): + """Error should raise with incorrect python expresions on + tier definitions.""" + self.tier_def_obj.create( + { + "model_id": self.tester_model.id, + "review_type": "expression", + "reviewer_expression": "rec.test_field", + "python_code": "rec.test_field > 1.0", + } + ) + with self.assertRaises(UserError): + self.test_record.with_user(self.test_user_3).request_validation() + self.test_record.review_ids.invalidate_cache() + self.test_record.review_ids._compute_python_reviewer_ids() + + def test_03_evaluate_wrong_reviewer_expression(self): + self.tier_def_obj.create( + { + "model_id": self.tester_model.id, + "review_type": "expression", + "reviewer_expression": "raise Exception", + "python_code": "rec.test_field > 1.0", + } + ) + with self.assertRaises(UserError): + self.test_record.with_user(self.test_user_3).request_validation() + self.test_record.review_ids.invalidate_cache() + self.test_record.review_ids._compute_python_reviewer_ids() + + def test_04_evaluate_wrong_python_formula_expression(self): + 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": "expression", + "reviewer_expression": "raise Exception", + "python_code": "raise Exception", + } + ) + # Request validation + with self.assertRaises(UserError): + review = test_record.with_user(self.test_user_2).request_validation() + self.test_record.evaluate_formula_tier(review) + + def test_05_definition_from_domain_formula(self): + self.tier_def_obj.create( + { + "model_id": self.tester_model.id, + "review_type": "individual", + "reviewer_id": self.test_user_1.id, + "definition_type": "domain_formula", + "definition_domain": '[("test_field", "<", 5.0)]', + "python_code": "rec.test_field > 1.0", + } + ) + self.test_record.write({"test_field": 3.5, "user_id": self.test_user_2.id}) + reviews = self.test_record.with_user(self.test_user_3.id).request_validation() + self.assertTrue(reviews) diff --git a/base_tier_validation_formula/views/tier_definition_view.xml b/base_tier_validation_formula/views/tier_definition_view.xml new file mode 100644 index 0000000000..4f0031cfba --- /dev/null +++ b/base_tier_validation_formula/views/tier_definition_view.xml @@ -0,0 +1,32 @@ + + + + + tier.definition.form + tier.definition + + + + + + + + + {'invisible': [('definition_type', 'not in', ('domain', 'domain_formula'))]} + + + + + + + diff --git a/setup/base_tier_validation_formula/odoo/addons/base_tier_validation_formula b/setup/base_tier_validation_formula/odoo/addons/base_tier_validation_formula new file mode 120000 index 0000000000..fff1acb286 --- /dev/null +++ b/setup/base_tier_validation_formula/odoo/addons/base_tier_validation_formula @@ -0,0 +1 @@ +../../../../base_tier_validation_formula \ No newline at end of file diff --git a/setup/base_tier_validation_formula/setup.py b/setup/base_tier_validation_formula/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/base_tier_validation_formula/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)