예제 #1
0
 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
예제 #2
0
    def _sync_google_calendar(self, calendar_service: GoogleCalendarService):
        self.ensure_one()
        if self.google_synchronization_stopped:
            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_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 -> Odoo
        recurrences = events.filter(lambda e: e.is_recurrence())
        synced_recurrences = self.env['calendar.recurrence']._sync_google2odoo(
            recurrences)
        synced_events = self.env['calendar.event']._sync_google2odoo(
            events - recurrences, default_reminders=default_reminders)

        # Odoo -> Google
        recurrences = self.env['calendar.recurrence']._get_records_to_sync(
            full_sync=full_sync)
        recurrences -= synced_recurrences
        recurrences._sync_odoo2google(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_odoo2google(calendar_service)

        return bool(events | synced_events) or bool(recurrences
                                                    | synced_recurrences)
예제 #3
0
    def reset_account(self):
        google = GoogleCalendarService(self.env['google.service'])

        events = self.env['calendar.event'].search([
            ('user_id', '=', self.user_id.id),
            ('google_id', '!=', False)])
        if self.delete_policy in ('delete_google', 'delete_both'):
            with google_calendar_token(self.user_id) as token:
                for event in events:
                    google.delete(event.google_id, token=token)

        if self.delete_policy in ('delete_odoo', 'delete_both'):
            events.google_id = False
            events.unlink()

        if self.sync_policy == 'all':
            events.write({
                'google_id': False,
                'need_sync': True,
            })

        self.user_id.google_cal_account_id._set_auth_tokens(False, False, 0)
        self.user_id.write({
            'google_calendar_sync_token': False,
            'google_calendar_cal_id': False,
        })
예제 #4
0
 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)
             self.need_sync = False
예제 #5
0
 def _google_patch(self, google_service: GoogleCalendarService, google_id, values, timeout=TIMEOUT):
     with google_calendar_token(self.env.user.sudo()) as token:
         if token:
             try:
                 google_service.patch(google_id, values, token=token, timeout=timeout)
             except HTTPError as e:
                 if e.response.status_code in (400, 403):
                     self._google_error_handling(e)
             self.need_sync = False
예제 #6
0
 def _sync_event(self):
     # For weird reasons, we can't sync status when we are not the responsible
     # We can't adapt google_value to only keep ['id', 'summary', 'attendees', 'start', 'end', 'reminders']
     # and send that. We get a Forbidden for non-organizer error even if we only send start, end that are mandatory !
     all_events = self.mapped('event_id').filtered(lambda e: e.google_id)
     other_events = all_events.filtered(lambda e: e.user_id and e.user_id.id != self.env.user.id)
     for user in other_events.mapped('user_id'):
         service = GoogleCalendarService(self.env['google.service'].with_user(user))
         other_events.filtered(lambda ev: ev.user_id.id == user.id).with_user(user)._sync_odoo2google(service)
     google_service = GoogleCalendarService(self.env['google.service'])
     (all_events - other_events)._sync_odoo2google(google_service)
예제 #7
0
파일: res_users.py 프로젝트: GSLabIt/odoo
    def _sync_google_calendar(self, calendar_service: GoogleCalendarService):
        self.ensure_one()
        if self.google_synchronization_stopped:
            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_cal_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_cal_account_id.calendar_sync_token = next_sync_token

        # Google -> Odoo
        events.clear_type_ambiguity(self.env)
        recurrences = events.filter(lambda e: e.is_recurrence())
        synced_recurrences = self.env['calendar.recurrence']._sync_google2odoo(
            recurrences)
        synced_events = self.env['calendar.event']._sync_google2odoo(
            events - recurrences, default_reminders=default_reminders)

        # Odoo -> Google
        recurrences = self.env['calendar.recurrence']._get_records_to_sync(
            full_sync=full_sync)
        recurrences -= synced_recurrences
        recurrences._sync_odoo2google(calendar_service)
        synced_events |= recurrences.calendar_event_ids - recurrences._get_outliers(
        )
        synced_events |= synced_recurrences.calendar_event_ids - synced_recurrences._get_outliers(
        )
        events = self.env['calendar.event']._get_records_to_sync(
            full_sync=full_sync)
        (events - synced_events)._sync_odoo2google(calendar_service)

        return bool(events | synced_events) or bool(recurrences
                                                    | synced_recurrences)
예제 #8
0
 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_odoo2google(google_service)
     return res
예제 #9
0
 def synchroniser_google_user(self, event, user):
     if user:
         with google_calendar_token(user.sudo()) as token:
             if token:
                 _logger.warning("## token = %s" % (token))
                 headers = {
                     'Content-type': 'application/json',
                     'Authorization': 'Bearer %s' % token
                 }
                 params = {'access_token': token}
                 values = event._google_values()
                 _logger.warning("## values = %s" % (values))
                 google_service = GoogleCalendarService(
                     self.with_user(user).env['google.service'])
                 event_id = values.get('id')
                 _logger.warning(
                     "## synchroniser_google_action event_id = %s" %
                     (event_id))
                 try:
                     _logger.warning("## _google_patch event = %s" %
                                     (event))
                     event.with_user(user)._google_patch(google_service,
                                                         event_id,
                                                         values,
                                                         timeout=3)
                 except:
                     _logger.exception(
                         "## _google_patch  ERROR event = %s" % (event))
예제 #10
0
    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
예제 #11
0
    def sync_data(self, model, **kw):
        """ This route/function is called when we want to synchronize Odoo
            calendar with Google Calendar.
            Function return a dictionary with the status :  need_config_from_admin, need_auth,
            need_refresh, sync_stopped, success if not calendar_event
            The dictionary may contains an url, to allow Odoo 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 Odoo 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)

            # If synchronization has been stopped
            if not need_refresh and request.env.user.google_synchronization_stopped:
                return {"status": "sync_stopped", "url": ''}
            return {
                "status":
                "need_refresh" if need_refresh else "no_new_event_from_google",
                "url": ''
            }

        return {"status": "success"}
예제 #12
0
 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,
             })
예제 #13
0
 def _sync_all_google_calendar(self):
     """ Cron job """
     users = self.env['res.users'].search([('google_calendar_rtoken', '!=', False), ('google_synchronization_stopped', '=', 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))
예제 #14
0
    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
예제 #15
0
    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
예제 #16
0
 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:
             try:
                 google_id = google_service.insert(values, token=token, timeout=timeout)
                 # Everything went smoothly
                 self.with_context(dont_notify=True).write({
                     'google_id': google_id,
                     'need_sync': False,
                 })
             except HTTPError as e:
                 if e.response.status_code in (400, 403):
                     self._google_error_handling(e)
                     self.need_sync = False
예제 #17
0
 def setUp(self):
     super().setUp()
     self.google_service = GoogleCalendarService(self.env['google.service'])
     # Make sure this test will work for the next 30 years
     self.env['ir.config_parameter'].set_param(
         'google_calendar.sync.range_days', 10000)
예제 #18
0
 def setUp(self):
     super().setUp()
     self.google_service = GoogleCalendarService(self.env['google.service'])
예제 #19
0
 def _sync_event(self):
     google_service = GoogleCalendarService(self.env['google.service'])
     self.event_id.filtered(lambda e: e.google_id)._sync_odoo2google(
         google_service)