From de3b64018aac6f310847e04b02b8b2bd64768009 Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Fri, 4 Dec 2015 14:32:21 +0100 Subject: [PATCH] [FIX] osv: fix boolean in domain for custom field When a new column has been added after that some data already exists, the old lines will keep an empty/null value. So when we search is the new field is equals to False or if it is different of True, we need to match the null values. close #9925 --- openerp/addons/test_new_api/demo_data.xml | 13 ++++++ .../addons/test_new_api/ir.model.access.csv | 1 + openerp/addons/test_new_api/models.py | 8 ++++ openerp/addons/test_new_api/tests/__init__.py | 1 + .../addons/test_new_api/tests/test_domain.py | 41 +++++++++++++++++++ openerp/osv/expression.py | 4 +- 6 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 openerp/addons/test_new_api/tests/test_domain.py diff --git a/openerp/addons/test_new_api/demo_data.xml b/openerp/addons/test_new_api/demo_data.xml index 1715b024cd7..17ac07718b3 100644 --- a/openerp/addons/test_new_api/demo_data.xml +++ b/openerp/addons/test_new_api/demo_data.xml @@ -28,5 +28,18 @@ + + + + + + + + + + + + + diff --git a/openerp/addons/test_new_api/ir.model.access.csv b/openerp/addons/test_new_api/ir.model.access.csv index 2bbd1adf12d..757e2050363 100644 --- a/openerp/addons/test_new_api/ir.model.access.csv +++ b/openerp/addons/test_new_api/ir.model.access.csv @@ -5,3 +5,4 @@ access_message,test_new_api_message,test_new_api.model_test_new_api_message,,1,1 access_mixed,test_new_api_mixed,test_new_api.model_test_new_api_mixed,,1,1,1,1 access_test_function_noinfiniterecursion,access_test_function_noinfiniterecursion,model_test_old_api_function_noinfiniterecursion,,1,1,1,1 access_test_function_counter,access_test_function_counter,model_test_old_api_function_counter,,1,1,1,1 +access_domain_bool,access_domain_bool,model_domain_bool,,1,1,1,1 diff --git a/openerp/addons/test_new_api/models.py b/openerp/addons/test_new_api/models.py index 173935a8985..50343b0d1fc 100644 --- a/openerp/addons/test_new_api/models.py +++ b/openerp/addons/test_new_api/models.py @@ -236,3 +236,11 @@ class MixedModel(models.Model): return [(model.model, model.name) for model in models if not model.model.startswith('ir.')] + + +class BoolModel(models.Model): + _name = 'domain.bool' + + bool_true = fields.Boolean('b1', default=True) + bool_false = fields.Boolean('b2', default=False) + bool_undefined = fields.Boolean('b3') diff --git a/openerp/addons/test_new_api/tests/__init__.py b/openerp/addons/test_new_api/tests/__init__.py index f4803bd4837..1bae0b503c3 100644 --- a/openerp/addons/test_new_api/tests/__init__.py +++ b/openerp/addons/test_new_api/tests/__init__.py @@ -6,3 +6,4 @@ from . import test_onchange from . import test_field_conversions from . import test_attributes from . import test_no_infinite_recursion +from . import test_domain diff --git a/openerp/addons/test_new_api/tests/test_domain.py b/openerp/addons/test_new_api/tests/test_domain.py new file mode 100644 index 00000000000..03ee468c76d --- /dev/null +++ b/openerp/addons/test_new_api/tests/test_domain.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +from openerp.tests import common + + +class test_domain(common.TransactionCase): + + def setUp(self): + super(test_domain, self).setUp() + self.bool = self.env['domain.bool'] + + def test_00_test_bool_undefined(self): + """ + Check that undefined/empty values in database is equal to False and different of True + + """ + + # Add a new boolean column after that some rows/tuples has been added (with data) + # Existing rows/tuples will be undefined/empty + self.env['ir.model.fields'].create({ + 'name': 'x_bool_new_undefined', + 'model_id': self.env.ref('test_new_api.model_domain_bool').id, + 'field_description': 'A new boolean column', + 'ttype': 'boolean' + }) + + self.env.ref('test_new_api.bool_3').write({'x_bool_new_undefined': True}) + self.env.ref('test_new_api.bool_4').write({'x_bool_new_undefined': False}) + + model = self.bool + all_bool = model.search([]) + for f in ['bool_true', 'bool_false', 'bool_undefined', 'x_bool_new_undefined']: + eq_1 = model.search([(f, '=', False)]) + neq_1 = model.search([(f, '!=', True)]) + self.assertEqual(eq_1, neq_1, '`= False` (%s) <> `!= True` (%s) ' % (len(eq_1), len(neq_1))) + + eq_2 = model.search([(f, '=', True)]) + neq_2 = model.search([(f, '!=', False)]) + self.assertEqual(eq_2, neq_2, '`= True` (%s) <> `!= False` (%s) ' % (len(eq_2), len(neq_2))) + + self.assertEqual(eq_1+eq_2, all_bool, 'True + False != all') + self.assertEqual(neq_1+neq_2, all_bool, 'not True + not False != all') diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py index ecf01d86618..ef8a40dab90 100644 --- a/openerp/osv/expression.py +++ b/openerp/osv/expression.py @@ -1192,7 +1192,7 @@ class expression(object): else: # Must not happen raise ValueError("Invalid domain term %r" % (leaf,)) - elif right == False and (left in model._columns) and model._columns[left]._type == "boolean" and (operator == '='): + elif (left in model._columns) and model._columns[left]._type == "boolean" and ((operator == '=' and right is False) or (operator == '!=' and right is True)): query = '(%s."%s" IS NULL or %s."%s" = false )' % (table_alias, left, table_alias, left) params = [] @@ -1200,7 +1200,7 @@ class expression(object): query = '%s."%s" IS NULL ' % (table_alias, left) params = [] - elif right == False and (left in model._columns) and model._columns[left]._type == "boolean" and (operator == '!='): + elif (left in model._columns) and model._columns[left]._type == "boolean" and ((operator == '!=' and right is False) or (operator == '==' and right is True)): query = '(%s."%s" IS NOT NULL and %s."%s" != false)' % (table_alias, left, table_alias, left) params = []