From d1927bb7469eece110a68e2c4a74a8a583339bd2 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Mon, 17 Aug 2015 10:32:56 +0200 Subject: [PATCH] [ADD] ir_model: add fields `copy` and `related` on `ir.model.fields` Also add a constraint on the value of field `related`, and corresponding onchange methods. --- openerp/addons/base/base.sql | 2 ++ openerp/addons/base/ir/ir_model.py | 37 ++++++++++++++++++++++++ openerp/addons/base/ir/ir_model_view.xml | 4 +++ openerp/models.py | 4 +++ 4 files changed, 47 insertions(+) diff --git a/openerp/addons/base/base.sql b/openerp/addons/base/base.sql index 6b0812a4b40..0088d054fac 100644 --- a/openerp/addons/base/base.sql +++ b/openerp/addons/base/base.sql @@ -35,6 +35,8 @@ CREATE TABLE ir_model_fields ( relation varchar, relation_field varchar, select_level varchar, + copy boolean, + related varchar, readonly boolean default False, required boolean default False, selectable boolean default False, diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index ab30836feb9..7725d005ad1 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -226,6 +226,8 @@ class ir_model_fields(osv.osv): 'selection': fields.char('Selection Options', help="List of options for a selection field, " "specified as a Python expression defining a list of (key, label) pairs. " "For example: [('blue','Blue'),('yellow','Yellow')]"), + 'copy': fields.boolean('Copied', help="Whether the value is copied when duplicating a record."), + 'related': fields.char('Related Field', help="The corresponding related field, if any. This must be a dot-separated list of field names."), 'required': fields.boolean('Required'), 'readonly': fields.boolean('Readonly'), 'select_level': fields.selection([('0','Not Searchable'),('1','Always Searchable'),('2','Advanced Search (deprecated)')],'Searchable', required=True), @@ -290,6 +292,40 @@ class ir_model_fields(osv.osv): ('size_gt_zero', 'CHECK (size>=0)',_size_gt_zero_msg ), ] + def _related_field(self): + """ Return the ``Field`` instance corresponding to ``self.related``. """ + names = self.related.split(".") + last = len(names) - 1 + model = self.env[self.model or self.model_id.model] + for index, name in enumerate(names): + field = model._fields.get(name) + if field is None: + raise UserError(_("Unknown field name '%s' in related field '%s'") % (name, self.related)) + if index < last and not field.relational: + raise UserError(_("Non-relational field name '%s' in related field '%s'") % (name, self.related)) + model = model[name] + return field + + @api.one + @api.constrains('related') + def _check_related(self): + if self.state == 'manual' and self.related: + field = self._related_field() + if field.type != self.ttype: + raise UserError(_("Related field '%s' does not have type '%s'") % (self.related, self.ttype)) + if field.relational and field.comodel_name != self.relation: + raise UserError(_("Related field '%s' does not have comodel '%s'") % (self.related, self.relation)) + + @api.onchange('related') + def _onchange_related(self): + if self.related: + try: + field = self._related_field() + except UserError as e: + return {'warning': {'title': _("Warning"), 'message': e.message}} + self.ttype = field.type + self.relation = field.comodel_name + @api.model def _custom_many2many_names(self, model_name, comodel_name): """ Return default names for the table and columns of a custom many2many field. """ @@ -303,6 +339,7 @@ class ir_model_fields(osv.osv): @api.onchange('ttype', 'model_id', 'relation') def _onchange_ttype(self): + self.copy = (self.ttype != 'one2many') if self.ttype == 'many2many' and self.model_id and self.relation: names = self._custom_many2many_names(self.model_id.model, self.relation) self.relation_table, self.column1, self.column2 = names diff --git a/openerp/addons/base/ir/ir_model_view.xml b/openerp/addons/base/ir/ir_model_view.xml index 44a44fe66bf..3519736e799 100644 --- a/openerp/addons/base/ir/ir_model_view.xml +++ b/openerp/addons/base/ir/ir_model_view.xml @@ -65,6 +65,7 @@ + @@ -80,6 +81,7 @@ + @@ -170,6 +172,7 @@ + @@ -187,6 +190,7 @@ + diff --git a/openerp/models.py b/openerp/models.py index 5ae59f45e68..e331569f7b4 100644 --- a/openerp/models.py +++ b/openerp/models.py @@ -385,6 +385,8 @@ class BaseModel(object): 'ttype': f.type, 'relation': f.comodel_name or None, 'select_level': tools.ustr(int(f.index)), + 'copy': bool(f.copy), + 'related': f.related and ".".join(f.related), 'readonly': bool(f.readonly), 'required': bool(f.required), 'selectable': bool(f.search or f.store), @@ -670,6 +672,8 @@ class BaseModel(object): attrs = { 'manual': True, 'string': field['field_description'], + 'copy': bool(field['copy']), + 'related': field['related'], 'required': bool(field['required']), 'readonly': bool(field['readonly']), }