[MERGE] enforce unique `key` attribute for res.currency, ir.model, res.company

For res.company the constraint is made of 2 parts:
 - one normal unique constraint (name,company_id) to catch
   most cases and define the user error message
 - one additional unique index to enforce the unique currency
   name even for multiple entries with NULL company_id, not
   caught by the constraint. The index is named with the 
   constraint name as prefix, in order to automatically
   share the user error message

Also, cleanup up the res.currency views a bit, and improved
field labels in ir.model to make them easier to understand.

lp bug: https://launchpad.net/bugs/789019 fixed

bzr revid: odo@openerp.com-20110919144821-708avl7t9q7g8vpr
This commit is contained in:
Olivier Dony 2011-09-19 16:48:21 +02:00
commit 8c5cb638b9
6 changed files with 36 additions and 9 deletions

View File

@ -1599,6 +1599,7 @@
<field name="rounding">0.01</field>
<field name="accuracy">4</field>
<field name="symbol">¢</field>
<field name="company_id" ref="main_company"/>
</record>
<record id="rateCRC" model="res.currency.rate">
<field name="rate">691.3153</field>

View File

@ -1274,7 +1274,7 @@
<record id="action_model_model" model="ir.actions.act_window">
<field name="name">Objects</field>
<field name="name">Models</field>
<field name="res_model">ir.model</field>
<field name="view_type">form</field>
<field name="context">{'manual':True}</field>

View File

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

View File

@ -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):

View File

@ -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')

View File

@ -9,7 +9,7 @@
<field name="arch" type="xml">
<tree string="Currencies">
<field name="name"/>
<field name="company_id" select="2" />
<field name="company_id" groups="base.group_multi_company"/>
<field name="rate_ids" invisible="1"/>
<field name="date"/>
<field name="rate"/>
@ -26,9 +26,9 @@
<field name="arch" type="xml">
<form string="Currency">
<group col="6" colspan="6">
<field name="name" select="1"/>
<field name="name"/>
<field name="rate"/>
<field name="company_id" select="2" groups="base.group_multi_company" />
<field name="company_id" groups="base.group_multi_company"/>
<field name="symbol"/>
</group>