From a2993fc85d03194d1305720703b74391d5fce2cf Mon Sep 17 00:00:00 2001 From: "Gabriel de Paula Felix (gdpf)" Date: Tue, 24 Oct 2023 11:13:16 -0300 Subject: [PATCH] [FIX] microsoft_calendar: limit events request range to calendar view Before this commit, a time window of two years was being used for requesting events occurrences from Microsoft Graph API. This way, events that were not being visualized in the calendar view were being fetched from the API many times, wasting requests and decreasing the calendar app's performance. After this commit, this time window is limited to the range being shown in the calendar view to avoid fetching events not being visualized and then increase performance. closes odoo/odoo#139721 Task-id: 3525764 X-original-commit: ceab3ee21d3e6eb4cfcf0a0cd8df40873744beaa Signed-off-by: Arnaud Joset (arj) --- addons/microsoft_calendar/controllers/main.py | 14 +++++++++++++- .../microsoft_calendar_model.js | 15 +++++++++++---- .../tests/test_microsoft_service.py | 8 ++++---- .../utils/microsoft_calendar.py | 15 +++++++++++++-- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/addons/microsoft_calendar/controllers/main.py b/addons/microsoft_calendar/controllers/main.py index 89814f68624..9399e222358 100644 --- a/addons/microsoft_calendar/controllers/main.py +++ b/addons/microsoft_calendar/controllers/main.py @@ -5,6 +5,8 @@ from odoo import http from odoo.http import request from odoo.addons.calendar.controllers.main import CalendarController +from dateutil.parser import parse + class MicrosoftCalendarController(CalendarController): @@ -40,8 +42,18 @@ class MicrosoftCalendarController(CalendarController): "status": "need_auth", "url": url } + # Get synchronization time window form calendar view if received through parameters. + sync_context = {} + range_start_date = kw.get('rangeStart') + range_end_date = kw.get('rangeEnd') + if range_start_date and range_end_date: + sync_context.update({ + 'range_start_date': parse(range_start_date), + 'range_end_date': parse(range_end_date), + }) + # If App authorized, and user access accepted, We launch the synchronization - need_refresh = request.env.user.sudo()._sync_microsoft_calendar() + need_refresh = request.env.user.sudo().with_context(sync_context)._sync_microsoft_calendar() # If synchronization has been stopped or paused sync_status = request.env.user._get_microsoft_sync_status() diff --git a/addons/microsoft_calendar/static/src/views/microsoft_calendar/microsoft_calendar_model.js b/addons/microsoft_calendar/static/src/views/microsoft_calendar/microsoft_calendar_model.js index 2f7c50f29cb..7ab5dd43235 100644 --- a/addons/microsoft_calendar/static/src/views/microsoft_calendar/microsoft_calendar_model.js +++ b/addons/microsoft_calendar/static/src/views/microsoft_calendar/microsoft_calendar_model.js @@ -2,6 +2,7 @@ import { AttendeeCalendarModel } from "@calendar/views/attendee_calendar/attendee_calendar_model"; import { patch } from "@web/core/utils/patch"; +import { serializeDateTime } from "@web/core/l10n/dates"; patch(AttendeeCalendarModel, { services: [...AttendeeCalendarModel.services, "rpc"], @@ -40,12 +41,18 @@ patch(AttendeeCalendarModel.prototype, { async syncMicrosoftCalendar(silent = false) { this.microsoftPendingSync = true; + const request = { + model: this.resModel, + fromurl: window.location.href, + } + // Check if this.data.range is not null before adding rangeStart and rangeEnd. + if (this.data && this.data.range) { + request.rangeStart = serializeDateTime(this.data.range.start); + request.rangeEnd = serializeDateTime(this.data.range.end); + } const result = await this.rpc( "/microsoft_calendar/sync_data", - { - model: this.resModel, - fromurl: window.location.href - }, + request, { silent, }, diff --git a/addons/microsoft_calendar/tests/test_microsoft_service.py b/addons/microsoft_calendar/tests/test_microsoft_service.py index 136e979ae95..471b954f8db 100644 --- a/addons/microsoft_calendar/tests/test_microsoft_service.py +++ b/addons/microsoft_calendar/tests/test_microsoft_service.py @@ -38,8 +38,8 @@ class TestMicrosoftService(TransactionCase): self.call_without_sync_token = call( "/v1.0/me/calendarView/delta", { - 'startDateTime': fields.Datetime.subtract(fields.Datetime.now(), years=2).strftime("%Y-%m-%dT00:00:00Z"), - 'endDateTime': fields.Datetime.add(fields.Datetime.now(), years=2).strftime("%Y-%m-%dT00:00:00Z"), + 'startDateTime': fields.Datetime.subtract(fields.Datetime.now(), days=365).strftime("%Y-%m-%dT00:00:00Z"), + 'endDateTime': fields.Datetime.add(fields.Datetime.now(), days=365).strftime("%Y-%m-%dT00:00:00Z"), }, {**self.header, 'Prefer': self.header_prefer}, method="GET", timeout=DEFAULT_TIMEOUT, @@ -224,8 +224,8 @@ class TestMicrosoftService(TransactionCase): mock_do_request.assert_called_with( "/v1.0/me/events/123/instances", { - 'startDateTime': fields.Datetime.subtract(fields.Datetime.now(), years=2).strftime("%Y-%m-%dT00:00:00Z"), - 'endDateTime': fields.Datetime.add(fields.Datetime.now(), years=2).strftime("%Y-%m-%dT00:00:00Z"), + 'startDateTime': fields.Datetime.subtract(fields.Datetime.now(), days=365).strftime("%Y-%m-%dT00:00:00Z"), + 'endDateTime': fields.Datetime.add(fields.Datetime.now(), days=365).strftime("%Y-%m-%dT00:00:00Z"), }, {**self.header, 'Prefer': self.header_prefer}, method='GET', timeout=DEFAULT_TIMEOUT, diff --git a/addons/microsoft_calendar/utils/microsoft_calendar.py b/addons/microsoft_calendar/utils/microsoft_calendar.py index 2e4cb30e1cf..b22cb2866cd 100644 --- a/addons/microsoft_calendar/utils/microsoft_calendar.py +++ b/addons/microsoft_calendar/utils/microsoft_calendar.py @@ -56,9 +56,20 @@ class MicrosoftCalendarService(): 'Prefer': 'outlook.body-content-type="html", odata.maxpagesize=50' } if not params: + # Get context keys limiting query range for reducing requests and then increase performance. + start_date = self.microsoft_service._context.get('range_start_date') + end_date = self.microsoft_service._context.get('range_end_date') + if start_date and end_date: + start_date = start_date.strftime("%Y-%m-%dT00:00:00Z") + end_date = end_date.strftime("%Y-%m-%dT00:00:00Z") + else: + ICP = self.microsoft_service.env['ir.config_parameter'].sudo() + day_range = int(ICP.get_param('microsoft_calendar.sync.range_days', default=365)) + start_date = fields.Datetime.subtract(fields.Datetime.now(), days=day_range).strftime("%Y-%m-%dT00:00:00Z") + end_date = fields.Datetime.add(fields.Datetime.now(), days=day_range).strftime("%Y-%m-%dT00:00:00Z") params = { - 'startDateTime': fields.Datetime.subtract(fields.Datetime.now(), years=2).strftime("%Y-%m-%dT00:00:00Z"), - 'endDateTime': fields.Datetime.add(fields.Datetime.now(), years=2).strftime("%Y-%m-%dT00:00:00Z"), + 'startDateTime': start_date, + 'endDateTime': end_date, } # get the first page of events