Skip to content
21 changes: 21 additions & 0 deletions base_field_validator/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2014 Agile Business Group sagl (<http://www.agilebg.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import ir_model
from . import ir_model_field_regex
90 changes: 90 additions & 0 deletions base_field_validator/__openerp__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2014 Agile Business Group sagl (<http://www.agilebg.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################

{
'name': "Fields Validator",
'version': '0.1',
'category': 'Tools',
'summary': "Validate fields using regular expressions",
'description': """
Fields Validator
================

This module allows to set a regular expression 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.


Configuration
=============

Open ir.model form (say res.partner) and add 'Validators' lines


Known issues / Roadmap
======================

The module performs the check at server side. Client side check is also needed,
to improve user experience and avoid server calls when unnecessary


Credits
=======

Contributors
------------

* Lorenzo Battistini <lorenzo.battistini@agilebg.com>
* Nicola Malcontenti <nicola.malcontenti@agilebg.com>

Maintainer
----------

.. image:: http://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://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 http://odoo-community.org.

""",
'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
}
112 changes: 112 additions & 0 deletions base_field_validator/ir_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2014 Agile Business Group sagl (<http://www.agilebg.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################

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 valid 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)
res = old_write(cr, uid, ids, vals, context=context, **kwargs)
return res

return wrapper

def _register_hook(self, cr, ids=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call super

""" Wrap the methods `create` and `write` of the model
"""
res = super(IrModel, self)._register_hook(cr)
if ids is None:
ids = self.search(
cr, SUPERUSER_ID, [('validator_line_ids', '!=', False)])
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
if updated:
openerp.modules.registry.RegistryManager.\
signal_registry_change(cr.dbname)
return res

def create(self, cr, uid, vals, context=None):
res_id = super(IrModel, self).create(
cr, uid, vals, context=context)
self._register_hook(cr, [res_id])
return res_id

def write(self, cr, uid, ids, vals, context=None):
if isinstance(ids, (int, long)):
ids = [ids]
res = super(IrModel, self).write(cr, uid, ids, vals, context=context)
self._register_hook(cr, ids)
return res


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),
}
9 changes: 9 additions & 0 deletions base_field_validator/ir_model_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="regex_mail" model="ir.model.fields.regex">
<field name="regex">[^@]+@[^@]+\.[^@]+</field>
<field name="name">Email</field>
</record>
</data>
</openerp>
33 changes: 33 additions & 0 deletions base_field_validator/ir_model_field_regex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2014 Agile Business Group sagl (<http://www.agilebg.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################

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'),
}
22 changes: 22 additions & 0 deletions base_field_validator/ir_model_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_model_form_validator" model="ir.ui.view">
<field name="model">ir.model</field>
<field name="inherit_id" ref="base.view_model_form"></field>
<field name="arch" type="xml">
<notebook position="inside">
<page string="Validators">
<field name="validator_line_ids">
<tree editable="bottom">
<field name="field_id"
domain="[('model_id','=',parent.id)]"></field>
<field name="regex_id"></field>
</tree>
</field>
</page>
</notebook>
</field>
</record>
</data>
</openerp>
5 changes: 5 additions & 0 deletions base_field_validator/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -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
Binary file added base_field_validator/static/src/img/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions base_field_validator/test/validator.yml
Original file line number Diff line number Diff line change
@@ -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