From 0992d0973823c296e2f6ec4e9ba9fb9bd615559b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Fri, 18 Dec 2020 21:03:02 +0100 Subject: [PATCH] [IMP] add method exception --- base_exception/__manifest__.py | 1 + base_exception/models/base_exception.py | 36 +++++++++++++++------ base_exception/tests/purchase_test.py | 16 +++++++++ base_exception/tests/test_base_exception.py | 2 +- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/base_exception/__manifest__.py b/base_exception/__manifest__.py index c4a57fb75..6875198c6 100644 --- a/base_exception/__manifest__.py +++ b/base_exception/__manifest__.py @@ -13,6 +13,7 @@ "author": "Akretion, Sodexis, Camptocamp, Odoo Community Association (OCA)", "website": "https://github.com/OCA/server-tools", "depends": ["base_setup"], + "maintainers": ["hparfr", "sebastienbeau"], "license": "AGPL-3", "data": [ "security/base_exception_security.xml", diff --git a/base_exception/models/base_exception.py b/base_exception/models/base_exception.py index 9f777e729..a78a44589 100644 --- a/base_exception/models/base_exception.py +++ b/base_exception/models/base_exception.py @@ -25,17 +25,22 @@ class ExceptionRule(models.Model): model = fields.Selection(selection=[], string="Apply on", required=True) exception_type = fields.Selection( - selection=[("by_domain", "By domain"), ("by_py_code", "By python code")], + selection=[ + ("by_domain", "By domain"), + ("by_py_code", "By python code"), + ("by_method", "By method"), + ], string="Exception Type", required=True, default="by_py_code", help="By python code: allow to define any arbitrary check\n" "By domain: limited to a selection by an odoo domain:\n" - " performance can be better when exceptions " - " are evaluated with several records", + " performance can be better when exceptions" + " are evaluated with several records\n" + "By method: allow to select an existing check method", ) domain = fields.Char("Domain") - + method = fields.Selection(selection=[], string="Method", readonly=True) active = fields.Boolean("Active", default=True) code = fields.Text( "Python Code", @@ -47,16 +52,19 @@ class ExceptionRule(models.Model): help="When checked the exception can not be ignored", ) - @api.constrains("exception_type", "domain", "code") + @api.constrains("exception_type", "domain", "code", "model") def check_exception_type_consistency(self): for rule in self: - if (rule.exception_type == "by_py_code" and not rule.code) or ( - rule.exception_type == "by_domain" and not rule.domain + if ( + (rule.exception_type == "by_py_code" and not rule.code) + or (rule.exception_type == "by_domain" and not rule.domain) + or (rule.exception_type == "by_method" and not rule.method) ): raise ValidationError( _( - "There is a problem of configuration, python code or " - "domain is missing to match the exception type." + "There is a problem of configuration, python code, " + "domain or method is missing to match the exception " + "type." ) ) @@ -160,6 +168,8 @@ class BaseExceptionMethod(models.AbstractModel): return self._detect_exceptions_by_py_code(rule) elif rule.exception_type == "by_domain": return self._detect_exceptions_by_domain(rule) + elif rule.exception_type == "by_method": + return self._detect_exceptions_by_method(rule) def _get_base_domain(self): return [("ignore_exception", "=", False), ("id", "in", self.ids)] @@ -185,6 +195,14 @@ class BaseExceptionMethod(models.AbstractModel): domain = expression.AND([base_domain, rule_domain]) return self.search(domain) + def _detect_exceptions_by_method(self, rule): + """ + Find exceptions found on self. + """ + base_domain = self._get_base_domain() + records = self.search(base_domain) + return getattr(records, rule.method)() + class BaseExceptionModel(models.AbstractModel): _inherit = "base.exception.method" diff --git a/base_exception/tests/purchase_test.py b/base_exception/tests/purchase_test.py index 9d570460f..450284f6a 100644 --- a/base_exception/tests/purchase_test.py +++ b/base_exception/tests/purchase_test.py @@ -4,6 +4,15 @@ from odoo import api, fields, models +class ExceptionRule(models.Model): + _inherit = "exception.rule" + _name = "exception.rule" + + method = fields.Selection( + selection_add=[("exception_method_no_zip", "Purchase exception no zip")] + ) + + class PurchaseTest(models.Model): _inherit = "base.exception" _name = "base.exception.test.purchase" @@ -58,6 +67,13 @@ class PurchaseTest(models.Model): def _reverse_field(self): return "test_purchase_ids" + def exception_method_no_zip(self): + records_fail = self.env["base.exception.test.purchase"] + for rec in self: + if not rec.partner_id.zip: + records_fail += rec + return records_fail + class LineTest(models.Model): _name = "base.exception.test.purchase.line" diff --git a/base_exception/tests/test_base_exception.py b/base_exception/tests/test_base_exception.py index 51d387a56..0ee697a3f 100644 --- a/base_exception/tests/test_base_exception.py +++ b/base_exception/tests/test_base_exception.py @@ -19,7 +19,7 @@ class TestBaseException(common.SavepointCase): @classmethod def setUpClass(cls): super(TestBaseException, cls).setUpClass() - setup_test_model(cls.env, [PurchaseTest, LineTest]) + setup_test_model(cls.env, [PurchaseTest, LineTest, ExceptionRule]) cls.base_exception = cls.env["base.exception"] cls.exception_rule = cls.env["exception.rule"]