##############################################################################
#
# OpenERP, Open Source Business Applications
-# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
+# Copyright (C) 2004-2014 OpenERP S.A. (<http://openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
import openerp
import openerp.modules.registry
from openerp import SUPERUSER_ID
-from openerp import netsvc, pooler, tools
+from openerp import tools
from openerp.osv import fields,osv
-from openerp.osv.orm import Model
+from openerp.osv.orm import Model, browse_null
from openerp.tools.safe_eval import safe_eval as eval
from openerp.tools import config
from openerp.tools.translate import _
def _in_modules(self, cr, uid, ids, field_name, arg, context=None):
#pseudo-method used by fields.function in ir.model/ir.model.fields
- module_pool = self.pool.get("ir.module.module")
+ module_pool = self.pool["ir.module.module"]
installed_module_ids = module_pool.search(cr, uid, [('state','=','installed')])
installed_module_names = module_pool.read(cr, uid, installed_module_ids, ['name'], context=context)
installed_modules = set(x['name'] for x in installed_module_names)
models = self.browse(cr, uid, ids, context=context)
res = dict.fromkeys(ids)
for model in models:
- if self.pool.get(model.model):
- res[model.id] = self.pool.get(model.model).is_transient()
+ if model.model in self.pool:
+ res[model.id] = self.pool[model.model].is_transient()
else:
_logger.error('Missing model %s' % (model.model, ))
return res
models = self.browse(cr, uid, ids)
res = {}
for model in models:
- res[model.id] = self.pool.get("ir.ui.view").search(cr, uid, [('model', '=', model.model)])
+ res[model.id] = self.pool["ir.ui.view"].search(cr, uid, [('model', '=', model.model)])
return res
_columns = {
- 'name': fields.char('Model Description', size=64, translate=True, required=True),
- 'model': fields.char('Model', size=64, required=True, select=1),
+ 'name': fields.char('Model Description', translate=True, required=True),
+ 'model': fields.char('Model', 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),
'osv_memory': fields.function(_is_osv_memory, string='Transient Model', type='boolean',
fnct_search=_search_osv_memory,
help="This field specifies whether the model is transient or not (i.e. if records are automatically deleted from the database or not)"),
- 'modules': fields.function(_in_modules, type='char', size=128, string='In Modules', help='List of modules in which the object is defined or inherited'),
+ 'modules': fields.function(_in_modules, type='char', string='In Modules', help='List of modules in which the object is defined or inherited'),
'view_ids': fields.function(_view_ids, type='one2many', obj='ir.ui.view', string='Views'),
}
def _drop_table(self, cr, uid, ids, context=None):
for model in self.browse(cr, uid, ids, context):
- model_pool = self.pool.get(model.model)
+ model_pool = self.pool[model.model]
cr.execute('select relkind from pg_class where relname=%s', (model_pool._table,))
result = cr.fetchone()
if result and result[0] == 'v':
# only reload pool for normal unlink. For module uninstall the
# reload is done independently in openerp.modules.loading
cr.commit() # must be committed before reloading registry in new cursor
- pooler.restart_pool(cr.dbname)
+ openerp.modules.registry.RegistryManager.new(cr.dbname)
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
return res
field_state='manual',
select=vals.get('select_level', '0'),
update_custom_fields=True)
- self.pool.get(vals['model'])._auto_init(cr, ctx)
- self.pool.get(vals['model'])._auto_end(cr, ctx) # actually create FKs!
+ self.pool[vals['model']]._auto_init(cr, ctx)
+ self.pool[vals['model']]._auto_end(cr, ctx) # actually create FKs!
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
return res
class ir_model_fields(osv.osv):
_name = 'ir.model.fields'
_description = "Fields"
+ _rec_name = 'field_description'
_columns = {
- 'name': fields.char('Name', required=True, size=64, select=1),
- 'model': fields.char('Object Name', size=64, required=True, select=1,
+ 'name': fields.char('Name', required=True, select=1),
+ 'complete_name': fields.char('Complete Name', select=1),
+ 'model': fields.char('Object Name', required=True, select=1,
help="The technical name of the model this field belongs to"),
- 'relation': fields.char('Object Relation', size=64,
+ 'relation': fields.char('Object Relation',
help="For relationship fields, the technical name of the target model"),
- 'relation_field': fields.char('Relation Field', size=64,
+ 'relation_field': fields.char('Relation Field',
help="For one2many fields, the field on the target model that implement the opposite many2one relationship"),
'model_id': fields.many2one('ir.model', 'Model', required=True, select=True, ondelete='cascade',
help="The model this field belongs to"),
- 'field_description': fields.char('Field Label', required=True, size=256),
- 'ttype': fields.selection(_get_fields_type, 'Field Type',size=64, required=True),
- 'selection': fields.char('Selection Options',size=128, help="List of options for a selection field, "
+ 'field_description': fields.char('Field Label', required=True),
+ 'ttype': fields.selection(_get_fields_type, 'Field Type', required=True),
+ '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')]"),
'required': fields.boolean('Required'),
'size': fields.integer('Size'),
'state': fields.selection([('manual','Custom Field'),('base','Base Field')],'Type', required=True, readonly=True, select=1),
'on_delete': fields.selection([('cascade','Cascade'),('set null','Set NULL')], 'On Delete', help='On delete property for many2one fields'),
- 'domain': fields.char('Domain', size=256, help="The optional domain to restrict possible values for relationship fields, "
+ 'domain': fields.char('Domain', help="The optional domain to restrict possible values for relationship fields, "
"specified as a Python expression defining a list of triplets. "
"For example: [('color','=','red')]"),
'groups': fields.many2many('res.groups', 'ir_model_fields_group_rel', 'field_id', 'group_id', 'Groups'),
- 'view_load': fields.boolean('View Auto-Load'),
'selectable': fields.boolean('Selectable'),
- 'modules': fields.function(_in_modules, type='char', size=128, string='In Modules', help='List of modules in which the field is defined'),
+ 'modules': fields.function(_in_modules, type='char', string='In Modules', help='List of modules in which the field is defined'),
'serialization_field_id': fields.many2one('ir.model.fields', 'Serialization Field', domain = "[('ttype','=','serialized')]",
ondelete='cascade', help="If set, this field will be stored in the sparse "
"structure of the serialization field, instead "
}
_rec_name='field_description'
_defaults = {
- 'view_load': 0,
'selection': "",
'domain': "[]",
'name': 'x_',
for field in self.browse(cr, uid, ids, context):
if field.name in MAGIC_COLUMNS:
continue
- model = self.pool.get(field.model)
+ model = self.pool[field.model]
cr.execute('select relkind from pg_class where relname=%s', (model._table,))
result = cr.fetchone()
cr.execute("SELECT column_name FROM information_schema.columns WHERE table_name ='%s' and column_name='%s'" %(model._table, field.name))
def create(self, cr, user, vals, context=None):
if 'model_id' in vals:
- model_data = self.pool.get('ir.model').browse(cr, user, vals['model_id'])
+ model_data = self.pool['ir.model'].browse(cr, user, vals['model_id'])
vals['model'] = model_data.model
if context is None:
context = {}
if not vals['name'].startswith('x_'):
raise except_orm(_('Error'), _("Custom fields must have a name that starts with 'x_' !"))
- if vals.get('relation',False) and not self.pool.get('ir.model').search(cr, user, [('model','=',vals['relation'])]):
+ if vals.get('relation',False) and not self.pool['ir.model'].search(cr, user, [('model','=',vals['relation'])]):
raise except_orm(_('Error'), _("Model %s does not exist!") % vals['relation'])
- if self.pool.get(vals['model']):
- self.pool.get(vals['model']).__init__(self.pool, cr)
+ if vals['model'] in self.pool:
+ self.pool[vals['model']].__init__(self.pool, cr)
#Added context to _auto_init for special treatment to custom field for select_level
ctx = dict(context,
field_name=vals['name'],
field_state='manual',
select=vals.get('select_level', '0'),
update_custom_fields=True)
- self.pool.get(vals['model'])._auto_init(cr, ctx)
- self.pool.get(vals['model'])._auto_end(cr, ctx) # actually create FKs!
+ self.pool[vals['model']]._auto_init(cr, ctx)
+ self.pool[vals['model']]._auto_end(cr, ctx) # actually create FKs!
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
return res
raise except_orm(_('Error!'), _('Renaming sparse field "%s" is not allowed')%field.name)
column_rename = None # if set, *one* column can be renamed here
- obj = None
models_patch = {} # structs of (obj, [(field, prop, change_to),..])
# data to be updated on the orm model
('size', 'size', int),
('on_delete', 'ondelete', str),
('translate', 'translate', bool),
- ('view_load', 'view_load', bool),
('selectable', 'selectable', bool),
('select_level', 'select', int),
('selection', 'selection', eval),
checked_selection = False # need only check it once, so defer
for item in self.browse(cr, user, ids, context=context):
- if not (obj and obj._name == item.model):
- obj = self.pool.get(item.model)
+ obj = self.pool.get(item.model)
if item.state != 'manual':
raise except_orm(_('Error!'),
# We don't check the 'state', because it might come from the context
# (thus be set for multiple fields) and will be ignored anyway.
- if obj:
+ if obj is not None:
models_patch.setdefault(obj._name, (obj,[]))
# find out which properties (per model) we need to update
for field_name, field_property, set_fn in model_props:
"""
_name = 'ir.model.constraint'
_columns = {
- 'name': fields.char('Constraint', required=True, size=128, select=1,
+ 'name': fields.char('Constraint', required=True, select=1,
help="PostgreSQL constraint or foreign key name."),
'model': fields.many2one('ir.model', string='Model',
required=True, select=1),
Delete PostgreSQL foreign keys and constraints tracked by this model.
"""
- if uid != SUPERUSER_ID and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"):
+ if uid != SUPERUSER_ID and not self.pool['ir.model.access'].check_groups(cr, uid, "base.group_system"):
raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module')))
context = dict(context or {})
ids.reverse()
for data in self.browse(cr, uid, ids, context):
model = data.model.model
- model_obj = self.pool.get(model)
+ model_obj = self.pool[model]
name = openerp.tools.ustr(data.name)
typ = data.type
"""
_name = 'ir.model.relation'
_columns = {
- 'name': fields.char('Relation Name', required=True, size=128, select=1,
+ 'name': fields.char('Relation Name', required=True, select=1,
help="PostgreSQL table name implementing a many2many relation."),
'model': fields.many2one('ir.model', string='Model',
required=True, select=1),
Delete PostgreSQL many2many relations tracked by this model.
"""
- if uid != SUPERUSER_ID and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"):
+ if uid != SUPERUSER_ID and not self.pool['ir.model.access'].check_groups(cr, uid, "base.group_system"):
raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module')))
ids_set = set(ids)
class ir_model_access(osv.osv):
_name = 'ir.model.access'
_columns = {
- 'name': fields.char('Name', size=64, required=True, select=True),
+ 'name': fields.char('Name', required=True, select=True),
'active': fields.boolean('Active', help='If you uncheck the active field, it will disable the ACL without deleting it (if you delete a native ACL, it will be re-created when you reload the module.'),
'model_id': fields.many2one('ir.model', 'Object', required=True, domain=[('osv_memory','=', False)], select=True, ondelete='cascade'),
'group_id': fields.many2one('res.groups', 'Group', ondelete='cascade', select=True),
model_name = model
# TransientModel records have no access rights, only an implicit access rule
- if not self.pool.get(model_name):
+ if model_name not in self.pool:
_logger.error('Missing model %s' % (model_name, ))
- elif self.pool.get(model_name).is_transient():
+ elif self.pool[model_name].is_transient():
return True
# We check if a specific rule exists
msg_params = (model_name,)
_logger.warning('Access Denied by ACLs for operation: %s, uid: %s, model: %s', mode, uid, model_name)
msg = '%s %s' % (msg_heads[mode], msg_tail)
- raise except_orm(_('Access Denied'), msg % msg_params)
+ raise openerp.exceptions.AccessError(msg % msg_params)
return r or False
__cache_clearing_methods = []
def call_cache_clearing_methods(self, cr):
self.check.clear_cache(self) # clear the cache of check function
for model, method in self.__cache_clearing_methods:
- object_ = self.pool.get(model)
- if object_:
- getattr(object_, method)()
+ if model in self.pool:
+ getattr(self.pool[model], method)()
#
# Check rights on actions
for model in result:
try:
- r = dict(self.pool.get(model).name_get(cr, uid, result[model].keys(), context=context))
+ r = dict(self.pool[model].name_get(cr, uid, result[model].keys(), context=context))
for key,val in result[model].items():
result2[val] = r.get(key, False)
except:
return result
_columns = {
- 'name': fields.char('External Identifier', required=True, size=128, select=1,
+ 'name': fields.char('External Identifier', required=True, select=1,
help="External Key/Identifier that can be used for "
"data integration with third-party systems"),
'complete_name': fields.function(_complete_name_get, type='char', string='Complete ID'),
'display_name': fields.function(_display_name_get, type='char', string='Record Name'),
- 'model': fields.char('Model Name', required=True, size=64, select=1),
- 'module': fields.char('Module', required=True, size=64, select=1),
+ 'model': fields.char('Model Name', required=True, select=1),
+ 'module': fields.char('Module', required=True, select=1),
'res_id': fields.integer('Record ID', select=1,
help="ID of the target record in the database"),
'noupdate': fields.boolean('Non Updatable'),
if not cr.fetchone():
cr.execute('CREATE INDEX ir_model_data_module_name_index ON ir_model_data (module, name)')
- @tools.ormcache()
- def _get_id(self, cr, uid, module, xml_id):
- """Returns the id of the ir.model.data record corresponding to a given module and xml_id (cached) or raise a ValueError if not found"""
- ids = self.search(cr, uid, [('module','=',module), ('name','=', xml_id)])
+ # NEW V8 API
+ @tools.ormcache(skiparg=3)
+ def xmlid_lookup(self, cr, uid, xmlid):
+ """Low level xmlid lookup
+ Return (id, res_model, res_id) or raise ValueError if not found
+ """
+ module, name = xmlid.split('.', 1)
+ ids = self.search(cr, uid, [('module','=',module), ('name','=', name)])
if not ids:
- raise ValueError('No such external ID currently defined in the system: %s.%s' % (module, xml_id))
+ raise ValueError('External ID not found in the system: %s' % (xmlid))
# the sql constraints ensure us we have only one result
- return ids[0]
+ res = self.read(cr, uid, ids[0], ['model', 'res_id'])
+ if not res['res_id']:
+ raise ValueError('External ID not found in the system: %s' % (xmlid))
+ return ids[0], res['model'], res['res_id']
+
+ def xmlid_to_res_model_res_id(self, cr, uid, xmlid, raise_if_not_found=False):
+ """ Return (res_model, res_id)"""
+ try:
+ return self.xmlid_lookup(cr, uid, xmlid)[1:3]
+ except ValueError:
+ if raise_if_not_found:
+ raise
+ return (False, False)
+
+ def xmlid_to_res_id(self, cr, uid, xmlid, raise_if_not_found=False):
+ """ Returns res_id """
+ return self.xmlid_to_res_model_res_id(cr, uid, xmlid, raise_if_not_found)[1]
+
+ def xmlid_to_object(self, cr, uid, xmlid, raise_if_not_found=False, context=None):
+ """ Return a browse_record
+ if not found and raise_if_not_found is True return the browse_null
+ """
+ t = self.xmlid_to_res_model_res_id(cr, uid, xmlid, raise_if_not_found)
+ res_model, res_id = t
+
+ if res_model and res_id:
+ record = self.pool[res_model].browse(cr, uid, res_id, context=context)
+ if record.exists():
+ return record
+ if raise_if_not_found:
+ raise ValueError('No record found for unique ID %s. It may have been deleted.' % (xml_id))
+ return browse_null()
+
+ # OLD API
+ def _get_id(self, cr, uid, module, xml_id):
+ """Returns the id of the ir.model.data record corresponding to a given module and xml_id (cached) or raise a ValueError if not found"""
+ return self.xmlid_lookup(cr, uid, "%s.%s" % (module, xml_id))[0]
- @tools.ormcache()
def get_object_reference(self, cr, uid, module, xml_id):
"""Returns (model, res_id) corresponding to a given module and xml_id (cached) or raise ValueError if not found"""
- data_id = self._get_id(cr, uid, module, xml_id)
- res = self.read(cr, uid, data_id, ['model', 'res_id'])
- if not res['res_id']:
- raise ValueError('No such external ID currently defined in the system: %s.%s' % (module, xml_id))
- return res['model'], res['res_id']
+ return self.xmlid_lookup(cr, uid, "%s.%s" % (module, xml_id))[1:3]
+
+ def check_object_reference(self, cr, uid, module, xml_id, raise_on_access_error=False):
+ """Returns (model, res_id) corresponding to a given module and xml_id (cached), if and only if the user has the necessary access rights
+ to see that object, otherwise raise a ValueError if raise_on_access_error is True or returns a tuple (model found, False)"""
+ model, res_id = self.get_object_reference(cr, uid, module, xml_id)
+ #search on id found in result to check if current user has read access right
+ check_right = self.pool.get(model).search(cr, uid, [('id', '=', res_id)])
+ if check_right:
+ return model, res_id
+ if raise_on_access_error:
+ raise ValueError('Not enough access rights on the external ID: %s.%s' % (module, xml_id))
+ return model, False
def get_object(self, cr, uid, module, xml_id, context=None):
- """Returns a browsable record for the given module name and xml_id or raise ValueError if not found"""
- res_model, res_id = self.get_object_reference(cr, uid, module, xml_id)
- result = self.pool.get(res_model).browse(cr, uid, res_id, context=context)
- if not result.exists():
- raise ValueError('No record found for unique ID %s.%s. It may have been deleted.' % (module, xml_id))
- return result
+ """ Returns a browsable record for the given module name and xml_id.
+ If not found, raise a ValueError or return a browse_null, depending
+ on the value of `raise_exception`.
+ """
+ return self.xmlid_to_object(cr, uid, "%s.%s" % (module, xml_id), raise_if_not_found=True, context=context)
def _update_dummy(self,cr, uid, model, module, xml_id=False, store=True):
if not xml_id:
:returns: itself
"""
- self._get_id.clear_cache(self)
- self.get_object_reference.clear_cache(self)
+ self.xmlid_lookup.clear_cache(self)
return self
def unlink(self, cr, uid, ids, context=None):
return super(ir_model_data,self).unlink(cr, uid, ids, context=context)
def _update(self,cr, uid, model, module, values, xml_id=False, store=True, noupdate=False, mode='init', res_id=False, context=None):
- model_obj = self.pool.get(model)
+ model_obj = self.pool[model]
if not context:
context = {}
# records created during module install should not display the messages of OpenChatter
return False
action_id = False
if xml_id:
- cr.execute('''SELECT imd.id, imd.res_id, md.id, imd.model
+ cr.execute('''SELECT imd.id, imd.res_id, md.id, imd.model, imd.noupdate
FROM ir_model_data imd LEFT JOIN %s md ON (imd.res_id = md.id)
WHERE imd.module=%%s AND imd.name=%%s''' % model_obj._table,
(module, xml_id))
results = cr.fetchall()
- for imd_id2,res_id2,real_id2,real_model in results:
+ for imd_id2,res_id2,real_id2,real_model,noupdate_imd in results:
+ # In update mode, do not update a record if it's ir.model.data is flagged as noupdate
+ if mode == 'update' and noupdate_imd:
+ return res_id2
if not real_id2:
- self._get_id.clear_cache(self, uid, module, xml_id)
- self.get_object_reference.clear_cache(self, uid, module, xml_id)
+ self.clear_caches()
cr.execute('delete from ir_model_data where id=%s', (imd_id2,))
res_id = False
else:
elif res_id:
model_obj.write(cr, uid, [res_id], values, context=context)
if xml_id:
- self.create(cr, uid, {
- 'name': xml_id,
- 'model': model,
- 'module':module,
- 'res_id':res_id,
- 'noupdate': noupdate,
- },context=context)
if model_obj._inherits:
for table in model_obj._inherits:
inherit_id = model_obj.browse(cr, uid,
'res_id': inherit_id.id,
'noupdate': noupdate,
},context=context)
+ self.create(cr, uid, {
+ 'name': xml_id,
+ 'model': model,
+ 'module':module,
+ 'res_id':res_id,
+ 'noupdate': noupdate,
+ },context=context)
else:
if mode=='init' or (mode=='update' and xml_id):
res_id = model_obj.create(cr, uid, values, context=context)
if xml_id:
- self.create(cr, uid, {
- 'name': xml_id,
- 'model': model,
- 'module': module,
- 'res_id': res_id,
- 'noupdate': noupdate
- },context=context)
if model_obj._inherits:
for table in model_obj._inherits:
inherit_id = model_obj.browse(cr, uid,
'res_id': inherit_id.id,
'noupdate': noupdate,
},context=context)
+ self.create(cr, uid, {
+ 'name': xml_id,
+ 'model': model,
+ 'module': module,
+ 'res_id': res_id,
+ 'noupdate': noupdate
+ },context=context)
if xml_id and res_id:
self.loads[(module, xml_id)] = (model, res_id)
for table, inherit_field in model_obj._inherits.iteritems():
cr.execute('select * from ir_values where model=%s and key=%s and name=%s'+where,(model, key, name))
res = cr.fetchone()
if not res:
- ir_values_obj = pooler.get_pool(cr.dbname).get('ir.values')
+ ir_values_obj = openerp.registry(cr.dbname)['ir.values']
ir_values_obj.set(cr, uid, key, key2, name, models, value, replace, isobject, meta)
elif xml_id:
cr.execute('UPDATE ir_values set value=%s WHERE model=%s and key=%s and name=%s'+where,(value, model, key, name))
ids = self.search(cr, uid, [('module', 'in', modules_to_remove)])
- if uid != 1 and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"):
+ if uid != 1 and not self.pool['ir.model.access'].check_groups(cr, uid, "base.group_system"):
raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module')))
context = dict(context or {})
wkf_todo.extend(cr.fetchall())
cr.execute("update wkf_transition set condition='True', group_id=NULL, signal=NULL,act_to=act_from,act_from=%s where act_to=%s", (res_id,res_id))
- wf_service = netsvc.LocalService("workflow")
for model,res_id in wkf_todo:
try:
- wf_service.trg_write(uid, model, res_id, cr)
+ openerp.workflow.trg_write(uid, model, res_id, cr)
except Exception:
_logger.info('Unable to force processing of workflow for item %s@%s in order to leave activity to be deleted', res_id, model, exc_info=True)
if set(external_ids)-ids_set:
# if other modules have defined this record, we must not delete it
continue
+ if model == 'ir.model.fields':
+ # Don't remove the LOG_ACCESS_COLUMNS unless _log_access
+ # has been turned off on the model.
+ field = self.pool[model].browse(cr, uid, [res_id], context=context)[0]
+ if not field.exists():
+ _logger.info('Deleting orphan external_ids %s', external_ids)
+ self.unlink(cr, uid, external_ids)
+ continue
+ if field.name in openerp.osv.orm.LOG_ACCESS_COLUMNS and self.pool[field.model]._log_access:
+ continue
+ if field.name == 'id':
+ continue
_logger.info('Deleting %s@%s', res_id, model)
try:
cr.execute('SAVEPOINT record_unlink_save')
- self.pool.get(model).unlink(cr, uid, [res_id], context=context)
+ self.pool[model].unlink(cr, uid, [res_id], context=context)
except Exception:
_logger.info('Unable to delete %s@%s', res_id, model, exc_info=True)
cr.execute('ROLLBACK TO SAVEPOINT record_unlink_save')
unlink_if_refcount((model, res_id) for model, res_id in to_unlink
if model == 'ir.model.fields')
- ir_model_relation = self.pool.get('ir.model.relation')
- ir_module_module = self.pool.get('ir.module.module')
+ ir_model_relation = self.pool['ir.model.relation']
+ ir_module_module = self.pool['ir.module.module']
modules_to_remove_ids = ir_module_module.search(cr, uid, [('name', 'in', modules_to_remove)])
relation_ids = ir_model_relation.search(cr, uid, [('module', 'in', modules_to_remove_ids)])
ir_model_relation._module_data_uninstall(cr, uid, relation_ids, context)
return True
to_unlink = []
cr.execute("""SELECT id,name,model,res_id,module FROM ir_model_data
- WHERE module IN %s AND res_id IS NOT NULL AND noupdate=%s
- ORDER BY id DESC""",
+ WHERE module IN %s AND res_id IS NOT NULL AND noupdate=%s ORDER BY id DESC""",
(tuple(modules), False))
for (id, name, model, res_id, module) in cr.fetchall():
if (module,name) not in self.loads:
to_unlink.append((model,res_id))
if not config.get('import_partial'):
for (model, res_id) in to_unlink:
- if self.pool.get(model):
+ if model in self.pool:
_logger.info('Deleting %s@%s', res_id, model)
- self.pool.get(model).unlink(cr, uid, [res_id])
+ self.pool[model].unlink(cr, uid, [res_id])
+
+class wizard_model_menu(osv.osv_memory):
+ _name = 'wizard.ir.model.menu.create'
+ _columns = {
+ 'menu_id': fields.many2one('ir.ui.menu', 'Parent Menu', required=True),
+ 'name': fields.char('Menu Name', size=64, required=True),
+ }
+
+ def menu_create(self, cr, uid, ids, context=None):
+ if not context:
+ context = {}
+ model_pool = self.pool.get('ir.model')
+ for menu in self.browse(cr, uid, ids, context):
+ model = model_pool.browse(cr, uid, context.get('model_id'), context=context)
+ val = {
+ 'name': menu.name,
+ 'res_model': model.model,
+ 'view_type': 'form',
+ 'view_mode': 'tree,form'
+ }
+ action_id = self.pool.get('ir.actions.act_window').create(cr, uid, val)
+ self.pool.get('ir.ui.menu').create(cr, uid, {
+ 'name': menu.name,
+ 'parent_id': menu.menu_id.id,
+ 'action': 'ir.actions.act_window,%d' % (action_id,),
+ 'icon': 'STOCK_INDENT'
+ }, context)
+ return {'type':'ir.actions.act_window_close'}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: