[MERGE] merge from 6.0.0-RC1
authorNumerigraphe - Lionel Sausin <ls@numerigraphe.fr>
Mon, 25 Oct 2010 07:43:13 +0000 (09:43 +0200)
committerNumerigraphe - Lionel Sausin <ls@numerigraphe.fr>
Mon, 25 Oct 2010 07:43:13 +0000 (09:43 +0200)
bzr revid: ls@numerigraphe.fr-20101025074313-uaspq2f2y523my99

1  2 
bin/addons/base/module/module.py
bin/osv/orm.py
bin/report/print_xml.py
bin/report/render/rml2pdf/trml2pdf.py

Simple merge
diff --cc bin/osv/orm.py
@@@ -1085,9 -1243,48 +1243,48 @@@ class orm_template(object)
              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])
@@@ -1966,14 -2326,14 +2328,14 @@@ class orm(orm_template)
                  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():
Simple merge
Simple merge