From 1eaa72adf9b72780399e61d5e9ae91c0bce5a0ee Mon Sep 17 00:00:00 2001 From: Lorenzo Battistini Date: Sun, 15 Mar 2015 10:54:29 +0100 Subject: [PATCH] [REF] module renamed to base_field_validator --- base_field_validator/__init__.py | 21 ++++ base_field_validator/__openerp__.py | 48 ++++++++ base_field_validator/ir_model.py | 111 ++++++++++++++++++ base_field_validator/ir_model_demo.xml | 9 ++ base_field_validator/ir_model_field_regex.py | 33 ++++++ base_field_validator/ir_model_view.xml | 22 ++++ .../security/ir.model.access.csv | 5 + base_field_validator/test/validator.yml | 30 +++++ 8 files changed, 279 insertions(+) create mode 100644 base_field_validator/__init__.py create mode 100644 base_field_validator/__openerp__.py create mode 100644 base_field_validator/ir_model.py create mode 100644 base_field_validator/ir_model_demo.xml create mode 100644 base_field_validator/ir_model_field_regex.py create mode 100644 base_field_validator/ir_model_view.xml create mode 100644 base_field_validator/security/ir.model.access.csv create mode 100644 base_field_validator/test/validator.yml diff --git a/base_field_validator/__init__.py b/base_field_validator/__init__.py new file mode 100644 index 000000000..e556f3b5c --- /dev/null +++ b/base_field_validator/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2014 Agile Business Group sagl () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import ir_model +from . import ir_model_field_regex diff --git a/base_field_validator/__openerp__.py b/base_field_validator/__openerp__.py new file mode 100644 index 000000000..b91ed9981 --- /dev/null +++ b/base_field_validator/__openerp__.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2014 Agile Business Group sagl () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +{ + 'name': "Fields Validator", + 'version': '0.1', + 'category': 'Tools', + 'summary': "", + 'description': """ +This module allows to set a regular expresion as field validator. +When the regular expresion is set, write and create operations on the involved +field are blocked, if the regular expression is not satisfied. +See demo and test data for an example with partner email. +""", + 'author': 'Agile Business Group', + 'website': 'http://www.agilebg.com', + 'license': 'AGPL-3', + "depends": ['base'], + "data": [ + 'ir_model_view.xml', + 'security/ir.model.access.csv', + ], + "demo": [ + 'ir_model_demo.xml', + ], + 'test': [ + 'test/validator.yml', + ], + "active": False, + "installable": True +} diff --git a/base_field_validator/ir_model.py b/base_field_validator/ir_model.py new file mode 100644 index 000000000..70f050b2a --- /dev/null +++ b/base_field_validator/ir_model.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2014 Agile Business Group sagl () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.osv import orm, fields +import re +from openerp.tools.translate import _ +import openerp +from openerp import SUPERUSER_ID + + +class IrModel(orm.Model): + + _inherit = 'ir.model' + _columns = { + 'validator_line_ids': fields.one2many( + 'ir.model.validator.line', 'name', 'Validators'), + } + + def check_vals(self, cr, uid, vals, model, context=None): + for validator_line in model.validator_line_ids: + if validator_line.field_id.name in vals: + pattern = re.compile(validator_line.regex_id.regex) + if not pattern.match(vals[validator_line.field_id.name]): + raise orm.except_orm( + _('Error'), + _('Expression %s not passed for %s') % ( + validator_line.regex_id.regex, + vals[validator_line.field_id.name])) + return True + + def _wrap_create(self, old_create, model): + def wrapper(cr, uid, vals, context=None, **kwargs): + self.check_vals(cr, uid, vals, model, context=context) + new_id = old_create(cr, uid, vals, context=context, **kwargs) + return new_id + + return wrapper + + def _wrap_write(self, old_write, model): + def wrapper(cr, uid, ids, vals, context=None, **kwargs): + self.check_vals(cr, uid, vals, model, context=context) + old_write(cr, uid, ids, vals, context=context, **kwargs) + return True + + return wrapper + + def _register_hook(self, cr, ids=None): + """ Wrap the methods `create` and `write` of the model + """ + if ids is None: + ids = self.search(cr, SUPERUSER_ID, []) + updated = False + for model in self.browse(cr, SUPERUSER_ID, ids): + if model.validator_line_ids: + model_name = model.model + model_obj = self.pool.get(model_name) + if model_obj and not hasattr( + model_obj, 'field_validator_checked' + ): + model_obj.create = self._wrap_create( + model_obj.create, model) + model_obj.write = self._wrap_write(model_obj.write, model) + model_obj.field_validator_checked = True + updated = True + return updated + + def create(self, cr, uid, vals, context=None): + res_id = super(IrModel, self).create( + cr, uid, vals, context=context) + if self._register_hook(cr, [res_id]): + openerp.modules.registry.RegistryManager.\ + signal_registry_change(cr.dbname) + return res_id + + def write(self, cr, uid, ids, vals, context=None): + if isinstance(ids, (int, long)): + ids = [ids] + super(IrModel, self).write(cr, uid, ids, vals, context=context) + if self._register_hook(cr, ids): + openerp.modules.registry.RegistryManager.\ + signal_registry_change(cr.dbname) + return True + + +class IrModelValidatorLine(orm.Model): + _name = "ir.model.validator.line" + _columns = { + 'name': fields.many2one('ir.model', string="Model", required=True), + 'field_id': fields.many2one( + 'ir.model.fields', 'Field', required=True), + 'regex_id': fields.many2one( + 'ir.model.fields.regex', string="Validator", + required=True), + } diff --git a/base_field_validator/ir_model_demo.xml b/base_field_validator/ir_model_demo.xml new file mode 100644 index 000000000..857a7b642 --- /dev/null +++ b/base_field_validator/ir_model_demo.xml @@ -0,0 +1,9 @@ + + + + + [^@]+@[^@]+\.[^@]+ + Email + + + diff --git a/base_field_validator/ir_model_field_regex.py b/base_field_validator/ir_model_field_regex.py new file mode 100644 index 000000000..f9764d399 --- /dev/null +++ b/base_field_validator/ir_model_field_regex.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2014 Agile Business Group sagl () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.osv import orm, fields + + +class IrModelFieldsRegex(orm.Model): + _name = "ir.model.fields.regex" + _columns = { + 'name': fields.char('Description', size=512, required=True), + 'regex': fields.char( + 'Regular Expression', size=512, required=True, + help="Regular expression used to validate the field. For example, " + "you can add the expression\n%s\nto the email field" + % r'\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b'), + } diff --git a/base_field_validator/ir_model_view.xml b/base_field_validator/ir_model_view.xml new file mode 100644 index 000000000..de80f39fb --- /dev/null +++ b/base_field_validator/ir_model_view.xml @@ -0,0 +1,22 @@ + + + + + ir.model + + + + + + + + + + + + + + + + diff --git a/base_field_validator/security/ir.model.access.csv b/base_field_validator/security/ir.model.access.csv new file mode 100644 index 000000000..ff026f68f --- /dev/null +++ b/base_field_validator/security/ir.model.access.csv @@ -0,0 +1,5 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"access_ir_model_regex_erp_manager","ir_model_regex group_erp_manager","model_ir_model_fields_regex","base.group_erp_manager",1,1,1,1 +"access_ir_model_regex_all","access_ir_model_regex_all","model_ir_model_fields_regex",,1,0,0,0 +"access_ir_model_validator_line_erp_manager","ir_model_validator_line group_erp_manager","model_ir_model_validator_line","base.group_erp_manager",1,1,1,1 +"access_ir_model_validator_line_all","access_ir_model_validator_line_all","model_ir_model_validator_line",,1,0,0,0 diff --git a/base_field_validator/test/validator.yml b/base_field_validator/test/validator.yml new file mode 100644 index 000000000..ef6f6c0f6 --- /dev/null +++ b/base_field_validator/test/validator.yml @@ -0,0 +1,30 @@ +- + set regex for partner +- + !python {model: ir.model}: | + self.write(cr, uid, [ref('base.model_res_partner')], { + 'validator_line_ids': [(0,0, + { + 'name': ref('base.model_res_partner'), + 'field_id': ref('base.field_res_partner_email'), + 'regex_id': ref('regex_mail'), + })], + }) +- + Set valid email +- + !record {model: res.partner, id: base.res_partner_12}: + email: 'info@agilebg.com' +- + Try invalid email +- + !python {model: res.partner}: | + from openerp.osv import orm + try: + self.write(cr, uid, [ref('base.res_partner_12')], { + 'email': 'john', + }) + assert False, "An exception should have been raised, 'john' is not a valid email!" + except orm.except_orm: + # exception was raised as expected + pass