From 283c842289f1bc06bc30a877864e868127418e80 Mon Sep 17 00:00:00 2001 From: RomainLibert Date: Fri, 7 Sep 2018 14:02:45 +0200 Subject: [PATCH] [FIX] models: support multiple group by in _read_group_fill_temporal The method _read_group_fill_temporal did not support multiple levels of groupby. Which meant that everytime you grouped by a date and by something else you had a traceback. --- odoo/models.py | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/odoo/models.py b/odoo/models.py index 3aa493663eb..8f3737c1fcb 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -1811,37 +1811,23 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): # assumption: existing data is sorted by field 'groupby_name' first, last = existing[0], existing[-1] - expected = collections.deque(date_utils.date_range(first, last, interval)) + empty_item = {'id': False, (groupby_name.split(':')[0] + '_count'): 0} + empty_item.update({key: False for key in aggregated_fields}) + empty_item.update({key: False for key in [group['field'] for group in annotated_groupbys[1:]]}) - if len(existing) < len(expected): - empty_data = dict.fromkeys(aggregated_fields, False) - empty_data['id'] = False - empty_data[groupby_name.split(':')[0] + '_count'] = 0 + grouped_data = collections.defaultdict(list) + for d in data: + grouped_data[d[groupby_name]].append(d) - data = collections.deque(data) + result = [] - new_data = [] + for dt in date_utils.date_range(first, last, interval): + result.extend(grouped_data[dt] or [dict(empty_item, **{groupby_name: dt})]) - # Note: the list 'expected' contains the the dates that should be - # represented inside data when it is returned. Notice that 'expected' - # is sorted like data, so what we do is empty data progressivly by - # popping its elements from first to last. To do this properly, we - # need to compare dates together. - while expected or data: - if not data[0][groupby_name]: - new_data.append(data.popleft()) - continue - dt = expected.popleft() - if data[0][groupby_name] == dt: - new_data.append(data.popleft()) - else: - new_data.append(dict(empty_data, **{groupby_name: dt})) - - assert not data - return new_data - - return data + if False in grouped_data: + result.extend(grouped_data[False]) + return result @api.model def _read_group_prepare(self, orderby, aggregated_fields, annotated_groupbys, query):