def _google_delete(self, google_service: GoogleCalendarService, google_id, timeout=TIMEOUT): with google_calendar_token(self.env.user.sudo()) as token: if token: google_service.delete(google_id, token=token, timeout=timeout) # When the record has been deleted on our side, we need to delete it on google but we don't want # to raise an error because the record don't exists anymore. self.exists().need_sync = False
def _sync_google_calendar(self, calendar_service: GoogleCalendarService): self.ensure_one() 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_sync_token, token=token) except InvalidSyncToken: events, next_sync_token, default_reminders = calendar_service.get_events(token=token) full_sync = True self.google_calendar_sync_token = next_sync_token # Google -> Flectra events.clear_type_ambiguity(self.env) recurrences = events.filter(lambda e: e.is_recurrence()) synced_recurrences = self.env['calendar.recurrence']._sync_google2flectra(recurrences) synced_events = self.env['calendar.event']._sync_google2flectra(events - recurrences, default_reminders=default_reminders) # Flectra -> Google recurrences = self.env['calendar.recurrence']._get_records_to_sync(full_sync=full_sync) recurrences -= synced_recurrences recurrences._sync_flectra2google(calendar_service) synced_events |= recurrences.calendar_event_ids - recurrences._get_outliers() events = self.env['calendar.event']._get_records_to_sync(full_sync=full_sync) (events - synced_events)._sync_flectra2google(calendar_service) return bool(events | synced_events) or bool(recurrences | synced_recurrences)
def write(self, vals): res = super().write(vals) if vals.get('state'): # When the state is changed, the corresponding event must be sync with google google_service = GoogleCalendarService(self.env['google.service']) self.event_id.filtered('google_id')._sync_flectra2google(google_service) return res
def _apply_recurrence(self, specific_values_creation=None, no_send_edit=False): events = self.filtered('need_sync').calendar_event_ids detached_events = super()._apply_recurrence(specific_values_creation, no_send_edit) google_service = GoogleCalendarService(self.env['google.service']) # If a synced event becomes a recurrence, the event needs to be deleted from # Google since it's now the recurrence which is synced. # Those events are kept in the database and their google_id is updated # according to the recurrence google_id, therefore we need to keep an inactive copy # of those events with the original google id. The next sync will then correctly # delete those events from Google. vals = [] for event in events.filtered('google_id'): if event.active and event.google_id != event.recurrence_id._get_event_google_id( event): vals += [{ 'name': event.name, 'google_id': event.google_id, 'start': event.start, 'stop': event.stop, 'active': False, 'need_sync': True, }] event._google_delete(google_service, event.google_id) event.google_id = False self.env['calendar.event'].create(vals) self.calendar_event_ids.need_sync = False return detached_events
def _sync_all_google_calendar(self): """ Cron job """ users = self.env['res.users'].search([('google_calendar_rtoken', '!=', False)]) google = GoogleCalendarService(self.env['google.service']) for user in users: _logger.info("Calendar Synchro - Starting synchronization for %s", user) try: user.with_user(user).sudo()._sync_google_calendar(google) except Exception as e: _logger.exception("[%s] Calendar Synchro - Exception : %s !", user, exception_to_unicode(e))
def create(self, vals_list): if any(vals.get('google_id') for vals in vals_list): self._from_google_ids.clear_cache(self) records = super().create(vals_list) google_service = GoogleCalendarService(self.env['google.service']) records_to_sync = records.filtered(lambda r: r.need_sync and r.active) for record in records_to_sync: record._google_insert(google_service, record._google_values(), timeout=3) return records
def _google_insert(self, google_service: GoogleCalendarService, values, timeout=TIMEOUT): if not values: return with google_calendar_token(self.env.user.sudo()) as token: if token: google_id = google_service.insert(values, token=token, timeout=timeout) self.write({ 'google_id': google_id, 'need_sync': False, })
def sync_data(self, model, **kw): """ This route/function is called when we want to synchronize Flectra calendar with Google Calendar. Function return a dictionary with the status : need_config_from_admin, need_auth, need_refresh, success if not calendar_event The dictionary may contains an url, to allow Flectra Client to redirect user on this URL for authorization for example """ if model == 'calendar.event': GoogleCal = GoogleCalendarService(request.env['google.service']) # Checking that admin have already configured Google API for google synchronization ! client_id = request.env['ir.config_parameter'].sudo().get_param( 'google_calendar_client_id') if not client_id or client_id == '': action_id = '' if GoogleCal._can_authorize_google(request.env.user): action_id = request.env.ref( 'base_setup.action_general_configuration').id return { "status": "need_config_from_admin", "url": '', "action": action_id } # Checking that user have already accepted Flectra to access his calendar ! if not GoogleCal.is_authorized(request.env.user): url = GoogleCal._google_authentication_url( from_url=kw.get('fromurl')) return {"status": "need_auth", "url": url} # If App authorized, and user access accepted, We launch the synchronization need_refresh = request.env.user.sudo()._sync_google_calendar( GoogleCal) return { "status": "need_refresh" if need_refresh else "no_new_event_from_google", "url": '' } return {"status": "success"}
def write(self, vals): google_service = GoogleCalendarService(self.env['google.service']) if 'google_id' in vals: self._from_google_ids.clear_cache(self) synced_fields = self._get_google_synced_fields() if 'need_sync' not in vals and vals.keys() & synced_fields: vals['need_sync'] = True result = super().write(vals) for record in self.filtered('need_sync'): if record.google_id: record._google_patch(google_service, record.google_id, record._google_values(), timeout=3) return result
def _google_patch(self, google_service: GoogleCalendarService, google_id, values, timeout=TIMEOUT): with google_calendar_token(self.env.user.sudo()) as token: if token: google_service.patch(google_id, values, token=token, timeout=timeout) self.need_sync = False
def setUp(self): super().setUp() self.google_service = GoogleCalendarService(self.env['google.service'])