From e9739b6580d06cc35ec07c94e23ef2c8d2967112 Mon Sep 17 00:00:00 2001 From: Adrien Widart Date: Mon, 15 Mar 2021 09:33:45 +0000 Subject: [PATCH] [FIX] google_calendar: compare with normalized address When syncing Odoo with Google Calendar, if one Odoo event has an attendee with an email address that contains some uppercases, it will lead to undesirable behavior. To reproduce the error: (Need contacts) 1. Create an event - In attendees, adds a new partner PA - The email must be valid and the local-part must contain at least one uppercase (e.g. demoUP@example.com) 2. Sync with Google 3. On Google Calendar, update the event (e.g., add a description) 4. Refresh Odoo Calendar Error: The event is updated, but the attendee has been removed. The error comes from both Google and Odoo. Google Calendar is not case sensitive: if a user creates a meeting on Google Calendar and adds an email address with uppercases, the latter will be converted with lowercases. (On step 3, on Google Calendar, we can notice that PA's email address does not contain any uppercase) On Odoo side, when syncing the event, the module checks the attendees. To do so, it uses email addresses from Odoo (with uppercases) and Google (without uppercases): https://github.com/odoo/odoo/blob/12cb76bdfe7a5affb7580485473be71cfa37658a/addons/google_calendar/models/calendar.py#L105-L114 `email` comes from Google and `attendees_by_emails` from Odoo. Therefore, it will consider the email as a new attendee and will run `find_or_create` to get the associated partner. However, this method uses the normalized email address to find the partner: https://github.com/odoo/odoo/blob/12cb76bdfe7a5affb7580485473be71cfa37658a/addons/mail/models/res_partner.py#L50-L63 Thus, `find_or_create` returns PA and adds the latter to the attendees and partners (even if PA already exists in partners and attendees). After that, the module checks if some attendees must be removed: https://github.com/odoo/odoo/blob/12cb76bdfe7a5affb7580485473be71cfa37658a/addons/google_calendar/models/calendar.py#L115-L120 Again, `odoo_attendee` comes from Odoo and `email` comes from Google. Therefore, it will remove PA from attendees and partners. This explains why: - PA has disappeared - No partner has been created for the email address without uppercase This fix suggests to normalize the Odoo email addresses each they are compared with the Google ones. OPW-2464863 closes odoo/odoo#67950 X-original-commit: 01648d37b9d5ad858d3b60dacfb724a18045f007 Signed-off-by: Nicolas Lempereur (nle) Signed-off-by: Adrien Widart --- addons/google_calendar/models/calendar.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/google_calendar/models/calendar.py b/addons/google_calendar/models/calendar.py index 17ebd7dd838..255500f7463 100644 --- a/addons/google_calendar/models/calendar.py +++ b/addons/google_calendar/models/calendar.py @@ -5,7 +5,7 @@ import pytz from dateutil.parser import parse from dateutil.relativedelta import relativedelta -from odoo import api, fields, models, _ +from odoo import api, fields, models, tools, _ class Meeting(models.Model): @@ -104,7 +104,7 @@ class Meeting(models.Model): existing_attendees = self.env['calendar.attendee'] if google_event.exists(self.env): existing_attendees = self.browse(google_event.odoo_id(self.env)).attendee_ids - attendees_by_emails = {a.email: a for a in existing_attendees} + attendees_by_emails = {tools.email_normalize(a.email): a for a in existing_attendees} for attendee in google_attendees: email = attendee.get('email') @@ -120,7 +120,7 @@ class Meeting(models.Model): partner.name = attendee.get('displayName') for odoo_attendee in attendees_by_emails.values(): # Remove old attendees - if odoo_attendee.email not in emails: + if tools.email_normalize(odoo_attendee.email) not in emails: attendee_commands += [(2, odoo_attendee.id)] partner_commands += [(3, odoo_attendee.partner_id.id)] return attendee_commands, partner_commands