context = {}
result = False
fields = {}
- childs = True
+ children = True
- if node.tag == 'field':
+ def encode(s):
+ if isinstance(s, unicode):
+ return s.encode('utf8')
+ return s
+
+ # return True if node can be displayed to current user
+ def check_group(node):
+ if node.get('groups'):
+ groups = node.get('groups').split(',')
+ access_pool = self.pool.get('ir.model.access')
+ can_see = any(access_pool.check_groups(cr, user, group) for group in groups)
+ if not can_see:
+ node.set('invisible', '1')
+ if 'attrs' in node.attrib:
+ del(node.attrib['attrs']) #avoid making field visible later
+ del(node.attrib['groups'])
+ return can_see
+ else:
+ return True
+
+ if node.tag in ('field', 'node', 'arrow'):
+ if node.get('object'):
+ attrs = {}
+ views = {}
+ xml = "<form>"
+ for f in node:
+ if f.tag in ('field'):
+ xml += etree.tostring(f, encoding="utf-8")
+ xml += "</form>"
+ new_xml = etree.fromstring(encode(xml))
+ ctx = context.copy()
+ ctx['base_model_name'] = self._name
+ xarch, xfields = self.pool.get(node.get('object', False)).__view_look_dom_arch(cr, user, new_xml, view_id, ctx)
+ views[str(f.tag)] = {
+ 'arch': xarch,
+ 'fields': xfields
+ }
+ attrs = {'views': views}
+ view = False
+ fields = views.get('field', False) and views['field'].get('fields', False)
if node.get('name'):
attrs = {}
try:
column = False
if column:
- relation = column._obj
+ relation = self.pool.get(column._obj)
+
- childs = False
+ children = False
views = {}
for f in node:
if f.tag in ('form', 'tree', 'graph'):
if trans:
node.set('sum', trans)
+ if children:
+ for f in node:
+ for f in node:
- if childs or (node.tag == 'field' and f.tag in ('filter','separator')):
++ if children or (node.tag == 'field' and f.tag in ('filter','separator')):
fields.update(self.__view_look_dom(cr, user, f, view_id, context))
return fields
- def __view_look_dom_arch(self, cr, user, node, view_id, context=None):
- fields_def = self.__view_look_dom(cr, user, node, view_id, context=context)
+ def _disable_workflow_buttons(self, cr, user, node):
+ if user == 1:
+ # admin user can always activate workflow buttons
+ return node
- rolesobj = self.pool.get('res.roles')
+ # TODO handle the case of more than one workflow for a model or multiple
+ # transitions with different groups and same signal
usersobj = self.pool.get('res.users')
-
buttons = (n for n in node.getiterator('button') if n.get('type') != 'object')
for button in buttons:
- can_click = True
- if user != 1: # admin user has all roles
- user_roles = usersobj.read(cr, user, [user], ['roles_id'])[0]['roles_id']
- # TODO handle the case of more than one workflow for a model
- cr.execute("""SELECT DISTINCT t.role_id
- FROM wkf
- INNER JOIN wkf_activity a ON a.wkf_id = wkf.id
- INNER JOIN wkf_transition t ON (t.act_to = a.id)
- WHERE wkf.osv = %s
- AND t.signal = %s
- """, (self._name, button.get('name'),))
- roles = cr.fetchall()
-
- # draft -> valid = signal_next (role X)
- # draft -> cancel = signal_cancel (no role)
- #
- # valid -> running = signal_next (role Y)
- # valid -> cancel = signal_cancel (role Z)
- #
- # running -> done = signal_next (role Z)
- # running -> cancel = signal_cancel (role Z)
-
- # As we don't know the object state, in this scenario,
- # the button "signal_cancel" will be always shown as there is no restriction to cancel in draft
- # the button "signal_next" will be show if the user has any of the roles (X Y or Z)
- # The verification will be made later in workflow process...
- if roles:
- can_click = any((not role) or rolesobj.check(cr, user, user_roles, role) for (role,) in roles)
-
+ user_groups = usersobj.read(cr, user, [user], ['groups_id'])[0]['groups_id']
+ cr.execute("""SELECT DISTINCT t.group_id
+ FROM wkf
+ INNER JOIN wkf_activity a ON a.wkf_id = wkf.id
+ INNER JOIN wkf_transition t ON (t.act_to = a.id)
+ WHERE wkf.osv = %s
+ AND t.signal = %s
+ AND t.group_id is NOT NULL
+ """, (self._name, button.get('name')))
+ group_ids = [x[0] for x in cr.fetchall() if x[0]]
+ can_click = not group_ids or bool(set(user_groups).intersection(group_ids))
button.set('readonly', str(int(not can_click)))
+ return node
+ def __view_look_dom_arch(self, cr, user, node, view_id, context=None):
+ fields_def = self.__view_look_dom(cr, user, node, view_id, context=context)
+ node = self._disable_workflow_buttons(cr, user, node)
arch = etree.tostring(node, encoding="utf-8").replace('\t', '')
-
- #code for diagram view.
- fields={}
- if node.tag=='diagram':
- if node.getchildren()[0].tag=='node':
- node_fields=self.pool.get(node.getchildren()[0].get('object')).fields_get(cr, user, fields_def.keys(), context)
- if node.getchildren()[1].tag=='arrow':
- arrow_fields = self.pool.get(node.getchildren()[1].get('object')).fields_get(cr, user, fields_def.keys(), context)
- for key,value in node_fields.items():
- fields[key]=value
- for key,value in arrow_fields.items():
- fields[key]=value
+ fields = {}
+ if node.tag == 'diagram':
+ if node.getchildren()[0].tag == 'node':
+ node_fields = self.pool.get(node.getchildren()[0].get('object')).fields_get(cr, user, fields_def.keys(), context)
+ if node.getchildren()[1].tag == 'arrow':
+ arrow_fields = self.pool.get(node.getchildren()[1].get('object')).fields_get(cr, user, fields_def.keys(), context)
+ for key, value in node_fields.items():
+ fields[key] = value
+ for key, value in arrow_fields.items():
+ fields[key] = value
else:
fields = self.fields_get(cr, user, fields_def.keys(), context)
-
for field in fields_def:
if field == 'id':
- # sometime, the view may containt the (invisible) field 'id' needed for a domain (when 2 objects have cross references)
+ # sometime, the view may contain the (invisible) field 'id' needed for a domain (when 2 objects have cross references)
fields['id'] = {'readonly': True, 'type': 'integer', 'string': 'ID'}
elif field in fields:
fields[field].update(fields_def[field])
where += ' order by '+self._parent_order
cr.execute('SELECT id FROM '+self._table+' WHERE '+where)
pos2 = pos + 1
- childs = cr.fetchall()
- for id in childs:
+ children = cr.fetchall()
+ for id in children:
pos2 = browse_rec(id[0], pos2)
- cr.execute('update '+self._table+' set parent_left=%s, parent_right=%s where id=%s', (pos,pos2,root))
- return pos2+1
+ cr.execute('update '+self._table+' set parent_left=%s, parent_right=%s where id=%s', (pos, pos2, root))
+ return pos2 + 1
query = 'SELECT id FROM '+self._table+' WHERE '+self._parent_name+' IS NULL'
if self._parent_order:
- query += ' order by '+self._parent_order
+ query += ' order by ' + self._parent_order
pos = 0
cr.execute(query)
for (root,) in cr.fetchall():