From 7eab880660da4a1a9cc25619f2314bdde5062091 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 15 Sep 2014 12:09:35 +0200 Subject: [PATCH] [FIX] orm: correct read_group() on models with `_group_by_full` (introduced by previous forward-port) also add tests of `_group_by_full` functionality --- openerp/addons/test_converter/models.py | 15 +++++++++++ .../addons/test_converter/tests/__init__.py | 5 ++-- .../addons/test_converter/tests/test_gbf.py | 25 +++++++++++++++++++ openerp/osv/orm.py | 16 +++++------- 4 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 openerp/addons/test_converter/tests/test_gbf.py diff --git a/openerp/addons/test_converter/models.py b/openerp/addons/test_converter/models.py index 9074ba8178f..9dd2f486af0 100644 --- a/openerp/addons/test_converter/models.py +++ b/openerp/addons/test_converter/models.py @@ -30,6 +30,21 @@ class test_model(orm.Model): 'text': fields.text(), } + # `base` module does not contains any model that implement the `_group_by_full` functionality + # test this feature here... + + def _gbf_m2o(self, cr, uid, ids, domain, read_group_order, access_rights_uid, context): + Sub = self.pool['test_converter.test_model.sub'] + all_ids = Sub._search(cr, uid, [], access_rights_uid=access_rights_uid, context=context) + result = Sub.name_get(cr, access_rights_uid or uid, all_ids, context=context) + folds = {i: i not in ids for i, _ in result} + return result, folds + + _group_by_full = { + 'many2one': _gbf_m2o, + } + + class test_model_sub(orm.Model): _name = 'test_converter.test_model.sub' diff --git a/openerp/addons/test_converter/tests/__init__.py b/openerp/addons/test_converter/tests/__init__.py index 493b164d44a..16946f57713 100644 --- a/openerp/addons/test_converter/tests/__init__.py +++ b/openerp/addons/test_converter/tests/__init__.py @@ -1,12 +1,13 @@ # -*- coding: utf-8 -*- -from . import test_html +from . import test_html, test_gbf fast_suite = [ ] checks = [ - test_html + test_html, + test_gbf, ] # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/test_converter/tests/test_gbf.py b/openerp/addons/test_converter/tests/test_gbf.py new file mode 100644 index 00000000000..5c97f9c8609 --- /dev/null +++ b/openerp/addons/test_converter/tests/test_gbf.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +from openerp.tests import common + +class TestGBF(common.TransactionCase): + + def test_group_by_full(self): + + Subs = self.registry('test_converter.test_model.sub') + TM = self.registry('test_converter.test_model') + + # remove all existing subs (no need to panic, it will be rollbacked...) + all_subs = Subs.search(self.cr, self.uid, []) + if all_subs: + Subs.unlink(self.cr, self.uid, all_subs) + + subs_ids = [Subs.create(self.cr, self.uid, {'name': 'sub%d' % i}) for i in range(5)] + tm_ids = [TM.create(self.cr, self.uid, {'many2one': subs_ids[i]}) for i in range(3)] + + domain = [('id', 'in', tuple(tm_ids))] + + rg = TM.read_group(self.cr, self.uid, domain, fields=['many2one'], groupby=['many2one']) + + self.assertEqual(len(rg), len(subs_ids)) + rg_subs = sorted(g['many2one'][0] for g in rg) + self.assertListEqual(rg_subs, sorted(subs_ids)) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 2ea51704b7e..853ec4c600c 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -2153,7 +2153,8 @@ class BaseModel(object): pass - def _read_group_fill_results(self, cr, uid, domain, groupby, remaining_groupbys, aggregated_fields, + def _read_group_fill_results(self, cr, uid, domain, groupby, remaining_groupbys, + aggregated_fields, count_field, read_group_result, read_group_order=None, context=None): """Helper method for filling in empty groups for all possible values of the field being grouped by""" @@ -2182,19 +2183,13 @@ class BaseModel(object): result = [] known_values = {} - if len(groupby_list) < 2 and context.get('group_by_no_leaf'): - count_attr = '_' - else: - count_attr = groupby - count_attr += '_count' - def append_left(left_side): grouped_value = left_side[groupby] and left_side[groupby][0] if not grouped_value in known_values: result.append(left_side) known_values[grouped_value] = left_side else: - known_values[grouped_value].update({count_attr: left_side[count_attr]}) + known_values[grouped_value].update({count_field: left_side[count_field]}) def append_right(right_side): grouped_value = right_side[0] if not grouped_value in known_values: @@ -2438,12 +2433,13 @@ class BaseModel(object): count_field = groupby_fields[0] if len(groupby_fields) >= 1 else '_' else: count_field = '_' + count_field += '_count' prefix_terms = lambda prefix, terms: (prefix + " " + ",".join(terms)) if terms else '' prefix_term = lambda prefix, term: ('%s %s' % (prefix, term)) if term else '' query = """ - SELECT min(%(table)s.id) AS id, count(%(table)s.id) AS %(count_field)s_count %(extra_fields)s + SELECT min(%(table)s.id) AS id, count(%(table)s.id) AS %(count_field)s %(extra_fields)s FROM %(from)s %(where)s %(groupby)s @@ -2483,7 +2479,7 @@ class BaseModel(object): # method _read_group_fill_results need to be completely reimplemented # in a sane way result = self._read_group_fill_results(cr, uid, domain, groupby_fields[0], groupby[len(annotated_groupbys):], - aggregated_fields, result, read_group_order=order, + aggregated_fields, count_field, result, read_group_order=order, context=context) return result