From cb32d72dfa134e57c88742612c6c85bd13ee5797 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Tue, 22 Dec 2009 21:56:00 +0100 Subject: [PATCH] [FIX] rule and multi-company bzr revid: fp@tinyerp.com-20091222205600-3h0fow08pndm7y0f --- bin/addons/base/ir/ir_rule.py | 7 +++--- bin/addons/base/res/partner/partner.py | 2 +- bin/osv/expression.py | 30 ++++++++++++-------------- bin/osv/fields.py | 8 +++---- bin/osv/orm.py | 22 +++++++++++-------- 5 files changed, 36 insertions(+), 33 deletions(-) diff --git a/bin/addons/base/ir/ir_rule.py b/bin/addons/base/ir/ir_rule.py index f096d53a93d..02b87a4a77f 100644 --- a/bin/addons/base/ir/ir_rule.py +++ b/bin/addons/base/ir/ir_rule.py @@ -137,7 +137,7 @@ class ir_rule(osv.osv): if not (field_id or operator or operand): return {} - def domain_get2(self, cr, uid, model_name): + def domain_get2(self, cr, uid, model_name, context={}): if uid == 1: return [] @@ -155,8 +155,9 @@ class ir_rule(osv.osv): for rule in self.browse(cr, uid, ids): dom += rule.domain return dom - def domain_get(self, cr, uid, model_name): - dom = self.domain_get2(cr, uid, model_name) + + def domain_get(self, cr, uid, model_name, context={}): + dom = self.domain_get2(cr, uid, model_name, context=context) d1,d2,tables = self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False) return ' and '.join(d1), d2, tables domain_get = tools.cache()(domain_get) diff --git a/bin/addons/base/res/partner/partner.py b/bin/addons/base/res/partner/partner.py index 39190d4df33..765eb86f686 100644 --- a/bin/addons/base/res/partner/partner.py +++ b/bin/addons/base/res/partner/partner.py @@ -151,7 +151,7 @@ class res_partner(osv.osv): 'supplier': fields.boolean('Supplier', help="Check this box if the partner is a supplier. If it's not checked, purchase people will not see it when encoding a purchase order."), 'city':fields.related('address','city',type='char', string='City'), 'country':fields.related('address','country_id',type='many2one', relation='res.country', string='Country'), - 'company_id': fields.many2one('res.company', 'Company'), + 'company_id': fields.many2one('res.company', 'Company',select=1), } def _default_category(self, cr, uid, context={}): diff --git a/bin/osv/expression.py b/bin/osv/expression.py index 6dbe600fe0c..9b4b01d3fe9 100644 --- a/bin/osv/expression.py +++ b/bin/osv/expression.py @@ -145,25 +145,23 @@ class expression(object): if field._type in ['many2many','one2many']: right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context) right1 = table.search(cr, uid, [(fargs[0],'in', right)], context=context) - self.__exp[i] = ('id', 'in', right1) - + self.__exp[i] = ('id', 'in', right1) continue - if field._properties: + if field._properties and not field.store: # this is a function field - if not field.store: - if not field._fnct_search: - # the function field doesn't provide a search function and doesn't store - # values in the database, so we must ignore it : we generate a dummy leaf - self.__exp[i] = self.__DUMMY_LEAF - else: - subexp = field.search(cr, uid, table, left, [self.__exp[i]]) - # we assume that the expression is valid - # we create a dummy leaf for forcing the parsing of the resulting expression - self.__exp[i] = '&' - self.__exp.insert(i + 1, self.__DUMMY_LEAF) - for j, se in enumerate(subexp): - self.__exp.insert(i + 2 + j, se) + if not field._fnct_search: + # the function field doesn't provide a search function and doesn't store + # values in the database, so we must ignore it : we generate a dummy leaf + self.__exp[i] = self.__DUMMY_LEAF + else: + subexp = field.search(cr, uid, table, left, [self.__exp[i]]) + # we assume that the expression is valid + # we create a dummy leaf for forcing the parsing of the resulting expression + self.__exp[i] = '&' + self.__exp.insert(i + 1, self.__DUMMY_LEAF) + for j, se in enumerate(subexp): + self.__exp.insert(i + 2 + j, se) # else, the value of the field is store in the database, so we search on it diff --git a/bin/osv/fields.py b/bin/osv/fields.py index a8cf6e85b8d..8ecdd8eb407 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -506,7 +506,7 @@ class many2many(_column): limit_str = self._limit is not None and ' limit %d' % self._limit or '' obj = obj.pool.get(self._obj) - d1, d2, tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name) + d1, d2, tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context) if d1: d1 = ' and ' + d1 @@ -544,7 +544,7 @@ class many2many(_column): cr.execute('update '+self._rel+' set '+self._id2+'=null where '+self._id2+'=%s', (id,)) elif act[0] == 6: - d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name) + d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context) if d1: d1 = ' and ' + d1 cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+','.join(tables)+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2) @@ -741,7 +741,8 @@ class related(function): if not ids: return {} relation = obj._name res = {}.fromkeys(ids, False) - objlst = obj.browse(cr, uid, ids) + + objlst = obj.browse(cr, uid, ids, context=context) for data in objlst: if not data: continue @@ -778,7 +779,6 @@ class related(function): if res[r]: res[r] = [x.id for x in res[r]] - return res def __init__(self, *arg, **args): diff --git a/bin/osv/orm.py b/bin/osv/orm.py index d445e966bc9..ae27dcece2d 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -2375,7 +2375,7 @@ class orm(orm_template): fields_to_read = self._columns.keys() # construct a clause for the rules : - d1, d2, tables = self.pool.get('ir.rule').domain_get(cr, user, self._name) + d1, d2, tables = self.pool.get('ir.rule').domain_get(cr, user, self._name, context=context) # all inherited fields + all non inherited fields for which the attribute whose name is in load is True fields_pre = [f for f in fields_to_read if @@ -2404,7 +2404,7 @@ class orm(orm_template): self._order),[sub_ids,]+d2) if not cr.rowcount == len({}.fromkeys(sub_ids)): raise except_orm(_('AccessError'), - _('You try to bypass an access rule (Document type: %s).') % self._description) + _('You try to bypass an access rule while reading (Document type: %s).') % self._description) else: cr.execute('SELECT %s FROM \"%s\" WHERE id = ANY (%%s) ORDER BY %s' % \ (','.join(fields_pre2 + ['id']), self._table, @@ -2586,7 +2586,7 @@ class orm(orm_template): # ids2 = [x[self._inherits[key]] for x in res] # self.pool.get(key).unlink(cr, uid, ids2) - d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name) + d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name, context=context) if d1: d1 = ' AND '+d1 @@ -2702,7 +2702,7 @@ class orm(orm_template): if len(upd0): - d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, user, self._name) + d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, user, self._name, context=context) if d1: d1 = ' and '+d1 @@ -2714,7 +2714,7 @@ class orm(orm_template): 'WHERE '+self._table+'.id IN ('+ids_str+')'+d1, d2) if not cr.rowcount == len({}.fromkeys(sub_ids)): raise except_orm(_('AccessError'), - _('You try to bypass an access rule (Document type: %s).') % \ + _('You try to bypass an access rule while writing (Document type: %s).') % \ self._description) else: cr.execute('SELECT id FROM "'+self._table+'" WHERE id IN ('+ids_str+')') @@ -3016,7 +3016,9 @@ class orm(orm_template): continue result.setdefault(fncts[fnct][0], {}) - ids2 = fncts[fnct][2](self,cr, uid, ids, context) + + # uid == 1 for accessing objects having rules defined on store fields + ids2 = fncts[fnct][2](self,cr, 1, ids, context) for id in filter(None, ids2): result[fncts[fnct][0]].setdefault(id, []) result[fncts[fnct][0]][id].append(fnct) @@ -3065,7 +3067,8 @@ class orm(orm_template): for key in keys: val = todo[key] if key: - result = self._columns[val[0]].get(cr, self, ids, val, uid, context=context) + # uid == 1 for accessing objects having rules defined on store fields + result = self._columns[val[0]].get(cr, self, ids, val, 1, context=context) for id,value in result.items(): if field_flag: for f in value.keys(): @@ -3089,7 +3092,8 @@ class orm(orm_template): else: for f in val: - result = self._columns[f].get(cr, self, ids, f, uid, context=context) + # uid == 1 for accessing objects having rules defined on store fields + result = self._columns[f].get(cr, self, ids, f, 1, context=context) for r in result.keys(): if field_flag: if r in field_dict.keys(): @@ -3151,7 +3155,7 @@ class orm(orm_template): if not context: context = {} # compute the where, order by, limit and offset clauses - dom = self.pool.get('ir.rule').domain_get2(cr, user, self._name) + dom = self.pool.get('ir.rule').domain_get2(cr, user, self._name, context=context) (qu1, qu2, tables) = self._where_calc(cr, user, args+dom, context=context) if len(qu1): qu1 = ' where '+string.join(qu1, ' and ')