mirror of https://github.com/OCA/web.git
[FIX] evaluate domains containing _auto_join fields
before taking unionspull/1635/head
parent
7c9992dabc
commit
01c4ed572e
|
@ -19,7 +19,7 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
import itertools
|
import itertools
|
||||||
from openerp.osv.orm import Model
|
from openerp.osv.orm import Model, MAGIC_COLUMNS
|
||||||
from openerp.osv import fields, expression
|
from openerp.osv import fields, expression
|
||||||
from openerp.tools.safe_eval import safe_eval
|
from openerp.tools.safe_eval import safe_eval
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
@ -60,11 +60,19 @@ class IrFilters(Model):
|
||||||
['domain_this', 'union_filter_ids', 'complement_filter_ids'],
|
['domain_this', 'union_filter_ids', 'complement_filter_ids'],
|
||||||
context=context):
|
context=context):
|
||||||
domain = eval_n(this['domain_this'])
|
domain = eval_n(this['domain_this'])
|
||||||
domain = expression.OR(
|
for u in self.read(cr, uid, this['union_filter_ids'],
|
||||||
[domain] +
|
['domain', 'evaluate_always', 'model_id'],
|
||||||
[eval_n(u['domain']) for u in self.read(
|
context=context):
|
||||||
cr, uid, this['union_filter_ids'], ['domain'],
|
if u['evaluate_always']:
|
||||||
context=context)])
|
matching_ids = self.pool[u['model_id']].search(
|
||||||
|
cr, uid, eval_n(u['domain']),
|
||||||
|
context=context)
|
||||||
|
domain = expression.OR([
|
||||||
|
domain,
|
||||||
|
[('id', 'in', matching_ids)],
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
domain = expression.OR([domain, eval_n(u['domain'])])
|
||||||
for c in self.read(cr, uid, this['complement_filter_ids'],
|
for c in self.read(cr, uid, this['complement_filter_ids'],
|
||||||
['domain', 'evaluate_before_negate',
|
['domain', 'evaluate_before_negate',
|
||||||
'model_id'],
|
'model_id'],
|
||||||
|
@ -88,7 +96,7 @@ class IrFilters(Model):
|
||||||
context=None):
|
context=None):
|
||||||
self.write(cr, uid, ids, {'domain_this': field_value})
|
self.write(cr, uid, ids, {'domain_this': field_value})
|
||||||
|
|
||||||
def _evaluate_before_negate_get(self, cr, uid, ids, field_name, args,
|
def _evaluate_get(self, cr, uid, ids, field_name, args,
|
||||||
context=None):
|
context=None):
|
||||||
"""check if this filter contains references to x2many fields. If so,
|
"""check if this filter contains references to x2many fields. If so,
|
||||||
then negation goes wrong in nearly all cases, so we evaluate the
|
then negation goes wrong in nearly all cases, so we evaluate the
|
||||||
|
@ -96,27 +104,38 @@ class IrFilters(Model):
|
||||||
result = {}
|
result = {}
|
||||||
for this in self.read(cr, uid, ids, ['model_id', 'domain'],
|
for this in self.read(cr, uid, ids, ['model_id', 'domain'],
|
||||||
context=context):
|
context=context):
|
||||||
result[this['id']] = False
|
result[this['id']] = {
|
||||||
complement_domain = expression.normalize_domain(
|
'evaluate_before_negate': False,
|
||||||
|
'evaluate_always': False,
|
||||||
|
}
|
||||||
|
domain = expression.normalize_domain(
|
||||||
safe_eval(this['domain'] or 'False') or
|
safe_eval(this['domain'] or 'False') or
|
||||||
[expression.FALSE_LEAF])
|
[expression.FALSE_LEAF])
|
||||||
for arg in complement_domain:
|
for arg in domain:
|
||||||
if not expression.is_leaf(arg):
|
if not expression.is_leaf(arg) or not isinstance(
|
||||||
|
arg[0], basestring):
|
||||||
continue
|
continue
|
||||||
current_model = self.pool.get(this['model_id'])
|
current_model = self.pool.get(this['model_id'])
|
||||||
if not current_model:
|
if not current_model:
|
||||||
continue
|
continue
|
||||||
has_x2many = False
|
has_x2many = False
|
||||||
|
has_auto_join = False
|
||||||
for field_name in arg[0].split('.'):
|
for field_name in arg[0].split('.'):
|
||||||
|
if field_name in MAGIC_COLUMNS:
|
||||||
|
continue
|
||||||
field = current_model._all_columns[field_name].column
|
field = current_model._all_columns[field_name].column
|
||||||
has_x2many |= field._type in self._evaluate_before_negate
|
has_x2many |= field._type in self._evaluate_before_negate
|
||||||
has_x2many |= isinstance(field, fields.function)
|
has_x2many |= isinstance(field, fields.function)
|
||||||
|
has_auto_join |= field._auto_join
|
||||||
|
has_auto_join |= isinstance(field, fields.function)
|
||||||
if hasattr(field, '_obj'):
|
if hasattr(field, '_obj'):
|
||||||
current_model = self.pool.get(field._obj)
|
current_model = self.pool.get(field._obj)
|
||||||
if not current_model or has_x2many:
|
if not current_model or has_x2many and has_auto_join:
|
||||||
break
|
break
|
||||||
if has_x2many:
|
result[this['id']]['evaluate_before_negate'] |= has_x2many
|
||||||
result[this['id']] = True
|
result[this['id']]['evaluate_always'] |= has_auto_join
|
||||||
|
if result[this['id']]['evaluate_before_negate'] and\
|
||||||
|
result[this['id']]['evaluate_always']:
|
||||||
break
|
break
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -138,10 +157,15 @@ class IrFilters(Model):
|
||||||
'domain_this': fields.text(
|
'domain_this': fields.text(
|
||||||
'This filter\'s own domain', oldname='domain'),
|
'This filter\'s own domain', oldname='domain'),
|
||||||
'evaluate_before_negate': fields.function(
|
'evaluate_before_negate': fields.function(
|
||||||
_evaluate_before_negate_get, type='boolean',
|
_evaluate_get, type='boolean', multi='evaluate',
|
||||||
string='Evaluate this filter before negating',
|
string='Evaluate this filter before negating',
|
||||||
help='This is necessary if this filter contains positive operators'
|
help='This is necessary if this filter contains positive operators'
|
||||||
'on x2many fields')
|
'on x2many fields'),
|
||||||
|
'evaluate_always': fields.function(
|
||||||
|
_evaluate_get, type='boolean', multi='evaluate',
|
||||||
|
string='Always evaluate this filter before using it',
|
||||||
|
help='This is necessary if this filter contains x2many fields with'
|
||||||
|
'_auto_join activated')
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
|
|
Loading…
Reference in New Issue