split code in two parts: the implied groups, and enhanced view

bzr revid: rco@openerp.com-20110729140400-agr3x0o7xpqxyt0p
This commit is contained in:
Raphael Collet 2011-07-29 16:04:00 +02:00
parent 97dd3f3f41
commit beaf6ec43c
1 changed files with 81 additions and 61 deletions

View File

@ -549,11 +549,13 @@ res_config_view()
class groups2(osv.osv):
""" Extension of res.groups with a relation for implied groups.
The data defines a view that inherits from the user form; that view is
updated when groups are modified, to reflect their structure.
"""
#
# Extension of res.groups and res.users with a relation for "implied" or
# "inherited" groups. Once a user belongs to a group, it automatically belongs
# to the implied groups (transitively).
#
class groups_implied(osv.osv):
_inherit = 'res.groups'
_columns = {
'implied_ids': fields.many2many('res.groups', 'res_groups_implied_rel', 'gid', 'hid',
@ -572,27 +574,25 @@ class groups2(osv.osv):
return list(closure)
def create(self, cr, uid, values, context=None):
group_id = super(groups2, self).create(cr, uid, values, context)
if values.get('users') or values.get('implied_ids'):
# add implied groups to all users of the group
group = self.browse(cr, uid, group_id)
self.pool.get('res.users').write(cr, uid, map(int, group.users),
{'groups_id': [(4, group_id)]}, context)
return group_id
users = values.pop('users')
gid = super(groups_implied, self).create(cr, uid, values, context)
if users:
# delegate addition of users to add implied groups
self.write(cr, uid, [gid], {'users': users}, context)
return gid
def write(self, cr, uid, ids, values, context=None):
res = super(groups2, self).write(cr, uid, ids, values, context)
res = super(groups_implied, self).write(cr, uid, ids, values, context)
if values.get('users') or values.get('implied_ids'):
# add implied groups (to all users of each group)
users_obj = self.pool.get('res.users')
groups = self.browse(cr, uid, ids)
for g in groups:
users_obj.write(cr, uid, map(int, g.users),
{'groups_id': [(4, g.id)]}, context)
for g in self.browse(cr, uid, ids):
gids = self.get_closure(cr, uid, [g.id], context)
users = [(4, u.id) for u in g.users]
super(groups_implied, self).write(cr, uid, gids, {'users': users}, context)
return res
def get_rec_implied(self, cr, uid, context=None):
"return a dictionary giving the recursively implied groups of each group"
def get_trans_implied(self, cr, uid, context=None):
"return a dictionary giving the transitively implied groups of each group"
groups = self.browse(cr, 1, self.search(cr, 1, []))
# compute the transitive closure of implied_ids
succs = dict([(g.id, set()) for g in groups])
@ -608,21 +608,63 @@ class groups2(osv.osv):
def get_maximal(self, cr, uid, ids, context=None):
"return a maximal element among the group ids"
trans_implied = self.get_rec_implied(cr, uid, context)
res = None
for gid in ids:
if (not res) or (res in trans_implied[gid]):
if (not res) or (res in self.get_closure(cr, uid, [gid], context)):
res = gid
return res
groups_implied()
class users_implied(osv.osv):
_inherit = 'res.users'
def create(self, cr, uid, values, context=None):
groups = values.pop('groups_id')
user_id = super(users_implied, self).create(cr, uid, values, context)
if groups:
# delegate addition of groups to add implied groups
self.write(cr, uid, [user_id], {'groups_id': groups}, context)
return user_id
def write(self, cr, uid, ids, values, context=None):
res = super(users_implied, self).write(cr, uid, ids, values, context)
if values.get('groups_id'):
# add implied groups for all users
groups_obj = self.pool.get('res.groups')
for u in self.browse(cr, uid, ids):
gids = groups_obj.get_closure(cr, uid, map(int, u.groups_id), context)
groups = [(6, 0, gids)]
super(users_implied, self).write(cr, uid, [u.id], {'groups_id': groups}, context)
return res
users_implied()
#
# Extension of res.groups and res.users for the special groups view in the users
# form. This extension presents groups with selection and boolean widgets:
# - Groups named as "App/Name" (corresponding to root menu "App") are presented
# per application, with one boolean and selection field each. The selection
# field defines a role "Name" for the given application.
# - Groups named as "Stuff/Name" are presented as boolean fields and grouped
# under sections "Stuff".
# - The remaining groups are presented as boolean fields and grouped in a
# section "Others".
#
class groups_view(osv.osv):
_inherit = 'res.groups'
def get_classified(self, cr, uid, context=None):
""" classify all groups by prefix; return a pair (apps, groups) where
""" classify all groups by prefix; return a pair (apps, others) where
- apps is a list like [("App", [(id, "Name"), ...]), ...],
- groups is a dictionary like {'Class': [(id, "Name"), ...], ...}
- others is a dictionary like {'Class': [(id, "Name"), ...], ...}
- the key None is used in groups for groups not like App/Name
"""
# get the relation to order groups
order_relation = self.get_rec_implied(cr, uid, context)
order_relation = self.get_trans_implied(cr, uid, context)
order = lambda x, y: (x[0] in order_relation[y[0]] and -1 or 1)
# classify groups depending on their names
@ -650,10 +692,8 @@ class groups2(osv.osv):
groups.sort(key=lambda pair: pair[1])
return (apps, classified)
groups2()
groups_view()
# Naming conventions for reified groups fields:
# - boolean field 'in_group_ID' is True iff
@ -688,11 +728,7 @@ def partition(f, xs):
nos.append(x)
return yes, nos
class users2(osv.osv):
""" Extension of res.users for:
- adding implied groups when added to a group
- defining special widgets for field groups_id
"""
class users_view(osv.osv):
_inherit = 'res.users'
def _process_values_groups(self, cr, uid, values, context=None):
@ -709,43 +745,29 @@ class users2(osv.osv):
rem.extend(get_selection_groups(k))
add.append(int(values.pop(k)))
if add or rem:
# remove groups in 'rem' and add all implied groups in 'add'
add = self.pool.get('res.groups').get_closure(cr, uid, add, context)
values['groups_id'] = [(3, id) for id in rem] + [(4, id) for id in add]
elif 'groups_id' in values:
# add implied groups (only handles (4, ID) and (6, 0, IDs) cases)
closure = lambda ids: self.pool.get('res.groups').get_closure(cr, uid, ids, context)
groups = []
for elem in values['groups_id']:
if elem[0] == 4:
groups.extend([(4, id) for id in closure([elem[1]])])
elif elem[0] == 6:
groups.append((6, 0, closure(elem[2])))
else:
groups.append(elem)
values['groups_id'] = groups
# remove groups in 'rem' and add groups in 'add'
gdiff = [(3, id) for id in rem] + [(4, id) for id in add]
values.setdefault('groups_id', []).extend(gdiff)
return True
def create(self, cr, uid, values, context=None):
# add processing for reified group fields
self._process_values_groups(cr, uid, values, context)
return super(users2, self).create(cr, uid, values, context)
return super(users_view, self).create(cr, uid, values, context)
def write(self, cr, uid, ids, values, context=None):
# add processing for reified group fields
self._process_values_groups(cr, uid, values, context)
return super(users2, self).write(cr, uid, ids, values, context)
return super(users_view, self).write(cr, uid, ids, values, context)
def read(self, cr, uid, ids, fields, context=None, load='_classic_read'):
# add processing for reified group fields
group_fields, fields = partition(is_field_group, fields)
if group_fields:
group_obj = self.pool.get('res.groups')
fields.append('groups_id')
res = super(users2, self).read(cr, uid, ids, fields, context, load)
# read the normal fields (and 'groups_id')
res = super(users_view, self).read(cr, uid, ids, fields, context, load)
for record in res:
# remove the field 'groups_id' and insert the group_fields
groups = set(record.pop('groups_id'))
# get the field 'groups_id' and insert the group_fields
groups = set(record['groups_id'])
for f in group_fields:
if is_boolean_group(f):
record[f] = get_boolean_group(f) in groups
@ -755,12 +777,12 @@ class users2(osv.osv):
selected = groups.intersection(get_selection_groups(f))
record[f] = group_obj.get_maximal(cr, uid, selected, context)
return res
return super(users2, self).read(cr, uid, ids, fields, context, load)
return super(users_view, self).read(cr, uid, ids, fields, context, load)
def fields_view_get(self, cr, uid, view_id=None, view_type='form',
context=None, toolbar=False, submenu=False):
# in form views, transform 'groups_id' into reified group fields
res = super(users2, self).fields_view_get(cr, uid, view_id, view_type,
res = super(users_view, self).fields_view_get(cr, uid, view_id, view_type,
context, toolbar, submenu)
if view_type == 'form':
root = etree.fromstring(encode(res['arch']))
@ -806,8 +828,6 @@ class users2(osv.osv):
res['arch'] = etree.tostring(root)
return res
users2()
users_view()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: