diff --git a/README.rst b/README.rst index 81bb454db6373d8c4c39c60390a45db0f4447bf5..97cb3163eca1a0d679bdd40868ecb66d7e544da0 100644 --- a/README.rst +++ b/README.rst @@ -22,10 +22,30 @@ At user lever, you need to define : - login user (e.g. michel@example.org) - login password or API key -Exemple -======= - - +Limitations +=========== +Currently, from all the fields in Bluemind event +- the following are filled with default value : + - priority = 5 + - status = Confirmed + - sequence = 0 + - draft = False + - transparency = Opaque + +- the following are not filled (and therefore removed from Bluemind when updated from Odoo): + - alarm + - attendees + - categories + - exdate + - rdate + - conference + - attachments + + +Exceptions on recurrencies are not managed, nor are attendees for now. +In order to avoid having multiple events in Odoo for the same event, it is only created if : +- user in Odoo = Organizer from Bluemind +- or Organizer from Bluemind is not part of Odoo users (and in this case, the first user to create the event is set as reponsible in Odoo) Credits ======= diff --git a/models/calendar_event.py b/models/calendar_event.py index 65e21aea197c3708e0d25a771a7a113c5fdd2e45..347537acd2ba337a19f85e155b919cd30fa33e13 100644 --- a/models/calendar_event.py +++ b/models/calendar_event.py @@ -12,11 +12,15 @@ from netbluemind.calendar.api.VEventChanges import VEventChanges from netbluemind.calendar.api.VEventChangesItemAdd import VEventChangesItemAdd from netbluemind.calendar.api.VEventChangesItemModify import VEventChangesItemModify from netbluemind.calendar.api.VEventSeries import VEventSeries +from netbluemind.calendar.api.VEventTransparency import VEventTransparency from netbluemind.core.api.date.BmDateTime import BmDateTime from netbluemind.core.api.date.BmDateTimePrecision import BmDateTimePrecision from netbluemind.icalendar.api.ICalendarElementClassification import ( ICalendarElementClassification, ) +from netbluemind.icalendar.api.ICalendarElementOrganizer import ( + ICalendarElementOrganizer, +) from netbluemind.icalendar.api.ICalendarElementRRule import ICalendarElementRRule from netbluemind.icalendar.api.ICalendarElementRRuleFrequency import ( ICalendarElementRRuleFrequency, @@ -24,6 +28,7 @@ from netbluemind.icalendar.api.ICalendarElementRRuleFrequency import ( from netbluemind.icalendar.api.ICalendarElementRRuleWeekDay import ( ICalendarElementRRuleWeekDay, ) +from netbluemind.icalendar.api.ICalendarElementStatus import ICalendarElementStatus from netbluemind.python.client import ServerFault from pytz import timezone @@ -44,7 +49,7 @@ PRIVACY_CONVERTER_O2B = { } -# TODO: manage attendee_ids, organizer, alarm_ids, priority, status, categories, attachments ? +# TODO: manage attendee_ids, alarm_ids, categories, attachments ? # TODO: check if recurrency properly working without exceptions # TODO: manage exceptions in recurrencies class CalendarEvent(models.Model): @@ -53,10 +58,12 @@ class CalendarEvent(models.Model): """ This inheriting class adds 1 field to calendar.event table : * bluemind_id = Unique identifier of event in Bluemind + * url = URL from event in Bluemind It also adds a number of methods to transform events between Bluemind and Odoo formats """ bluemind_id = fields.Char("Bluemind Event ID") + url = fields.Char("URL") def _bm_to_odoo_values(self, bm_event): """ @@ -73,8 +80,7 @@ class CalendarEvent(models.Model): ), "location": bm_event.value.main.location, "description": bm_event.value.main.description, - "user_id": self.env.user.id, - "create_uid": self.env.user.id, + "url": bm_event.value.main.url, } # Dates handling, with timezones @@ -152,6 +158,22 @@ class CalendarEvent(models.Model): bm_event.main.classification = ICalendarElementClassification( PRIVACY_CONVERTER_O2B.get(event.privacy) ) + bm_event.main.status = ICalendarElementStatus("Confirmed") + bm_event.main.organizer = ICalendarElementOrganizer() + bm_event.main.organizer.commonName = event.user_id.partner_id.name + bm_event.main.organizer.mailto = event.user_id.partner_id.mail + if event.user_id.bluemind_user_id: + bm_event.main.organizer.dir = ( + "bm://" + + event.user_id.company_id.bluemind_domain + + "/users/" + + event.user_id.bluemind_user_id + ) + bm_event.main.url = event.url or "" + bm_event.main.priority = 5 + bm_event.main.sequence = 0 + bm_event.main.draft = False + bm_event.main.transparency = VEventTransparency("Opaque") # These fields are required (although not marked as such in doc / code) # Otherwise you get a NullPointerException diff --git a/models/res_users.py b/models/res_users.py index 681d5f208c9115ed61095d7c43fe96dc68862669..e0860b1fd6d741a2e735502a74ee9c1e0ec9788f 100644 --- a/models/res_users.py +++ b/models/res_users.py @@ -130,6 +130,14 @@ class ResUser(models.Model): is recreated in Odoo with organizer = user """ self.ensure_one() + # Retrieve emails from all internal & active Odoo users + odoo_users_emails = ( + self.sudo() + .env["res.users"] + .search([("share", "=", False), ("active", "=", True)]) + .mapped("partner_id.email") + ) + # TODO: add checks and error handling # Retrieve all events modified since last sync (followed by self.bluemind_id_version) bm_calendar = self.bluemind_auth().calendar(self.bluemind_calendar_id) @@ -141,12 +149,10 @@ class ResUser(models.Model): bm_deleted_uids = bm_changeset.deleted bm_last_version = bm_changeset.version - # Retrieve all events from Odoo organized by the current user - # and with a bluemind_id (= already synced at least once with Bluemind) + # Retrieve all events from Odoo with a bluemind_id + # (= already synced at least once with Bluemind) Calendar = self.env["calendar.event"] - odoo_events_bm_linked = Calendar.search( - [("user_id", "=", self.id), ("bluemind_id", "!=", False)] - ) + odoo_events_bm_linked = Calendar.search([("bluemind_id", "!=", False)]) odoo_events_bm_uids = odoo_events_bm_linked.mapped("bluemind_id") # Calendar entries created on Bluemind side, not already in Odoo @@ -159,8 +165,15 @@ class ResUser(models.Model): bm_events_to_create = bm_calendar.multipleGet(bm_events_to_create_uids) # Create corresponding events in Odoo for bm_event in bm_events_to_create: - events_to_create.append(Calendar._bm_to_odoo_values(bm_event)) - Calendar.create(events_to_create) + # Only if Organizer is the same as Odoo user or if is not linked to + # any active Odoo internal user + if ( + bm_event.value.main.organizer.mailto == self.partner_id.email + or bm_event.value.main.organizer.mailto not in odoo_users_emails + ): + events_to_create.append(Calendar._bm_to_odoo_values(bm_event)) + if events_to_create: + Calendar.create(events_to_create) # Calendar entries that have been updated on Bluemind # Retrieve full events from Bluemind @@ -170,18 +183,20 @@ class ResUser(models.Model): odoo_event = odoo_events_bm_linked.filtered( [("bluemind_id", "=", bm_event.uid)] ) - # If event exists in Odoo update it + # If related event exists in Odoo and belongs to the user, update it if odoo_event: - odoo_event.update_odoo_event_from_bm(bm_event) - # Otherwise log an error + if odoo_event.user_id == self: + odoo_event.update_odoo_event_from_bm(bm_event) + # If event does not exist in Odoo log an info else: - _logger.error( - "Event %s updated in Bluemind did not exist in Odoo", bm_event.uid + _logger.info( + "Event %s updated in Bluemind does not exist in Odoo", bm_event.uid ) # Calendar entries that have been deleted on Bluemind to be deleted on Odoo + # (only if belongs to user) odoo_events_to_delete = odoo_events_bm_linked.filtered( - [("bluemind_id", "in", bm_deleted_uids)] + [("bluemind_id", "in", bm_deleted_uids), ("user_id", "=", self.id)] ) odoo_events_to_delete.unlink(from_bluemind=True)