Mourad Elhadj Mimoune
8 years ago
committed by
Iván Todorovich
14 changed files with 874 additions and 0 deletions
-
60base_exception/README.rst
-
5base_exception/__init__.py
-
21base_exception/__manifest__.py
-
211base_exception/i18n/base_exception.pot
-
213base_exception/i18n/fr.po
-
5base_exception/models/__init__.py
-
215base_exception/models/base_exception.py
-
9base_exception/security/base_exception_security.xml
-
5base_exception/security/ir.model.access.csv
-
BINbase_exception/static/description/icon.png
-
51base_exception/views/base_exception_view.xml
-
5base_exception/wizard/__init__.py
-
35base_exception/wizard/base_exception_confirm.py
-
39base_exception/wizard/base_exception_confirm_view.xml
@ -0,0 +1,60 @@ |
|||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
|||
:alt: License: AGPL-3 |
|||
|
|||
============== |
|||
Base Exception |
|||
============== |
|||
|
|||
This module provide an abstract model to manage customizable exceptions to be applied on different models (sale order, invoice, ...). It is not usefull for itself. You can see an example of implementation in the 'sale_exception' module. (sale-workflow repository). |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/149/10.0 |
|||
|
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues |
|||
<https://github.com/OCA/server-tools/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 |
|||
<https://github.com/OCA/ |
|||
server-tools/issues/new?body=module:%20 |
|||
base_exception%0Aversion:%20 |
|||
10.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. |
|||
|
|||
Images |
|||
------ |
|||
|
|||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Raphaël Valyi <raphael.valyi@akretion.com> |
|||
* Renato Lima <renato.lima@akretion.com> |
|||
* Sébastien BEAU <sebastien.beau@akretion.com> |
|||
* Guewen Baconnier <guewen.baconnier@camptocamp.com> |
|||
* Yannick Vaucher <yannick.vaucher@camptocamp.com> |
|||
* SodexisTeam <dev@sodexis.com> |
|||
* Mourad EL HADJ MIMOUNE <mourad.elhadj.mimoune@akretion.com> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
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. |
|||
|
|||
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,5 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from . import wizard, models |
@ -0,0 +1,21 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
{'name': 'Exception Rule', |
|||
'version': '10.0.1.0.0', |
|||
'category': 'Generic Modules', |
|||
'summary': """This module provide an abstract model to manage customizable |
|||
exceptions to be applied on different models (sale order, invoice, ...)""", |
|||
'author': "Akretion, Sodexis, Camptocamp, Odoo Community Association (OCA)", |
|||
'website': 'http://www.akretion.com', |
|||
'depends': ['base_setup'], |
|||
'license': 'AGPL-3', |
|||
'data': [ |
|||
'security/base_exception_security.xml', |
|||
'security/ir.model.access.csv', |
|||
'wizard/base_exception_confirm_view.xml', |
|||
'views/base_exception_view.xml', |
|||
], |
|||
'installable': True, |
|||
} |
@ -0,0 +1,211 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * base_exception |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-03-22 09:46+0000\n" |
|||
"PO-Revision-Date: 2017-03-22 09:46+0000\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_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_active |
|||
msgid "Active" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_model |
|||
msgid "Apply on" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.actions.act_window,name:base_exception.action_exception_rule_confirm |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_confirm |
|||
msgid "Blocked in draft due to exceptions" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_create_uid |
|||
msgid "Created by" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_create_date |
|||
msgid "Created on" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_description |
|||
msgid "Description" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_display_name |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_display_name |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_display_name |
|||
msgid "Display Name" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: code:addons/base_exception/models/base_exception.py:185 |
|||
#, python-format |
|||
msgid "Error when evaluating the exception.rule rule:\n" |
|||
" %s \n" |
|||
"(%s)" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_name |
|||
msgid "Exception Name" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_tree |
|||
msgid "Exception Rule" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_form |
|||
msgid "Exception Rule Setup" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.actions.act_window,name:base_exception.action_exception_rule_tree |
|||
#: model:ir.model,name:base_exception.model_exception_rule |
|||
#: model:ir.ui.menu,name:base_exception.menu_action_exception |
|||
msgid "Exception Rules" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:res.groups,name:base_exception.group_exception_rule_manager |
|||
msgid "Exception manager" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_exception_ids |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_order_exception_ids |
|||
msgid "Exceptions" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_confirm |
|||
msgid "Exceptions Rules" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_exception_ids |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_exception_confirm_exception_ids |
|||
msgid "Exceptions to resolve" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,help:base_exception.field_exception_rule_sequence |
|||
msgid "Gives the sequence order when applying the test" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_id |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_id |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_id |
|||
msgid "ID" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_ignore_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_ignore |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_exception_confirm_ignore |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_order_ignore_exception |
|||
msgid "Ignore Exceptions" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception___last_update |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule___last_update |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm___last_update |
|||
msgid "Last Modified on" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_write_uid |
|||
msgid "Last Updated by" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_write_date |
|||
msgid "Last Updated on" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_main_exception_id |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_order_main_exception_id |
|||
msgid "Main Exception" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_code |
|||
msgid "Python Code" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,help:base_exception.field_exception_rule_code |
|||
msgid "Python code executed to check if the exception apply or not. The code must apply block = True to apply the exception." |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_related_model_id |
|||
msgid "Related model id" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_rule_group |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_rule_group |
|||
msgid "Rule group" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,help:base_exception.field_exception_rule_rule_group |
|||
msgid "Rule group is used to group the rules that must validated at same time for a target object. Ex: validate sale.order.line rules with sale order rules." |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: selection:exception.rule,rule_group:0 |
|||
msgid "Sale" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: selection:exception.rule,model:0 |
|||
msgid "Sale order" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: selection:exception.rule,model:0 |
|||
msgid "Sale order line" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_sequence |
|||
msgid "Sequence" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_confirm |
|||
msgid "_Close" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model,name:base_exception.model_base_exception |
|||
msgid "base.exception" |
|||
msgstr "" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model,name:base_exception.model_exception_rule_confirm |
|||
msgid "exception.rule.confirm" |
|||
msgstr "" |
|||
|
@ -0,0 +1,213 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * base_exception |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-03-22 09:46+0000\n" |
|||
"PO-Revision-Date: 2017-03-22 09:46+0000\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_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_active |
|||
msgid "Active" |
|||
msgstr "Actif" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_model |
|||
msgid "Apply on" |
|||
msgstr "Appliquer sur" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.actions.act_window,name:base_exception.action_exception_rule_confirm |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_confirm |
|||
msgid "Blocked in draft due to exceptions" |
|||
msgstr "Bloqué à l'état brouillon à cause d'une restriction" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_create_uid |
|||
msgid "Created by" |
|||
msgstr "Créé par" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_create_date |
|||
msgid "Created on" |
|||
msgstr "Créé le" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_description |
|||
msgid "Description" |
|||
msgstr "Description" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_display_name |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_display_name |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_display_name |
|||
msgid "Display Name" |
|||
msgstr "Nom à afficher" |
|||
|
|||
#. module: base_exception |
|||
#: code:addons/base_exception/models/base_exception.py:185 |
|||
#, python-format |
|||
msgid "Error when evaluating the exception.rule rule:\n" |
|||
" %s \n" |
|||
"(%s)" |
|||
msgstr "L'evaluatino de la règle d'exception a généré une erreur :\n" |
|||
" %s \n" |
|||
"(%s)" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_name |
|||
msgid "Exception Name" |
|||
msgstr "Nom de l'exception" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_tree |
|||
msgid "Exception Rule" |
|||
msgstr "Règle de l'exception" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_form |
|||
msgid "Exception Rule Setup" |
|||
msgstr "Paramètre de la règle de l'exception" |
|||
|
|||
#. modul: base_exception |
|||
#: model:ir.actions.act_window,name:base_exception.action_exception_rule_tree |
|||
#: model:ir.model,name:base_exception.model_exception_rule |
|||
#: model:ir.ui.menu,name:base_exception.menu_action_exception |
|||
msgid "Exception Rules" |
|||
msgstr "Règles de restriction" |
|||
|
|||
#. module: base_exception |
|||
#: model:res.groups,name:base_exception.group_exception_rule_manager |
|||
msgid "Exception manager" |
|||
msgstr "Gestionnaire d'exception" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_exception_ids |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_order_exception_ids |
|||
msgid "Exceptions" |
|||
msgstr "Exceptions" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_confirm |
|||
msgid "Exceptions Rules" |
|||
msgstr "Règles d'exceptions" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_exception_ids |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_exception_confirm_exception_ids |
|||
msgid "Exceptions to resolve" |
|||
msgstr "Exceptions à resoudre" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,help:base_exception.field_exception_rule_sequence |
|||
msgid "Gives the sequence order when applying the test" |
|||
msgstr "Donner l'order d'application des règles" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_id |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_id |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_id |
|||
msgid "ID" |
|||
msgstr "ID" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_ignore_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_ignore |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_exception_confirm_ignore |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_order_ignore_exception |
|||
msgid "Ignore Exceptions" |
|||
msgstr "Ignorer les exceptions" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception___last_update |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule___last_update |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm___last_update |
|||
msgid "Last Modified on" |
|||
msgstr "Dernière Modification le" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_write_uid |
|||
msgid "Last Updated by" |
|||
msgstr "Dernière mise à jour par" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_write_date |
|||
msgid "Last Updated on" |
|||
msgstr "Dernière mise à jour le" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_main_exception_id |
|||
#: model:ir.model.fields,field_description:base_exception.field_sale_order_main_exception_id |
|||
msgid "Main Exception" |
|||
msgstr "Exception principale" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_code |
|||
msgid "Python Code" |
|||
msgstr "Code Python" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,help:base_exception.field_exception_rule_code |
|||
msgid "Python code executed to check if the exception apply or not. The code must apply block = True to apply the exception." |
|||
msgstr "Code python à vérifier si l'exception est applicable ou pas. Le code doit renvoyer True pour appliquer l'exception." |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_confirm_related_model_id |
|||
msgid "Related model id" |
|||
msgstr "Model (obj) lié" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_base_exception_rule_group |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_rule_group |
|||
msgid "Rule group" |
|||
msgstr "Groupe de règles" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,help:base_exception.field_exception_rule_rule_group |
|||
msgid "Rule group is used to group the rules that must validated at same time for a target object. Ex: validate sale.order.line rules with sale order rules." |
|||
msgstr "Le groupe de règles est utiliser pour grouper toutes les règles qui doivent être vérifiées pour un même objet. Ex: valider les règles de sale.order.line avec les règles de sale order." |
|||
|
|||
#. module: base_exception |
|||
#: selection:exception.rule,rule_group:0 |
|||
msgid "Sale" |
|||
msgstr "Vente" |
|||
|
|||
#. module: base_exception |
|||
#: selection:exception.rule,model:0 |
|||
msgid "Sale order" |
|||
msgstr "Commande de vente" |
|||
|
|||
#. module: base_exception |
|||
#: selection:exception.rule,model:0 |
|||
msgid "Sale order line" |
|||
msgstr "Ligne de vente" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model.fields,field_description:base_exception.field_exception_rule_sequence |
|||
msgid "Sequence" |
|||
msgstr "Séquence" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.ui.view,arch_db:base_exception.view_exception_rule_confirm |
|||
msgid "_Close" |
|||
msgstr "_Close" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model,name:base_exception.model_base_exception |
|||
msgid "base.exception" |
|||
msgstr "base.exception" |
|||
|
|||
#. module: base_exception |
|||
#: model:ir.model,name:base_exception.model_exception_rule_confirm |
|||
msgid "exception.rule.confirm" |
|||
msgstr "exception.rule.confirm" |
|||
|
@ -0,0 +1,5 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from . import base_exception |
@ -0,0 +1,215 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
import time |
|||
from functools import wraps |
|||
|
|||
from odoo import api, models, fields, _ |
|||
from odoo.exceptions import UserError, ValidationError |
|||
from odoo.tools.safe_eval import safe_eval |
|||
|
|||
|
|||
def implemented_by_base_exception(func): |
|||
"""Call a prefixed function based on 'namespace'.""" |
|||
@wraps(func) |
|||
def wrapper(cls, *args, **kwargs): |
|||
fun_name = func.__name__ |
|||
fun = '_%s%s' % (cls.rule_group, fun_name) |
|||
if not hasattr(cls, fun): |
|||
fun = '_default%s' % (fun_name) |
|||
return getattr(cls, fun)(*args, **kwargs) |
|||
return wrapper |
|||
|
|||
|
|||
class ExceptionRule(models.Model): |
|||
_name = 'exception.rule' |
|||
_description = "Exception Rules" |
|||
_order = 'active desc, sequence asc' |
|||
|
|||
name = fields.Char('Exception Name', required=True, translate=True) |
|||
description = fields.Text('Description', translate=True) |
|||
sequence = fields.Integer( |
|||
string='Sequence', |
|||
help="Gives the sequence order when applying the test") |
|||
rule_group = fields.Selection( |
|||
selection=[], |
|||
help="Rule group is used to group the rules that must validated " |
|||
"at same time for a target object. Ex: " |
|||
"validate sale.order.line rules with sale order rules.", |
|||
required=True) |
|||
model = fields.Selection( |
|||
selection=[], |
|||
string='Apply on', required=True) |
|||
active = fields.Boolean('Active') |
|||
code = fields.Text( |
|||
'Python Code', |
|||
help="Python code executed to check if the exception apply or " |
|||
"not. The code must apply block = True to apply the " |
|||
"exception.", |
|||
default=""" |
|||
# Python code. Use failed = True to block the base.exception. |
|||
# You can use the following variables : |
|||
# - self: ORM model of the record which is checked |
|||
# - "rule_group" or "rule_group_"line: |
|||
# browse_record of the base.exception or |
|||
# base.exception line (ex rule_group = sale for sale order) |
|||
# - object: same as order or line, browse_record of the base.exception or |
|||
# base.exception line |
|||
# - pool: ORM model pool (i.e. self.pool) |
|||
# - time: Python time module |
|||
# - cr: database cursor |
|||
# - uid: current user id |
|||
# - context: current context |
|||
""") |
|||
|
|||
|
|||
class BaseException(models.AbstractModel): |
|||
_name = 'base.exception' |
|||
|
|||
_order = 'main_exception_id asc' |
|||
|
|||
main_exception_id = fields.Many2one( |
|||
'exception.rule', |
|||
compute='_compute_main_error', |
|||
string='Main Exception', |
|||
store=True) |
|||
rule_group = fields.Selection( |
|||
[], |
|||
readonly=True, |
|||
) |
|||
exception_ids = fields.Many2many( |
|||
'exception.rule', |
|||
string='Exceptions') |
|||
ignore_exception = fields.Boolean('Ignore Exceptions', copy=False) |
|||
|
|||
@api.depends('exception_ids', 'ignore_exception') |
|||
def _compute_main_error(self): |
|||
for obj in self: |
|||
if not obj.ignore_exception and obj.exception_ids: |
|||
obj.main_exception_id = obj.exception_ids[0] |
|||
else: |
|||
obj.main_exception_id = False |
|||
|
|||
@api.multi |
|||
def _popup_exceptions(self): |
|||
action = self._get_popup_action() |
|||
action = action.read()[0] |
|||
action.update({ |
|||
'context': { |
|||
'active_id': self.ids[0], |
|||
'active_ids': self.ids |
|||
} |
|||
}) |
|||
return action |
|||
|
|||
@api.model |
|||
def _get_popup_action(self): |
|||
action = self.env.ref('base_exception.action_exception_rule_confirm') |
|||
return action |
|||
|
|||
@api.model |
|||
def _check_exception(self): |
|||
""" |
|||
This method must be used in a constraint that must be created in the |
|||
object that inherits for base.exception. |
|||
for sale : |
|||
@api.constrains('ignore_exception',) |
|||
def sale_check_exception(self): |
|||
... |
|||
... |
|||
self._check_exception |
|||
""" |
|||
exception_ids = self.detect_exceptions() |
|||
if exception_ids: |
|||
exceptions = self.env['exception.rule'].browse(exception_ids) |
|||
raise ValidationError('\n'.join(exceptions.mapped('name'))) |
|||
|
|||
@api.multi |
|||
def test_exceptions(self): |
|||
""" |
|||
Condition method for the workflow from draft to confirm |
|||
""" |
|||
if self.detect_exceptions(): |
|||
return False |
|||
return True |
|||
|
|||
@api.multi |
|||
def detect_exceptions(self): |
|||
"""returns the list of exception_ids for all the considered base.exceptions |
|||
""" |
|||
exception_obj = self.env['exception.rule'] |
|||
all_exceptions = exception_obj.sudo().search( |
|||
[('rule_group', '=', self[0].rule_group)]) |
|||
model_exceptions = all_exceptions.filtered( |
|||
lambda ex: ex.model == self._name) |
|||
sub_exceptions = all_exceptions.filtered( |
|||
lambda ex: ex.model != self._name) |
|||
|
|||
all_exception_ids = [] |
|||
for obj in self: |
|||
if obj.ignore_exception: |
|||
continue |
|||
exception_ids = obj._detect_exceptions( |
|||
model_exceptions, sub_exceptions) |
|||
obj.exception_ids = [(6, 0, exception_ids)] |
|||
all_exception_ids += exception_ids |
|||
return all_exception_ids |
|||
|
|||
@api.model |
|||
def _exception_rule_eval_context(self, obj_name, rec): |
|||
user = self.env['res.users'].browse(self._uid) |
|||
return {obj_name: rec, |
|||
'self': self.pool.get(rec._name), |
|||
'object': rec, |
|||
'obj': rec, |
|||
'pool': self.pool, |
|||
'cr': self._cr, |
|||
'uid': self._uid, |
|||
'user': user, |
|||
'time': time, |
|||
# copy context to prevent side-effects of eval |
|||
'context': self._context.copy()} |
|||
|
|||
@api.model |
|||
def _rule_eval(self, rule, obj_name, rec): |
|||
expr = rule.code |
|||
space = self._exception_rule_eval_context(obj_name, rec) |
|||
try: |
|||
safe_eval(expr, |
|||
space, |
|||
mode='exec', |
|||
nocopy=True) # nocopy allows to return 'result' |
|||
except Exception, e: |
|||
raise UserError( |
|||
_('Error when evaluating the exception.rule ' |
|||
'rule:\n %s \n(%s)') % (rule.name, e)) |
|||
return space.get('failed', False) |
|||
|
|||
@api.multi |
|||
def _detect_exceptions(self, model_exceptions, |
|||
sub_exceptions): |
|||
self.ensure_one() |
|||
exception_ids = [] |
|||
for rule in model_exceptions: |
|||
if self._rule_eval(rule, self.rule_group, self): |
|||
exception_ids.append(rule.id) |
|||
if sub_exceptions: |
|||
for obj_line in self._get_lines(): |
|||
for rule in sub_exceptions: |
|||
if rule.id in exception_ids: |
|||
# we do not matter if the exception as already been |
|||
# found for an line of this object |
|||
# (ex sale order line if obj is sale order) |
|||
continue |
|||
group_line = self.rule_group + '_line' |
|||
if self._rule_eval(rule, group_line, obj_line): |
|||
exception_ids.append(rule.id) |
|||
return exception_ids |
|||
|
|||
@implemented_by_base_exception |
|||
def _get_lines(self): |
|||
pass |
|||
|
|||
def _default_get_lines(self): |
|||
return [] |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
|
|||
<record id="group_exception_rule_manager" model="res.groups"> |
|||
<field name="name">Exception manager</field> |
|||
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/> |
|||
</record> |
|||
|
|||
</odoo> |
@ -0,0 +1,5 @@ |
|||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" |
|||
"access_exception_rule","base.exception","model_exception_rule","base.group_user",1,0,0,0 |
|||
"access_exception_rule_manager","base.exception","model_exception_rule","base_exception.group_exception_rule_manager",1,1,1,1 |
|||
"access_base_exception","base.exception","model_base_exception","base.group_user",1,0,0,0 |
|||
"access_base_exception_manager","base.exception","model_base_exception","base_exception.group_exception_rule_manager",1,1,1,1 |
After Width: 128 | Height: 128 | Size: 9.2 KiB |
@ -0,0 +1,51 @@ |
|||
<?xml version="1.0" ?> |
|||
<odoo> |
|||
|
|||
<record id="view_exception_rule_tree" model="ir.ui.view"> |
|||
<field name="name">exception.rule.tree</field> |
|||
<field name="model">exception.rule</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Exception Rule"> |
|||
<field name="active"/> |
|||
<field name="name"/> |
|||
<field name="description"/> |
|||
<field name="model"/> |
|||
<field name="sequence"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="view_exception_rule_form" model="ir.ui.view"> |
|||
<field name="name">exception.rule.form</field> |
|||
<field name="model">exception.rule</field> |
|||
<field name="arch" type="xml"> |
|||
<form string="Exception Rule Setup" name="exception_rule"> |
|||
<group colspan="4" col="2"> |
|||
<field name="name"/> |
|||
<field name="description"/> |
|||
</group> |
|||
<group colspan="4" groups="base_exception.group_exception_rule_manager"> |
|||
<field name="active"/> |
|||
<field name="sequence"/> |
|||
</group> |
|||
<group colspan="4" col="2" groups="base.group_system"> |
|||
<field name="rule_group"/> |
|||
<field name="model"/> |
|||
<field name="code"/> |
|||
</group> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="action_exception_rule_tree" model="ir.actions.act_window"> |
|||
<field name="name">Exception Rules</field> |
|||
<field name="res_model">exception.rule</field> |
|||
<field name="view_type">form</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="view_id" ref="view_exception_rule_tree"/> |
|||
<field name="context">{'active_test': False}</field> |
|||
</record> |
|||
|
|||
<menuitem action="action_exception_rule_tree" id="menu_action_exception" parent="base_setup.menu_config" /> |
|||
|
|||
</odoo> |
@ -0,0 +1,5 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from . import base_exception_confirm |
@ -0,0 +1,35 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2011 Raphaël Valyi, Renato Lima, Guewen Baconnier, Sodexis |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class ExceptionRuleConfirm(models.AbstractModel): |
|||
|
|||
_name = 'exception.rule.confirm' |
|||
|
|||
related_model_id = fields.Many2one('base.exception',) |
|||
exception_ids = fields.Many2many('exception.rule', |
|||
string='Exceptions to resolve', |
|||
readonly=True) |
|||
ignore = fields.Boolean('Ignore Exceptions') |
|||
|
|||
@api.model |
|||
def default_get(self, field_list): |
|||
res = super(ExceptionRuleConfirm, self).default_get(field_list) |
|||
current_model = self._context.get('active_model') |
|||
model_except_obj = self.env[current_model] |
|||
active_ids = self._context.get('active_ids') |
|||
assert len(active_ids) == 1, "Only 1 ID accepted, got %r" % active_ids |
|||
active_id = active_ids[0] |
|||
related_model_except = model_except_obj.browse(active_id) |
|||
exception_ids = [e.id for e in related_model_except.exception_ids] |
|||
res.update({'exception_ids': [(6, 0, exception_ids)]}) |
|||
res.update({'related_model_id': active_id}) |
|||
return res |
|||
|
|||
@api.multi |
|||
def action_confirm(self): |
|||
self.ensure_one() |
|||
return {'type': 'ir.actions.act_window_close'} |
@ -0,0 +1,39 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<data> |
|||
|
|||
<record id="view_exception_rule_confirm" model="ir.ui.view"> |
|||
<field name="name">Exceptions Rules</field> |
|||
<field name="model">exception.rule.confirm</field> |
|||
<field name="arch" type="xml"> |
|||
<form string="Blocked in draft due to exceptions" version="7.0"> |
|||
<group> |
|||
<field name="exception_ids" nolabel="1" colspan="4"> |
|||
<tree string="Exceptions Rules"> |
|||
<field name="name"/> |
|||
<field name="description"/> |
|||
</tree> |
|||
</field> |
|||
<newline/> |
|||
<field name="ignore" groups='base_exception.group_exception_rule_manager'/> |
|||
</group> |
|||
<footer> |
|||
<button name="action_confirm" string="_Close" |
|||
colspan="1" type="object" icon="gtk-ok" /> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="action_exception_rule_confirm" model="ir.actions.act_window"> |
|||
<field name="name">Blocked in draft due to exceptions</field> |
|||
<field name="type">ir.actions.act_window</field> |
|||
<field name="res_model">exception.rule.confirm</field> |
|||
<field name="view_type">form</field> |
|||
<field name="view_mode">form</field> |
|||
<field name="view_id" ref="view_exception_rule_confirm"/> |
|||
<field name="target">new</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue