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 @@
- + - +