diff --git a/addons/google_calendar/models/res_users.py b/addons/google_calendar/models/res_users.py index c636c3e0bc9..69a4a3d316b 100644 --- a/addons/google_calendar/models/res_users.py +++ b/addons/google_calendar/models/res_users.py @@ -53,24 +53,10 @@ class User(models.Model): def _sync_google_calendar(self, calendar_service: GoogleCalendarService): self.ensure_one() - if self._get_google_sync_status() != "sync_active": + results = self._sync_request(calendar_service) + if not results or not results.get('events'): return False - # don't attempt to sync when another sync is already in progress, as we wouldn't be - # able to commit the transaction anyway (row is locked) - self.env.cr.execute("""SELECT id FROM res_users WHERE id = %s FOR NO KEY UPDATE SKIP LOCKED""", [self.id]) - if not self.env.cr.rowcount: - _logger.info("skipping calendar sync, locked user %s", self.login) - return False - - full_sync = not bool(self.google_calendar_sync_token) - with google_calendar_token(self) as token: - try: - events, next_sync_token, default_reminders = calendar_service.get_events(self.google_calendar_account_id.calendar_sync_token, token=token) - except InvalidSyncToken: - events, next_sync_token, default_reminders = calendar_service.get_events(token=token) - full_sync = True - self.google_calendar_account_id.calendar_sync_token = next_sync_token - + events, default_reminders, full_sync = results.values() # Google -> Odoo send_updates = not full_sync events.clear_type_ambiguity(self.env) @@ -89,6 +75,50 @@ class User(models.Model): return bool(events | synced_events) or bool(recurrences | synced_recurrences) + def _sync_single_event(self, calendar_service: GoogleCalendarService, odoo_event, event_id): + self.ensure_one() + results = self._sync_request(calendar_service, event_id) + if not results or not results.get('events'): + return False + event, default_reminders, full_sync = results.values() + # Google -> Odoo + send_updates = not full_sync + event.clear_type_ambiguity(self.env) + synced_events = self.env['calendar.event']._sync_google2odoo(event, default_reminders=default_reminders) + # Odoo -> Google + odoo_event.with_context(send_updates=send_updates)._sync_odoo2google(calendar_service) + return bool(odoo_event | synced_events) + + def _sync_request(self, calendar_service, event_id=None): + if self._get_google_sync_status() != "sync_active": + return False + # don't attempt to sync when another sync is already in progress, as we wouldn't be + # able to commit the transaction anyway (row is locked) + self.env.cr.execute("""SELECT id FROM res_users WHERE id = %s FOR NO KEY UPDATE SKIP LOCKED""", [self.id]) + if not self.env.cr.rowcount: + _logger.info("skipping calendar sync, locked user %s", self.login) + return False + + full_sync = not bool(self.google_calendar_sync_token) + with google_calendar_token(self) as token: + try: + if not event_id: + events, next_sync_token, default_reminders = calendar_service.get_events(self.google_calendar_account_id.calendar_sync_token, token=token) + else: + # We force the sync_token parameter to avoid doing a full sync. + # Other events are fetched when the calendar view is displayed. + events, next_sync_token, default_reminders = calendar_service.get_events(sync_token=token, token=token, event_id=event_id) + except InvalidSyncToken: + events, next_sync_token, default_reminders = calendar_service.get_events(token=token) + full_sync = True + if next_sync_token: + self.google_calendar_account_id.calendar_sync_token = next_sync_token + return { + 'events': events, + 'default_reminders': default_reminders, + 'full_sync': full_sync, + } + @api.model def _sync_all_google_calendar(self): """ Cron job """ diff --git a/addons/google_calendar/utils/google_calendar.py b/addons/google_calendar/utils/google_calendar.py index a2bf89bd32d..d063de6806a 100644 --- a/addons/google_calendar/utils/google_calendar.py +++ b/addons/google_calendar/utils/google_calendar.py @@ -29,8 +29,10 @@ class GoogleCalendarService(): self.google_service = google_service @requires_auth_token - def get_events(self, sync_token=None, token=None, timeout=TIMEOUT): + def get_events(self, sync_token=None, token=None, event_id=None, timeout=TIMEOUT): url = "/calendar/v3/calendars/primary/events" + if event_id: + url += f"/{event_id}" headers = {'Content-type': 'application/json'} params = {'access_token': token} if sync_token: @@ -51,6 +53,11 @@ class GoogleCalendarService(): raise InvalidSyncToken("Invalid sync token. Full sync required") raise e + if event_id: + next_sync_token = None + default_reminders = () + return GoogleEvent([data]), next_sync_token, default_reminders + events = data.get('items', []) next_page_token = data.get('nextPageToken') while next_page_token: