summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGoffin Simon <sig@odoo.com>2015-10-13 13:30:47 +0200
committerGoffin Simon <sig@odoo.com>2015-10-15 11:49:33 +0200
commit0239d1b357d1ffc8fb9692f8cbd2c4e4cb4a05ba (patch)
treece9304b8824b63d70b917a4f317800cf97162f7d
parent1487cf4e16384b2c217df01de4af2e5caabb3e37 (diff)
[FIX] models: read_group on many2one fields
When making on model A a read_group with groupby equal to a many2one field F1 to a model B which is ordered by a inherited not stored field F2, the group containing all the records from A with F1 not set was not returned. Example: model A= "hr.applicant" model B= "res.users" (_order = "name,login") inherited model= "res.partner" field F1= "user_id"(to "res.users) field F2= "name"(inherited from "res.partner") In this example, the query generated by the function "read_group" was: SELECT min(hr_applicant.id) AS id, count(hr_applicant.id) AS user_id_count , "hr_applicant"."user_id" as "user_id" FROM "hr_applicant" LEFT JOIN "res_users" as "hr_applicant__user_id" ON ("hr_applicant"."user_id" = "hr_applicant__user_id"."id"),"res_partner" as "hr_applicant__user_id__partner_id" WHERE ("hr_applicant"."active" = true) AND ("hr_applicant__user_id"."partner_id" = "hr_applicant__user_id__partner_id"."id") GROUP BY "hr_applicant"."user_id","hr_applicant__user_id__partner_id"."name","hr_applicant__user_id"."login" ORDER BY "hr_applicant__user_id__partner_id"."name" ,"hr_applicant__user_id"."login" which always returned "hr.applicant" groups of records with a "user_id" set due to the inner join maked on res_partners. This inner join on "res_partner" is coming from function "add_join" calling by "_inherits_join_add" in _generate_order_by_inner. Introduced by dac52e344c43808d76b8e57a059f803d3863db28 opw:651949
-rw-r--r--openerp/addons/base/tests/test_ir_filters.py24
-rw-r--r--openerp/models.py6
2 files changed, 27 insertions, 3 deletions
diff --git a/openerp/addons/base/tests/test_ir_filters.py b/openerp/addons/base/tests/test_ir_filters.py
index 9ca093d77af..d7e08376d6d 100644
--- a/openerp/addons/base/tests/test_ir_filters.py
+++ b/openerp/addons/base/tests/test_ir_filters.py
@@ -275,3 +275,27 @@ class TestGlobalDefaults(FiltersCase):
dict(name='a', user_id=False, is_default=False, domain='[]', context='{}'),
dict(name='b', user_id=False, is_default=True, domain='[]', context=context_value),
])
+
+from openerp.tests.common import TransactionCase
+
+class TestReadGroup(TransactionCase):
+ """Test function read_group with groupby on a many2one field to a model
+ (in test, "user_id" to "res.users") which is ordered by an inherited not stored field (in
+ test, "name" inherited from "res.partners").
+ """
+
+ def setUp(self):
+ super(TestReadGroup, self).setUp()
+ self.ir_filters_model = self.env['ir.filters']
+ self.res_partner_model = self.env['res.partner']
+ self.res_users_model = self.env['res.users']
+
+ def test_read_group_1(self):
+ self.assertEqual(self.res_users_model._order, "name, login", "Model res.users must be ordered by name, login")
+ self.assertFalse(self.res_users_model._fields['name'].store, "Field name is not stored in res.users")
+
+ filter_a = self.ir_filters_model.create(dict(name="Filter_A", model_id="ir.filters"))
+ filter_b = self.ir_filters_model.create(dict(name="Filter_B", model_id="ir.filters"))
+ filter_b.write(dict(user_id=False))
+ res = self.ir_filters_model.read_group([], ['name', 'user_id'], ['user_id'])
+ self.assertTrue(any(val['user_id'] == False for val in res), "At least one group must contain val['user_id'] == False.")
diff --git a/openerp/models.py b/openerp/models.py
index 16fd5a5db9d..c21bd76f3dc 100644
--- a/openerp/models.py
+++ b/openerp/models.py
@@ -2171,7 +2171,7 @@ class BaseModel(object):
parent_alias, parent_alias_statement = query.add_join((current_model._table, parent_model._table, inherits_field, 'id', inherits_field), implicit=True)
return parent_alias
- def _inherits_join_calc(self, alias, field, query):
+ def _inherits_join_calc(self, alias, field, query, implicit=True, outer=False):
"""
Adds missing table select and join clause(s) to ``query`` for reaching
the field coming from an '_inherits' parent table (no duplicates).
@@ -2191,7 +2191,7 @@ class BaseModel(object):
# JOIN parent_model._table AS parent_alias ON alias.parent_field = parent_alias.id
parent_alias, _ = query.add_join(
(alias, parent_model._table, parent_field, 'id', parent_field),
- implicit=True,
+ implicit=implicit, outer=outer,
)
model, alias = parent_model, parent_alias
return '"%s"."%s"' % (alias, field)
@@ -4624,7 +4624,7 @@ class BaseModel(object):
parent_obj = self.pool[self._inherit_fields[order_field][3]]
order_column = parent_obj._columns[order_field]
if order_column._classic_read:
- inner_clauses = [self._inherits_join_calc(alias, order_field, query)]
+ inner_clauses = [self._inherits_join_calc(alias, order_field, query, implicit=False, outer=True)]
add_dir = True
elif order_column._type == 'many2one':
key = (parent_obj._name, order_column._obj, order_field)