summaryrefslogtreecommitdiff
path: root/bin/addons/base
diff options
context:
space:
mode:
authorJay (Open ERP) <jvo@tinyerp.com>2010-05-20 12:00:44 +0530
committerJay (Open ERP) <jvo@tinyerp.com>2010-05-20 12:00:44 +0530
commite3ccef27d33ff83ddbb7bfd3eacc80f8a98bd21d (patch)
treef14fb77ab9702c91bcb9309724e5aa63a96ee570 /bin/addons/base
parent2669744f4f09ca6ac9219dc91909e895559c74c0 (diff)
parentfe7673b7ba1f2706b8ed2abe6892ad33211063cd (diff)
[BACKPORT] Stable fixes and refactorings to Trunk
bzr revid: jvo@tinyerp.com-20100520063044-sviy1e9pybirhpsw
Diffstat (limited to 'bin/addons/base')
-rw-r--r--bin/addons/base/ir/ir.xml4
-rw-r--r--bin/addons/base/ir/ir_actions.py38
-rw-r--r--bin/addons/base/ir/ir_cron.py3
-rw-r--r--bin/addons/base/ir/ir_model.py10
-rw-r--r--bin/addons/base/ir/ir_translation.py12
-rw-r--r--bin/addons/base/ir/ir_ui_menu.py28
-rw-r--r--bin/addons/base/ir/ir_ui_view.py4
-rw-r--r--bin/addons/base/module/module.py10
-rw-r--r--bin/addons/base/res/partner/partner_demo.xml20
-rw-r--r--bin/addons/base/res/res_lang.py7
-rw-r--r--bin/addons/base/res/res_security.xml10
-rw-r--r--bin/addons/base/res/res_user.py19
-rw-r--r--bin/addons/base/security/ir.model.access.csv2
13 files changed, 121 insertions, 46 deletions
diff --git a/bin/addons/base/ir/ir.xml b/bin/addons/base/ir/ir.xml
index edafae1af1c..1169798fe8e 100644
--- a/bin/addons/base/ir/ir.xml
+++ b/bin/addons/base/ir/ir.xml
@@ -1302,14 +1302,14 @@
<field name="subject" colspan="4" attrs="{'required':[('state','=','email')]}"/>
<field name="message" select="2" colspan="4" attrs="{'required':[('state','=','email')]}"/>
<newline/>
- <label colspan="4" string="Access all the fields related to the current object using expression in double brackets, i.e.[[ object.partner_id.name ]]" align="0.0"/>
+ <label colspan="4" string="Access all the fields related to the current object using expressions, i.e. object.partner_id.name " align="0.0"/>
</page>
<page string="SMS Configuration" attrs="{'invisible':[('state','!=','sms')]}">
<separator colspan="4" string="SMS Configuration"/>
<field name="mobile" domain="[('model_id','=',model_id)]" attrs="{'required':[('state','=','sms')]}"/>
<field name="sms" colspan="4" attrs="{'required':[('state','=','sms')]}"/>
<newline/>
- <label colspan="4" string="Access all the fields related to the current object using expression in double brackets, i.e. [[ object.partner_id.name ]]" align="0.0"/>
+ <label colspan="4" string="Access all the fields related to the current object using expressions, i.e. object.partner_id.name " align="0.0"/>
</page>
<page string="Create / Write / Copy" attrs="{'invisible':[('state','!=','object_create'), ('state','!=','object_write'), ('state','!=','object_copy')]}">
<separator colspan="4" string="Fields Mapping"/>
diff --git a/bin/addons/base/ir/ir_actions.py b/bin/addons/base/ir/ir_actions.py
index dd5cbc833b4..6c51ab2f771 100644
--- a/bin/addons/base/ir/ir_actions.py
+++ b/bin/addons/base/ir/ir_actions.py
@@ -455,7 +455,7 @@ class actions_server(osv.osv):
'type': lambda *a: 'ir.actions.server',
'sequence': lambda *a: 5,
'code': lambda *a: """# You can use the following variables
-# - object
+# - object or obj
# - time
# - cr
# - uid
@@ -532,7 +532,6 @@ class actions_server(osv.osv):
def run(self, cr, uid, ids, context={}):
logger = netsvc.Logger()
-
for action in self.browse(cr, uid, ids, context):
obj_pool = self.pool.get(action.model_id.model)
obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
@@ -554,19 +553,26 @@ class actions_server(osv.osv):
return self.pool.get(action.action_id.type)\
.read(cr, uid, action.action_id.id, context=context)
- if action.state == 'code':
- localdict = {
- 'self': self.pool.get(action.model_id.model),
- 'context': context,
- 'time': time,
- 'ids': ids,
- 'cr': cr,
- 'uid': uid,
- 'object':obj
- }
- exec action.code in localdict
- if 'action' in localdict:
- return localdict['action']
+ if config['server_actions_allow_code']:
+ localdict = {
+ 'self': self.pool.get(action.model_id.model),
+ 'context': context,
+ 'time': time,
+ 'ids': ids,
+ 'cr': cr,
+ 'uid': uid,
+ 'object':obj,
+ 'obj': obj,
+ }
+ exec action.code in localdict
+ if 'action' in localdict:
+ return localdict['action']
+ else:
+ netsvc.Logger().notifyChannel(
+ self._name, netsvc.LOG_ERROR,
+ "%s is a `code` server action, but "
+ "it isn't allowed in this configuration.\n\n"
+ "See server options to enable it"%action)
if action.state == 'email':
user = config['email_from']
@@ -580,7 +586,7 @@ class actions_server(osv.osv):
logger.notifyChannel('email', netsvc.LOG_INFO, 'Partner Email address not Specified!')
continue
if not user:
- raise osv.except_osv(_('Error'), _("Please specify server option --smtp-from !"))
+ raise osv.except_osv(_('Error'), _("Please specify server option --email-from !"))
subject = self.merge_message(cr, uid, action.subject, action, context)
body = self.merge_message(cr, uid, action.message, action, context)
diff --git a/bin/addons/base/ir/ir_cron.py b/bin/addons/base/ir/ir_cron.py
index dcf76945904..66ead94be48 100644
--- a/bin/addons/base/ir/ir_cron.py
+++ b/bin/addons/base/ir/ir_cron.py
@@ -146,16 +146,19 @@ class ir_cron(osv.osv, netsvc.Agent):
def create(self, cr, uid, vals, context=None):
res = super(ir_cron, self).create(cr, uid, vals, context=context)
cr.commit()
+ self.cancel(cr.dbname)
self._poolJobs(cr.dbname)
return res
def write(self, cr, user, ids, vals, context=None):
res = super(ir_cron, self).write(cr, user, ids, vals, context=context)
cr.commit()
+ self.cancel(cr.dbname)
self._poolJobs(cr.dbname)
return res
def unlink(self, cr, uid, ids, context=None):
res = super(ir_cron, self).unlink(cr, uid, ids, context=context)
cr.commit()
+ self.cancel(cr.dbname)
self._poolJobs(cr.dbname)
return res
ir_cron()
diff --git a/bin/addons/base/ir/ir_model.py b/bin/addons/base/ir/ir_model.py
index f6412e85b75..888432e7968 100644
--- a/bin/addons/base/ir/ir_model.py
+++ b/bin/addons/base/ir/ir_model.py
@@ -82,6 +82,8 @@ class ir_model(osv.osv):
return super(ir_model,self).write(cr, user, ids, vals, context)
def create(self, cr, user, vals, context=None):
+ if context is None:
+ context = {}
if context and context.get('manual',False):
vals['state']='manual'
res = super(ir_model,self).create(cr, user, vals, context)
@@ -260,6 +262,8 @@ class ir_model_fields(osv.osv):
if 'model_id' in vals:
model_data = self.pool.get('ir.model').browse(cr, user, vals['model_id'])
vals['model'] = model_data.model
+ if context is None:
+ context = {}
if context and context.get('manual',False):
vals['state'] = 'manual'
res = super(ir_model_fields,self).create(cr, user, vals, context)
@@ -267,7 +271,7 @@ class ir_model_fields(osv.osv):
if not vals['name'].startswith('x_'):
raise except_orm(_('Error'), _("Custom fields must have a name that starts with 'x_' !"))
- if 'relation' in vals and not self.pool.get('ir.model').search(cr, user, [('model','=',vals['relation'])]):
+ if vals.get('relation',False) and not self.pool.get('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']):
@@ -286,7 +290,7 @@ class ir_model_access(osv.osv):
_columns = {
'name': fields.char('Name', size=64, required=True),
'model_id': fields.many2one('ir.model', 'Object', required=True),
- 'group_id': fields.many2one('res.groups', 'Group'),
+ 'group_id': fields.many2one('res.groups', 'Group', ondelete='cascade'),
'perm_read': fields.boolean('Read Access'),
'perm_write': fields.boolean('Write Access'),
'perm_create': fields.boolean('Create Access'),
@@ -453,7 +457,7 @@ class ir_model_data(osv.osv):
def _get_id(self, cr, uid, module, xml_id):
ids = self.search(cr, uid, [('module','=',module),('name','=', xml_id)])
if not ids:
- raise Exception('No references to %s.%s' % (module, xml_id))
+ raise ValueError('No references to %s.%s' % (module, xml_id))
# the sql constraints ensure us we have only one result
return ids[0]
diff --git a/bin/addons/base/ir/ir_translation.py b/bin/addons/base/ir/ir_translation.py
index 73536ac339f..8e575b6b242 100644
--- a/bin/addons/base/ir/ir_translation.py
+++ b/bin/addons/base/ir/ir_translation.py
@@ -150,8 +150,8 @@ class ir_translation(osv.osv):
if not context:
context = {}
ids = super(ir_translation, self).create(cursor, user, vals, context=context)
- for trans_obj in self.read(cursor, user, [ids], ['name','type','res_id'], context=context):
- self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], lang=context.get('lang','en_US'))
+ for trans_obj in self.read(cursor, user, [ids], ['name','type','res_id','src','lang'], context=context):
+ self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], source=trans_obj['src'])
self._get_ids.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], context.get('lang','en_US'), [trans_obj['res_id']])
return ids
@@ -159,16 +159,16 @@ class ir_translation(osv.osv):
if not context:
context = {}
result = super(ir_translation, self).write(cursor, user, ids, vals, context=context)
- for trans_obj in self.read(cursor, user, ids, ['name','type','res_id'], context=context):
- self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], lang=context.get('lang','en_US'))
+ for trans_obj in self.read(cursor, user, ids, ['name','type','res_id','src','lang'], context=context):
+ self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], source=trans_obj['src'])
self._get_ids.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], context.get('lang','en_US'), [trans_obj['res_id']])
return result
def unlink(self, cursor, user, ids, context=None):
if not context:
context = {}
- for trans_obj in self.read(cursor, user, ids, ['name','type','res_id'], context=context):
- self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], lang=context.get('lang','en_US'))
+ for trans_obj in self.read(cursor, user, ids, ['name','type','res_id','src','lang'], context=context):
+ self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], source=trans_obj['src'])
self._get_ids.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], context.get('lang','en_US'), [trans_obj['res_id']])
result = super(ir_translation, self).unlink(cursor, user, ids, context=context)
return result
diff --git a/bin/addons/base/ir/ir_ui_menu.py b/bin/addons/base/ir/ir_ui_menu.py
index a33686e1eb9..87afaf821fe 100644
--- a/bin/addons/base/ir/ir_ui_menu.py
+++ b/bin/addons/base/ir/ir_ui_menu.py
@@ -31,6 +31,10 @@ def one_in(setA, setB):
return True
return False
+def cond(C, X, Y):
+ if C: return X
+ return Y
+
class many2many_unique(fields.many2many):
def set(self, cr, obj, id, name, values, user=None, context=None):
if not values:
@@ -63,19 +67,24 @@ class ir_ui_menu(osv.osv):
# radical but this doesn't frequently happen
self._cache = {}
- def search(self, cr, uid, args, offset=0, limit=2000, order=None,
- context=None, count=False):
- if context is None:
- context = {}
- ids = osv.orm.orm.search(self, cr, uid, args, offset, limit, order, context=context, count=(count and uid==1))
+ def search(self, cr, uid, args, offset=0, limit=None, order=None,
+ context=None, count=False):
+
+ super_offset = cond(uid == 1, offset, 0)
+ super_limit = cond(uid == 1, limit, None)
+ super_count = cond(uid == 1, count, False)
+
+ ids = super(ir_ui_menu, self).search(cr, uid, args, super_offset,
+ super_limit, order,
+ context=context, count=super_count)
+ if uid == 1 or count:
+ return ids
if not ids:
if count:
return 0
return []
- if count and ids:
- return ids
modelaccess = self.pool.get('ir.model.access')
user_groups = set(self.pool.get('res.users').read(cr, 1, uid, ['groups_id'])['groups_id'])
@@ -123,6 +132,11 @@ class ir_ui_menu(osv.osv):
result.append(menu.id)
self._cache[key] = True
+ if offset:
+ result = result[long(offset):]
+ if limit:
+ result = result[:long(limit)]
+
if count:
return len(result)
return result
diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py
index b04343e821f..a4b6923c672 100644
--- a/bin/addons/base/ir/ir_ui_view.py
+++ b/bin/addons/base/ir/ir_ui_view.py
@@ -200,6 +200,10 @@ class view_sc(osv.osv):
'resource': lambda *a: 'ir.ui.menu',
'user_id': lambda obj, cr, uid, context: uid,
}
+ _sql_constraints = [
+ ('shortcut_unique', 'unique(res_id, user_id)', 'Shortcut for this menu already exists!'),
+ ]
+
view_sc()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py
index 0a427427515..1f5f2393c19 100644
--- a/bin/addons/base/module/module.py
+++ b/bin/addons/base/module/module.py
@@ -146,11 +146,13 @@ class module(osv.osv):
], string='State', readonly=True),
'demo': fields.boolean('Demo data'),
'license': fields.selection([
- ('GPL-2', 'GPL-2'),
+ ('GPL-2', 'GPL Version 2'),
('GPL-2 or any later version', 'GPL-2 or later version'),
- ('GPL-3', 'GPL-3'),
+ ('GPL-3', 'GPL Version 3'),
('GPL-3 or any later version', 'GPL-3 or later version'),
- ('Other proprietary', 'Other proprietary')
+ ('AGPL-3', 'Affero GPL-3'),
+ ('Other OSI approved licence', 'Other OSI Approved Licence'),
+ ('Other proprietary', 'Other Proprietary')
], string='License', readonly=True),
'menus_by_module': fields.function(_get_views, method=True, string='Menus', type='text', multi="meta", store=True),
'reports_by_module': fields.function(_get_views, method=True, string='Reports', type='text', multi="meta", store=True),
@@ -161,7 +163,7 @@ class module(osv.osv):
_defaults = {
'state': lambda *a: 'uninstalled',
'demo': lambda *a: False,
- 'license': lambda *a: 'GPL-2',
+ 'license': lambda *a: 'AGPL-3',
}
_order = 'name'
diff --git a/bin/addons/base/res/partner/partner_demo.xml b/bin/addons/base/res/partner/partner_demo.xml
index f5d70a2490d..915ab903a3e 100644
--- a/bin/addons/base/res/partner/partner_demo.xml
+++ b/bin/addons/base/res/partner/partner_demo.xml
@@ -275,6 +275,26 @@
<field name="type">default</field>
<field name="partner_id" ref="res_partner_agrolait"/>
</record>
+ <record id="res_partner_address_8delivery" model="res.partner.address">
+ <field name="city">Wavre</field>
+ <field name="name">Paul Lelitre</field>
+ <field name="zip">5478</field>
+ <field name="title">M.</field>
+ <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/>
+ <field name="street">71 rue de Chimay</field>
+ <field name="type">delivery</field>
+ <field name="partner_id" ref="res_partner_agrolait"/>
+ </record>
+ <record id="res_partner_address_8invoice" model="res.partner.address">
+ <field name="city">Wavre</field>
+ <field name="name">Serge Lelitre</field>
+ <field name="zip">5478</field>
+ <field name="title">M.</field>
+ <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/>
+ <field name="street">69 rue de Chimay</field>
+ <field name="type">invoice</field>
+ <field name="partner_id" ref="res_partner_agrolait"/>
+ </record>
<record id="res_partner_address_9" model="res.partner.address">
<field name="city">Paris</field>
<field name="name">Arthur Grosbonnet</field>
diff --git a/bin/addons/base/res/res_lang.py b/bin/addons/base/res/res_lang.py
index 8427b366703..66c1463eba9 100644
--- a/bin/addons/base/res/res_lang.py
+++ b/bin/addons/base/res/res_lang.py
@@ -60,11 +60,11 @@ class lang(osv.osv):
('name_uniq', 'unique (name)', 'The name of the language must be unique !'),
('code_uniq', 'unique (code)', 'The code of the language must be unique !'),
]
-
+
@tools.cache(skiparg=3)
def _lang_data_get(self, cr, uid, lang_id, monetary=False):
conv = localeconv()
- lang_obj=self.browse(cr,uid,lang_id)
+ lang_obj = self.browse(cr, uid, lang_id)
thousands_sep = lang_obj.thousands_sep or conv[monetary and 'mon_thousands_sep' or 'thousands_sep']
decimal_point = lang_obj.decimal_point
grouping = lang_obj.grouping
@@ -80,6 +80,7 @@ class lang(osv.osv):
if not grouping:
return (s, 0)
+
result = ""
seps = 0
spaces = ""
@@ -129,7 +130,7 @@ class lang(osv.osv):
parts = formatted.split('.')
if grouping:
- parts[0], seps = self._group(cr,uid,ids,parts[0], monetary=monetary, grouping=lang_grouping, thousands_sep=thousands_sep)
+ parts[0], seps = self._group(cr,uid,ids,parts[0], monetary=monetary, grouping=lang_grouping, thousands_sep=thousands_sep)
formatted = decimal_point.join(parts)
while seps:
diff --git a/bin/addons/base/res/res_security.xml b/bin/addons/base/res/res_security.xml
index 8aae3a40ae7..9d935ca3248 100644
--- a/bin/addons/base/res/res_security.xml
+++ b/bin/addons/base/res/res_security.xml
@@ -6,9 +6,13 @@
<field name="name">Partner Manager</field>
</record>
- <record model="ir.ui.menu" id="menu_base_config">
- <field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/>
- </record>
+ <record model="ir.ui.menu" id="menu_base_partner">
+ <field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/>
+ </record>
+
+ <record model="ir.ui.menu" id="menu_base_config">
+ <field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/>
+ </record>
</data>
</openerp>
diff --git a/bin/addons/base/res/res_user.py b/bin/addons/base/res/res_user.py
index 72be48dcf0a..1e5f142ee0c 100644
--- a/bin/addons/base/res/res_user.py
+++ b/bin/addons/base/res/res_user.py
@@ -106,10 +106,11 @@ roles()
def _lang_get(self, cr, uid, context={}):
obj = self.pool.get('res.lang')
- ids = obj.search(cr, uid, [])
+ ids = obj.search(cr, uid, [('translatable','=',True)])
res = obj.read(cr, uid, ids, ['code', 'name'], context)
res = [(r['code'], r['name']) for r in res]
return res
+
def _tz_get(self,cr,uid, context={}):
return [(x, x) for x in pytz.all_timezones]
@@ -245,6 +246,15 @@ class users(osv.osv):
result = override_password(result)
else:
result = map(override_password, result)
+
+ if isinstance(result, list):
+ for rec in result:
+ if not rec.get('action_id',True):
+ rec['action_id'] = (self._get_menu(cr, uid),'Menu')
+ else:
+ if not result.get('action_id',True):
+ result['action_id'] = (self._get_menu(cr, uid),'Menu')
+
return result
@@ -467,6 +477,13 @@ class groups2(osv.osv): ##FIXME: Is there a reason to inherit this object ?
_columns = {
'users': fields.many2many('res.users', 'res_groups_users_rel', 'gid', 'uid', 'Users'),
}
+
+ def unlink(self, cr, uid, ids, context=None):
+ for record in self.read(cr, uid, ids, ['users'], context=context):
+ if record['users']:
+ raise osv.except_osv(_('Warning !'), _('Make sure you have no users linked with the group(s)!'))
+ return super(groups2, self).unlink(cr, uid, ids, context=context)
+
groups2()
class res_config_view(osv.osv_memory):
diff --git a/bin/addons/base/security/ir.model.access.csv b/bin/addons/base/security/ir.model.access.csv
index cf0f73a5cc9..e0f7f653ad6 100644
--- a/bin/addons/base/security/ir.model.access.csv
+++ b/bin/addons/base/security/ir.model.access.csv
@@ -19,7 +19,7 @@
"access_ir_module_module_group_user","ir_module_module group_user","model_ir_module_module","group_system",1,1,1,1
"access_ir_module_module_dependency_group_system","ir_module_module_dependency group_system","model_ir_module_module_dependency","group_system",1,1,1,1
"access_ir_property_group_user","ir_property group_user","model_ir_property",,1,0,0,0
-"access_ir_property_group_user_manager","ir_property group_manager","model_ir_property","base.group_partner_manager",1,1,1,1
+"access_ir_property_group_user_manager","ir_property group_manager","model_ir_property","base.group_partner_manager",1,1,1,0
"access_ir_report_custom_group_system","ir_report_custom group_system","model_ir_report_custom",,1,0,0,0
"access_ir_report_custom_fields_group_system","ir_report_custom_fields group_system","model_ir_report_custom_fields",,1,0,0,0
"access_ir_rule_group_user","ir_rule group_user","model_ir_rule",,1,0,0,0