From 30ede6a16afbb9f46033ef58c81ed7a7229959d4 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Wed, 4 Jul 2018 15:34:01 +0200 Subject: [PATCH] [FIX] pos_sale, sales_team: Timezone problem in dashboard graph The function _get_graph computing the dashboard graph must take the timezone of the user into account to compute the right start_date S and the right end_date E. The query made on model 'report.pos.order' by read_group in _graph_data must take the timezone of the user into account to substract the right offset to compute the start_date S and end_date E in UTC because the result returned by read_group is formated in the timezone of the user afterwards. Example: In function _get_graph: Start_date in 'Asia/Ulaanbaatar' timezone = 2018-06-05 End_date in 'Asia/Ulaanbaatar' timezone = 2018-07-04 So End_date - Start_date + 1 = 30 In function _graph_data: Start_date in 'Asia/Ulaanbaatar' timezone = 2018-06-05 00:00:00 End_date in 'Asia/Ulaanbaatar' timezone = 2018-07-04 23:59:59 So in UTC -9 hours: Start_date in UTC = 2018-06-04 15:00:00 End_date in UTC = 2018-07-04 14:59:59 SELECT min("report_pos_order".id) AS id, count("report_pos_order".id) AS "date_count" , sum("report_pos_order"."price_total") AS "price_total" , date_trunc('day', timezone('Asia/Ulaanbaatar', timezone('UTC',"report_pos_order"."date"))) as "date:day" FROM "report_pos_order" WHERE (((("report_pos_order"."date" >= Start_date) AND ("report_pos_order"."date" <= End_date)) AND ("report_pos_order"."config_id" in (1,2,3))) AND ("report_pos_order"."state" in ('paid','done','invoiced'))) GROUP BY date_trunc('day', timezone('Asia/Ulaanbaatar', timezone('UTC',"report_pos_order"."date"))) ORDER BY "date:day" And the result of this request will be between 2018-06-05 00:00:00 and 2018-07-04 23:59:59 but before the fix the result was between 2018-06-05 00:09:00 and 2018-07-05 08:59:59 and then End_date - Start_date + 1 was equal to 31. That's why a "IndexError: list index out of range" can be raised in _get_graph. In this way, no mismatch is possible between the datas computed by _graph_data and the dict "values" allocated by _get_graph. opw:1862996 --- addons/pos_sale/models/crm_team.py | 16 ++++++++++------ addons/sales_team/models/crm_team.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/addons/pos_sale/models/crm_team.py b/addons/pos_sale/models/crm_team.py index 54eed6c160b..341e275a791 100644 --- a/addons/pos_sale/models/crm_team.py +++ b/addons/pos_sale/models/crm_team.py @@ -3,6 +3,7 @@ from odoo import api, fields, models, _ from datetime import datetime +import pytz class CrmTeam(models.Model): @@ -41,13 +42,16 @@ class CrmTeam(models.Model): """ If the type of the sales team is point of sale ('pos'), the graph will display the sales data. The override here is to get data from pos.order instead of sale.order. """ + offset = datetime.now(pytz.timezone(self.env.user.tz or 'UTC')).utcoffset() + min_date = fields.Datetime.to_string(datetime.combine(start_date, datetime.min.time()) - offset) + max_date = fields.Datetime.to_string(datetime.combine(end_date, datetime.max.time()) - offset) if self.team_type == 'pos': result = [] if self.dashboard_graph_group_pos == 'pos': order_data = self.env['report.pos.order'].read_group( domain=[ - ('date', '>=', fields.Date.to_string(start_date)), - ('date', '<=', fields.Datetime.to_string(datetime.combine(end_date, datetime.max.time()))), + ('date', '>=', min_date), + ('date', '<=', max_date), ('config_id', 'in', self.pos_config_ids.ids), ('state', 'in', ['paid', 'done', 'invoiced'])], fields=['config_id', 'price_total'], @@ -63,8 +67,8 @@ class CrmTeam(models.Model): elif self.dashboard_graph_group_pos == 'user': order_data = self.env['report.pos.order'].read_group( domain=[ - ('date', '>=', fields.Date.to_string(start_date)), - ('date', '<=', fields.Datetime.to_string(datetime.combine(end_date, datetime.max.time()))), + ('date', '>=', min_date), + ('date', '<=', max_date), ('config_id', 'in', self.pos_config_ids.ids), ('state', 'in', ['paid', 'done', 'invoiced'])], fields=['user_id', 'price_total'], @@ -78,8 +82,8 @@ class CrmTeam(models.Model): # /!\ do not use en_US as it's not ISO-standard and does not match datetime's library order_data = self.env['report.pos.order'].with_context(lang='en_GB').read_group( domain=[ - ('date', '>=', fields.Date.to_string(start_date)), - ('date', '<=', fields.Datetime.to_string(datetime.combine(end_date, datetime.max.time()))), + ('date', '>=', min_date), + ('date', '<=', max_date), ('config_id', 'in', self.pos_config_ids.ids), ('state', 'in', ['paid', 'done', 'invoiced'])], fields=['date', 'price_total'], diff --git a/addons/sales_team/models/crm_team.py b/addons/sales_team/models/crm_team.py index 96ed4dcc942..f749d87fff2 100644 --- a/addons/sales_team/models/crm_team.py +++ b/addons/sales_team/models/crm_team.py @@ -177,7 +177,7 @@ class CrmTeam(models.Model): self.ensure_one() values = [] - today = date.today() + today = fields.Date.from_string(fields.Date.context_today(self)) start_date, end_date = self._graph_get_dates(today) graph_data = self._graph_data(start_date, end_date)