From ed0bf2baecdac711d507307f021f743c28ae45e8 Mon Sep 17 00:00:00 2001 From: abd-msyukyu-odoo Date: Thu, 24 Aug 2023 15:25:35 +0000 Subject: [PATCH] [FIX] base: filled week groups should be dependent on the locale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit How to reproduce: - open CRM > Forecast - group by Expected Closing > Week Current behavior: - some week numbers appear multiple times Expected behavior: - each week should only appear once Technical explanation: Since [1], week groups are dependent on the locale, but the `_read_group_fill_temporal` method was not updated to also produce groups dependent on the locale. [1]: https://github.com/odoo/odoo/pull/93053 task-3478451 closes odoo/odoo#135952 X-original-commit: 980786e301bdf80a9a39260a95359431c5cb5e86 Signed-off-by: Damien Abeloos (abd) Signed-off-by: Rémy Voet (ryv) --- .../tests/test_fill_temporal.py | 60 +++++++++++++++++++ odoo/models.py | 10 +++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/odoo/addons/test_read_group/tests/test_fill_temporal.py b/odoo/addons/test_read_group/tests/test_fill_temporal.py index 6f178f0190f..07dcb0ed19b 100644 --- a/odoo/addons/test_read_group/tests/test_fill_temporal.py +++ b/odoo/addons/test_read_group/tests/test_fill_temporal.py @@ -777,6 +777,66 @@ class TestFillTemporal(common.TransactionCase): self.assertEqual(groups, expected) + def test_with_bounds_groupby_week(self): + """Test data with weeks starting on Sunday and forced boundaries.""" + self.Model.create([ + {'date': '1916-08-19', 'value': 4}, # saturday W34 + {'date': '1916-08-20', 'value': 13}, # sunday W35 + {'date': '1916-09-10', 'value': 5}, # sunday W38 + {'date': '1916-08-18', 'value': 3}, # friday W34 + {'date': '1916-09-11', 'value': 4}, # monday W38 + {'date': '1916-09-12', 'value': 11}, # tuesday W38 + ]) + + expected = [{ + '__domain': ['&', ('date', '>=', '1916-08-06'), ('date', '<', '1916-08-13')], + '__range': {'date:week': {'from': '1916-08-06', 'to': '1916-08-13'}}, + 'date:week': 'W33 1916', + 'date_count': 0, + 'value': 0, + }, { + '__domain': ['&', ('date', '>=', '1916-08-13'), ('date', '<', '1916-08-20')], + '__range': {'date:week': {'from': '1916-08-13', 'to': '1916-08-20'}}, + 'date:week': 'W34 1916', + 'date_count': 2, + 'value': 7, + }, { + '__domain': ['&', ('date', '>=', '1916-08-20'), ('date', '<', '1916-08-27')], + '__range': {'date:week': {'from': '1916-08-20', 'to': '1916-08-27'}}, + 'date:week': 'W35 1916', + 'date_count': 1, + 'value': 13, + }, { + '__domain': ['&', ('date', '>=', '1916-08-27'), ('date', '<', '1916-09-03')], + '__range': {'date:week': {'from': '1916-08-27', 'to': '1916-09-03'}}, + 'date:week': 'W36 1916', + 'date_count': 0, + 'value': 0, + }, { + '__domain': ['&', ('date', '>=', '1916-09-03'), ('date', '<', '1916-09-10')], + '__range': {'date:week': {'from': '1916-09-03', 'to': '1916-09-10'}}, + 'date:week': 'W37 1916', + 'date_count': 0, + 'value': 0, + }, { + '__domain': ['&', ('date', '>=', '1916-09-10'), ('date', '<', '1916-09-17')], + '__range': {'date:week': {'from': '1916-09-10', 'to': '1916-09-17'}}, + 'date:week': 'W38 1916', + 'date_count': 3, + 'value': 20, + }, { + '__domain': ['&', ('date', '>=', '1916-09-17'), ('date', '<', '1916-09-24')], + '__range': {'date:week': {'from': '1916-09-17', 'to': '1916-09-24'}}, + 'date:week': 'W39 1916', + 'date_count': 0, + 'value': 0, + }] + + model_fill = self.Model.with_context(fill_temporal={"fill_from": '1916-08-10', "fill_to": '1916-09-20'}) + groups = model_fill.read_group([], fields=['date', 'value'], groupby=['date:week']) + + self.assertEqual(groups, expected) + def test_upper_bound(self): """Test the alternative dictionary format for the fill_temporal context key (fill_to). diff --git a/odoo/models.py b/odoo/models.py index 633b81307c7..c5c0a5cb095 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -2349,6 +2349,12 @@ class BaseModel(metaclass=MetaModel): return data granularity = first_group.split(':')[1] if ':' in first_group else 'month' + days_offset = 0 + if granularity == 'week': + # _read_group_process_groupby week groups are dependent on the + # locale, so filled groups should be too to avoid overlaps. + first_week_day = int(get_lang(self.env).week_start) - 1 + days_offset = first_week_day and 7 - first_week_day interval = READ_GROUP_TIME_GRANULARITY[granularity] tz = False if field.type == 'datetime' and self._context.get('tz') in pytz.all_timezones_set: @@ -2362,14 +2368,14 @@ class BaseModel(metaclass=MetaModel): existing_from, existing_to = existing[0], existing[-1] if fill_from: fill_from = odoo.fields.Datetime.to_datetime(fill_from) if isinstance(fill_from, datetime.datetime) else odoo.fields.Date.to_date(fill_from) - fill_from = date_utils.start_of(fill_from, granularity) + fill_from = date_utils.start_of(fill_from, granularity) - datetime.timedelta(days=days_offset) if tz: fill_from = tz.localize(fill_from) elif existing_from: fill_from = existing_from if fill_to: fill_to = odoo.fields.Datetime.to_datetime(fill_to) if isinstance(fill_to, datetime.datetime) else odoo.fields.Date.to_date(fill_to) - fill_to = date_utils.start_of(fill_to, granularity) + fill_to = date_utils.start_of(fill_to, granularity) - datetime.timedelta(days=days_offset) if tz: fill_to = tz.localize(fill_to) elif existing_to: