summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael Collet <rco@openerp.com>2015-08-17 10:32:56 +0200
committerRaphael Collet <rco@openerp.com>2015-08-18 14:53:04 +0200
commitd1927bb7469eece110a68e2c4a74a8a583339bd2 (patch)
treec9379175dedacdce3bbc9acce8ca63c8cfd70fb0
parent78577a606d0303c06d6b1346e03e5581c915167a (diff)
[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.
-rw-r--r--openerp/addons/base/base.sql2
-rw-r--r--openerp/addons/base/ir/ir_model.py37
-rw-r--r--openerp/addons/base/ir/ir_model_view.xml4
-rw-r--r--openerp/models.py4
4 files changed, 47 insertions, 0 deletions
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 @@
</group>
<group string="Properties">
<group>
+ <field name="related"/>
<field name="ttype"/>
<field name="relation" attrs="{'required': [('ttype','in',['many2one','one2many','many2many'])],'readonly': [('ttype','!=','one2many'), ('ttype','!=','many2one'), ('ttype','!=','many2many')]}"/>
<field name="relation_field" attrs="{'required': [('ttype','=','one2many')], 'readonly': [('ttype','!=','one2many')]}"/>
@@ -80,6 +81,7 @@
<field name="required"/>
<field name="readonly"/>
<field name="select_level"/>
+ <field name="copy"/>
<field name="translate"/>
<field name="on_delete" attrs="{'readonly': [('ttype','!=','many2one')]}"/>
<field name="modules"/>
@@ -170,6 +172,7 @@
</group>
<group>
<group>
+ <field name="related"/>
<field name="ttype"/>
<field name="relation" attrs="{'required': [('ttype','in', ['many2one','one2many','many2many'])],
'readonly': [('ttype','not in', ['many2one','one2many','many2many'])]}"/>
@@ -187,6 +190,7 @@
<field name="required"/>
<field name="readonly"/>
<field name="select_level"/>
+ <field name="copy"/>
<field name="translate"/>
</group>
</group>
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']),
}