diff options
| author | Aurélien (avd) <avd@odoo.com> | 2021-03-03 16:46:00 +0000 |
|---|---|---|
| committer | Aurélien (avd) <avd@odoo.com> | 2021-04-16 08:25:41 +0000 |
| commit | a05244c0b2a1d9c873696f7a856c438435e4cdf5 (patch) | |
| tree | 6bf6a64d205e5c1c24651db70432b3e875b3bcb8 /addons | |
| parent | 3e20e68f0790a0b0f3b5c4d43f59f235b7d20fef (diff) | |
[FIX] google_calendar: turn off notifications to improve perfs.
Turn off calendar.attendees notification during synced_events creation
to improve performances. The calendar notification are only computed
once after all the synced events have been created.
Add a flag in google_calendar.js to avoid retriggering synchronization
while navigating the calendar view if the past synchronization is still
pending.
Diffstat (limited to 'addons')
4 files changed, 47 insertions, 5 deletions
diff --git a/addons/google_calendar/models/calendar.py b/addons/google_calendar/models/calendar.py index ba455fa2111..0079c9c049d 100644 --- a/addons/google_calendar/models/calendar.py +++ b/addons/google_calendar/models/calendar.py @@ -226,3 +226,10 @@ class Meeting(models.Model): super(Meeting, my_cancelled_records)._cancel() attendees = (self - my_cancelled_records).attendee_ids.filtered(lambda a: a.partner_id == user.partner_id) attendees.state = 'declined' + + def _notify_attendees(self): + # filter events before notifying attendees through calendar_alarm_manager + need_notifs = self.filtered(lambda event: event.alarm_ids and event.stop >= fields.Datetime.now()) + partners = need_notifs.partner_ids + if partners: + self.env['calendar.alarm_manager']._notify_next_alarm(partners.ids) diff --git a/addons/google_calendar/models/calendar_recurrence_rule.py b/addons/google_calendar/models/calendar_recurrence_rule.py index 055359fa8f9..c9ff1566e9f 100644 --- a/addons/google_calendar/models/calendar_recurrence_rule.py +++ b/addons/google_calendar/models/calendar_recurrence_rule.py @@ -2,6 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. import re +from dateutil.relativedelta import relativedelta from odoo import api, fields, models @@ -131,8 +132,10 @@ class RecurrenceRule(models.Model): vals['calendar_event_ids'] = [(4, base_event.id)] # event_tz is written on event in Google but on recurrence in Odoo vals['event_tz'] = gevent.start.get('timeZone') - recurrence = super()._create_from_google(gevents, vals_list) - recurrence._apply_recurrence() + recurrence = super(RecurrenceRule, self.with_context(dont_notify=True))._create_from_google(gevents, vals_list) + recurrence.with_context(dont_notify=True)._apply_recurrence() + if not recurrence._context.get("dont_notify"): + recurrence._notify_attendees() return recurrence def _get_sync_domain(self): @@ -172,3 +175,13 @@ class RecurrenceRule(models.Model): }, } return values + + def _notify_attendees(self): + recurrences = self.filtered( + lambda recurrence: recurrence.base_event_id.alarm_ids and ( + not recurrence.until or recurrence.until >= fields.Date.today() - relativedelta(days=1) + ) and (max(recurrence.calendar_event_ids.mapped('stop')) >= fields.Datetime.now()) + ) + partners = recurrences.base_event_id.partner_ids + if partners: + self.env['calendar.alarm_manager']._notify_next_alarm(partners.ids) diff --git a/addons/google_calendar/models/google_sync.py b/addons/google_calendar/models/google_sync.py index e1486bac47e..94be4051735 100644 --- a/addons/google_calendar/models/google_sync.py +++ b/addons/google_calendar/models/google_sync.py @@ -155,12 +155,15 @@ class GoogleSync(models.AbstractModel): dict(self._odoo_values(e, default_reminders), need_sync=False) for e in new ] - new_odoo = self._create_from_google(new, odoo_values) + new_odoo = self.with_context(dont_notify=True)._create_from_google(new, odoo_values) + # Synced recurrences attendees will be notified once _apply_recurrence is called. + if not self._context.get("dont_notify") and all(not e.is_recurrence() for e in google_events): + new_odoo._notify_attendees() + cancelled = existing.cancelled() cancelled_odoo = self.browse(cancelled.odoo_ids(self.env)) cancelled_odoo._cancel() - - synced_records = new_odoo + cancelled_odoo + synced_records = (new_odoo + cancelled_odoo).with_context(dont_notify=self._context.get("dont_notify", False)) for gevent in existing - cancelled: # Last updated wins. # This could be dangerous if google server time and odoo server time are different @@ -251,3 +254,13 @@ class GoogleSync(models.AbstractModel): marks the record to be re-synchronized. """ raise NotImplementedError() + + def _notify_attendees(self): + """ Notify calendar event partners. + This is called when creating new calendar events in _sync_google2odoo. + At the initialization of a synced calendar, Odoo requests all events for a specific + GoogleCalendar. Among those there will probably be lots of events that will never triggers a notification + (e.g. single events that occured in the past). Processing all these events through the notification procedure + of calendar.event.create is a possible performance bottleneck. This method aimed at alleviating that. + """ + raise NotImplementedError() diff --git a/addons/google_calendar/static/src/js/google_calendar.js b/addons/google_calendar/static/src/js/google_calendar.js index ec8313e0e9e..6e250d7b8da 100644 --- a/addons/google_calendar/static/src/js/google_calendar.js +++ b/addons/google_calendar/static/src/js/google_calendar.js @@ -21,6 +21,7 @@ const GoogleCalendarModel = CalendarModel.include({ init: function () { this._super.apply(this, arguments); this.google_is_sync = true; + this.google_pending_sync = false; }, /** @@ -39,6 +40,11 @@ const GoogleCalendarModel = CalendarModel.include({ */ async _loadCalendar() { const _super = this._super.bind(this); + // When the calendar synchronization takes some time, prevents retriggering the sync while navigating the calendar. + if (this.google_pending_sync) { + return _super(...arguments); + } + try { await Promise.race([ new Promise(resolve => setTimeout(resolve, 1000)), @@ -49,6 +55,7 @@ const GoogleCalendarModel = CalendarModel.include({ error.event.preventDefault(); } console.error("Could not synchronize Google events now.", error); + this.google_pending_sync = false; } return _super(...arguments); }, @@ -56,6 +63,7 @@ const GoogleCalendarModel = CalendarModel.include({ _syncGoogleCalendar(shadow = false) { var self = this; var context = this.getSession().user_context; + this.google_pending_sync = true; return this._rpc({ route: '/google_calendar/sync_data', params: { @@ -69,6 +77,7 @@ const GoogleCalendarModel = CalendarModel.include({ } else if (result.status === "no_new_event_from_google" || result.status === "need_refresh") { self.google_is_sync = true; } + self.google_pending_sync = false; return result }); }, |
