diff --git a/models/calendar_event.py b/models/calendar_event.py index 46220a1a955976b44f5b0140050cc0c03a451bd0..d566b76a0e4da819d352d5dcc4c0b893ff393501 100644 --- a/models/calendar_event.py +++ b/models/calendar_event.py @@ -83,16 +83,15 @@ class CalendarEvent(models.Model): stop = bm_event.value.main.dtend.iso8601 data.update({"allday": True, "start_date": start, "stop_date": stop}) else: - timeZone_start = timezone(bm_event.value.main.dtstart.timezone) - timeZone_stop = timezone(bm_event.value.main.dtend.timezone) + utc = timezone("UTC") start = ( parse(bm_event.value.main.dtstart.iso8601) - .astimezone(timeZone_start) + .astimezone(utc) .replace(tzinfo=None) ) stop = ( parse(bm_event.value.main.dtend.iso8601) - .astimezone(timeZone_stop) + .astimezone(utc) .replace(tzinfo=None) ) data.update({"allday": False, "start": start, "stop": stop}) @@ -143,15 +142,16 @@ class CalendarEvent(models.Model): # Event object initialization bm_event = VEventSeries() bm_event.main = VEvent() - bm_event.main.classification = ICalendarElementClassification( - PRIVACY_CONVERTER_O2B.get(event.privacy) - ) bm_event.main.dtstart = BmDateTime() bm_event.main.dtend = BmDateTime() + # Event generic information bm_event.main.summary = event.name bm_event.main.description = event.description or "" bm_event.main.location = event.location or "" + bm_event.main.classification = ICalendarElementClassification( + PRIVACY_CONVERTER_O2B.get(event.privacy) + ) # These fields are required (although not marked as such in doc / code) # Otherwise you get a NullPointerException @@ -224,12 +224,49 @@ class CalendarEvent(models.Model): ) return uid.decode() - def update_odoo_event_from_bm(self, odoo_event, bm_event): + def update_odoo_event_from_bm(self, bm_event): """ - Update an Odoo event (odoo_event) with fields from a Bluemind event (bm_event) + Update an Odoo event with fields from a Bluemind event (bm_event) """ new_odoo_fields = self._bm_to_odoo_values(bm_event) - odoo_event.write(new_odoo_fields) + self.write(new_odoo_fields) + + def create_odoo_events_in_bm(self): + """ + Create events from Odoo (odoo_events) in Bluemind + """ + # Create a list of Bluemind events to be created + bm_events = VEventChanges() + bm_events.add = [] + for odoo_event in self: + # Avoid recreating events if already linked to Bluemind event + if not odoo_event.bluemind_id: + # Create a Bluemind event object and fills it with values + # from Odoo event + event_add = VEventChangesItemAdd() + event_add.uid = self.generate_uid_bluemind() + event_add.value = self._odoo_to_bm_values(odoo_event) + # Avoids sending notification from Bluemind + # (since assumed already sent from Odoo) + event_add.sendNotification = False + # Add Bluemind event to list + bm_events.add.append(event_add) + # Set bluemind_id on Odoo event (without pushing to Bluemind) + odoo_event.write({"bluemind_id": event_add.uid}, from_bluemind=True) + # If list of Bluemind events to be created is not empty, + # create these events in Bluemind + if bm_events.add: + try: + bm_calendar = self.env.user.bluemind_auth().calendar( + self.env.user.bluemind_calendar_id + ) + bm_calendar.updates(bm_events) + except (ServerFault, Exception) as e: + # TODO: better manage exceptions + _logger.warning( + "Did not manage to push events to Bluemind, error [%s]", + exception_to_unicode(e), + ) # Take caution about attendees (only one calendar event in Odoo for all attendees, # when in Bluemind you get a different one per attendee) @@ -286,37 +323,7 @@ class CalendarEvent(models.Model): """ # Calls base create() function first odoo_events = super().create(vals_list) - # Create a list of Bluemind events to be created - bm_events = VEventChanges() - bm_events.add = [] - for odoo_event in odoo_events: - if not odoo_event.bluemind_id: - # Create a Bluemind event object and fills it with values - # from Odoo event - event_add = VEventChangesItemAdd() - event_add.uid = self.generate_uid_bluemind() - event_add.value = self._odoo_to_bm_values(odoo_event) - # Avoids sending notification from Bluemind - # (since assumed already sent from Odoo) - event_add.sendNotification = False - # Add Bluemind event to list - bm_events.add.append(event_add) - # Set bluemind_id on Odoo event (without pushing to Bluemind) - odoo_event.write({"bluemind_id": event_add.uid}, from_bluemind=True) - # If list of Bluemind events to be created is not empty, - # create these events in Bluemind - if bm_events.add: - try: - bm_calendar = self.env.user.bluemind_auth().calendar( - self.env.user.bluemind_calendar_id - ) - bm_calendar.updates(bm_events) - except (ServerFault, Exception) as e: - # TODO: better manage exceptions - _logger.warning( - "Did not manage to push events to Bluemind, error [%s]", - exception_to_unicode(e), - ) + self.create_odoo_events_in_bm() return odoo_events def unlink(self, from_bluemind=False): diff --git a/models/res_users.py b/models/res_users.py index bed8e98b97ac534b87eca086d09d333b48fa0d7b..b6cc78e434ca43bfe39d4bd96e9bbace1a440241 100644 --- a/models/res_users.py +++ b/models/res_users.py @@ -80,7 +80,7 @@ class ResUser(models.Model): # TODO : add notification that it works or not return self.bluemind_auth(force=True) - @api.depends("company_id.bluemind_domain", "bluemind_login", "bluemind_password") + @api.depends("company_id.bluemind_domain", "bluemind_login", "bluemind_password", "is_bm_connection_ok") def _compute_bluemind_user_id(self): """ This method retrieves the user id from Bluemind client object @@ -90,13 +90,16 @@ class ResUser(models.Model): user.company_id.bluemind_url and user.bluemind_login and user.bluemind_password + and user.is_bm_connection_ok ): - user.bluemind_user_id = ( - user.bluemind_auth() - .directory(user.company_id.bluemind_domain) - .getByEmail(user.bluemind_login) - .entryUid - ) + client = user.bluemind_auth() + if client: + user.bluemind_user_id = ( + client + .directory(user.company_id.bluemind_domain) + .getByEmail(user.bluemind_login) + .entryUid + ) @api.depends("bluemind_user_id") def _compute_bluemind_calendar_uid(self): @@ -162,7 +165,7 @@ class ResUser(models.Model): ) # If event exists in Odoo update it if odoo_event: - Calendar.update_odoo_event_from_bm(odoo_event, bm_event) + odoo_event.update_odoo_event_from_bm(bm_event) # Otherwise log an error else: _logger.error( @@ -178,6 +181,18 @@ class ResUser(models.Model): # Update user last_sync_version with the latest one retrieved from Bluemind self.last_sync_version = bm_last_version + # TODO : sync all Odoo events without bluemind_id + # Should we sync only events on which user_id is the current user + # Or also all events to which he was invited as participant ? + # First we would sync only the ones where he is user_id + # (because otherwise you would set bluemind_id on an event which + # does not belong to the current user, and may have already been synced + # - with different bluemind_id by the organizer (user_id)) + odoo_events_no_bm = Calendar.search( + [("user_id", "=", self.id), ("bluemind_id", "=", False)] + ) + odoo_event_no_bm.create_odoo_events_in_bm() + @api.model def _sync_all_bm_calendar(self): """