diff --git a/openerp/addons/base/base_data.xml b/openerp/addons/base/base_data.xml
index 35666152751..9b41fb872a6 100644
--- a/openerp/addons/base/base_data.xml
+++ b/openerp/addons/base/base_data.xml
@@ -1599,6 +1599,7 @@
0.01
4
ยข
+
691.3153
diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml
index 7d4c4463d01..a947eda4785 100644
--- a/openerp/addons/base/ir/ir.xml
+++ b/openerp/addons/base/ir/ir.xml
@@ -1274,7 +1274,7 @@
- Objects
+ Models
ir.model
form
{'manual':True}
diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py
index 2cfb5143159..2e273f53b69 100644
--- a/openerp/addons/base/ir/ir_model.py
+++ b/openerp/addons/base/ir/ir_model.py
@@ -56,7 +56,7 @@ def _in_modules(self, cr, uid, ids, field_name, arg, context=None):
class ir_model(osv.osv):
_name = 'ir.model'
- _description = "Objects"
+ _description = "Models"
_order = 'model'
def _is_osv_memory(self, cr, uid, ids, field_name, arg, context=None):
@@ -85,8 +85,8 @@ class ir_model(osv.osv):
return res
_columns = {
- 'name': fields.char('Object Name', size=64, translate=True, required=True),
- 'model': fields.char('Object', size=64, required=True, select=1),
+ 'name': fields.char('Model Description', size=64, translate=True, required=True),
+ 'model': fields.char('Model', size=64, required=True, select=1),
'info': fields.text('Information'),
'field_id': fields.one2many('ir.model.fields', 'model_id', 'Fields', required=True),
'state': fields.selection([('manual','Custom Object'),('base','Base Object')],'Type',readonly=True),
@@ -97,12 +97,12 @@ class ir_model(osv.osv):
'modules': fields.function(_in_modules, method=True, type='char', size=128, string='In modules', help='List of modules in which the object is defined or inherited'),
'view_ids': fields.function(_view_ids, method=True, type='one2many', obj='ir.ui.view', string='Views'),
}
-
+
_defaults = {
'model': lambda *a: 'x_',
'state': lambda self,cr,uid,ctx=None: (ctx and ctx.get('manual',False)) and 'manual' or 'base',
}
-
+
def _check_model_name(self, cr, uid, ids, context=None):
for model in self.browse(cr, uid, ids, context=context):
if model.state=='manual':
@@ -114,9 +114,13 @@ class ir_model(osv.osv):
def _model_name_msg(self, cr, uid, ids, context=None):
return _('The Object name must start with x_ and not contain any special character !')
+
_constraints = [
(_check_model_name, _model_name_msg, ['model']),
]
+ _sql_constraints = [
+ ('obj_name_uniq', 'unique (model)', 'Each model must be unique!'),
+ ]
# overridden to allow searching both on model name (model field)
# and model description (name field)
diff --git a/openerp/addons/base/res/res_company.py b/openerp/addons/base/res/res_company.py
index 3ad0cfcfb55..dc07b55a78e 100644
--- a/openerp/addons/base/res/res_company.py
+++ b/openerp/addons/base/res/res_company.py
@@ -143,6 +143,9 @@ class res_company(osv.osv):
'vat': fields.related('partner_id', 'vat', string="Tax ID", type="char", size=32),
'company_registry': fields.char('Company Registry', size=64),
}
+ _sql_constraints = [
+ ('name_uniq', 'unique (name)', 'The company name must be unique !')
+ ]
def _search(self, cr, uid, args, offset=0, limit=None, order=None,
context=None, count=False, access_rights_uid=None):
diff --git a/openerp/addons/base/res/res_currency.py b/openerp/addons/base/res/res_currency.py
index 5c2221d0728..4a02d351e97 100644
--- a/openerp/addons/base/res/res_currency.py
+++ b/openerp/addons/base/res/res_currency.py
@@ -68,8 +68,27 @@ class res_currency(osv.osv):
_defaults = {
'active': lambda *a: 1,
}
+ _sql_constraints = [
+ # this constraint does not cover all cases due to SQL NULL handling for company_id,
+ # so it is complemented with a unique index (see below). The constraint and index
+ # share the same prefix so that IntegrityError triggered by the index will be caught
+ # and reported to the user with the constraint's error message.
+ ('unique_name_company_id', 'unique (name, company_id)', 'The currency code must be unique per company!'),
+ ]
_order = "name"
+ def init(self, cr):
+ # CONSTRAINT/UNIQUE INDEX on (name,company_id)
+ # /!\ The unique constraint 'unique_name_company_id' is not sufficient, because SQL92
+ # only support field names in constraint definitions, and we need a function here:
+ # we need to special-case company_id to treat all NULL company_id as equal, otherwise
+ # we would allow duplicate "global" currencies (all having company_id == NULL)
+ cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'res_currency_unique_name_company_id_idx'""")
+ if not cr.fetchone():
+ cr.execute("""CREATE UNIQUE INDEX res_currency_unique_name_company_id_idx
+ ON res_currency
+ (name, (COALESCE(company_id,-1)))""")
+
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
res = super(osv.osv, self).read(cr, user, ids, fields, context, load)
currency_rate_obj = self.pool.get('res.currency.rate')
diff --git a/openerp/addons/base/res/res_currency_view.xml b/openerp/addons/base/res/res_currency_view.xml
index 8d747c882b1..dd2c83a630f 100644
--- a/openerp/addons/base/res/res_currency_view.xml
+++ b/openerp/addons/base/res/res_currency_view.xml
@@ -9,7 +9,7 @@
-
+
@@ -26,9 +26,9 @@