From a67dc7e151bd4b19339580600d0251847d63f250 Mon Sep 17 00:00:00 2001 From: Arnaud Joset Date: Tue, 1 Feb 2022 09:28:42 +0000 Subject: [PATCH] [FIX] google_calendar: chose internal users when portal and internal users share the same email Before this commit, when two users shared the same mail, they were ordered by alphabetical order. This commit makes sure that the internal user is preferred. closes odoo/odoo#84805 X-original-commit: 992b7a00f8eb567aed730420d0d10fa476fb9dd7 Signed-off-by: Thibault Francois Signed-off-by: Arnaud Joset --- addons/google_calendar/models/calendar.py | 2 +- .../models/calendar_recurrence_rule.py | 2 +- addons/google_calendar/models/google_sync.py | 13 ++++++++- .../tests/test_sync_google2odoo.py | 29 +++++++++++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/addons/google_calendar/models/calendar.py b/addons/google_calendar/models/calendar.py index 12cb2e476ba..ffafbd77b84 100644 --- a/addons/google_calendar/models/calendar.py +++ b/addons/google_calendar/models/calendar.py @@ -132,7 +132,7 @@ class Meeting(models.Model): if google_event.exists(self.env): existing_attendees = self.browse(google_event.odoo_id(self.env)).attendee_ids attendees_by_emails = {tools.email_normalize(a.email): a for a in existing_attendees} - partners = self.env['mail.thread']._mail_find_partner_from_emails(emails, records=self, force_create=True) + partners = self._get_sync_partner(emails) for attendee in zip(emails, partners, google_attendees): email = attendee[0] if email in attendees_by_emails: diff --git a/addons/google_calendar/models/calendar_recurrence_rule.py b/addons/google_calendar/models/calendar_recurrence_rule.py index db179f6ffe1..4c195247698 100644 --- a/addons/google_calendar/models/calendar_recurrence_rule.py +++ b/addons/google_calendar/models/calendar_recurrence_rule.py @@ -92,7 +92,7 @@ class RecurrenceRule(models.Model): # We update the attendee status for all events in the recurrence google_attendees = gevent.attendees or [] emails = [a.get('email') for a in google_attendees] - partners = self.env['mail.thread']._mail_find_partner_from_emails(emails, records=self, force_create=True) + partners = self._get_sync_partner(emails) existing_attendees = self.calendar_event_ids.attendee_ids for attendee in zip(emails, partners, google_attendees): email = attendee[0] diff --git a/addons/google_calendar/models/google_sync.py b/addons/google_calendar/models/google_sync.py index 89942e057d4..db161b60ac6 100644 --- a/addons/google_calendar/models/google_sync.py +++ b/addons/google_calendar/models/google_sync.py @@ -9,7 +9,7 @@ import pytz from dateutil.parser import parse from odoo import api, fields, models, registry, _ -from odoo.tools import ormcache_context +from odoo.tools import ormcache_context, email_normalize from odoo.exceptions import UserError from odoo.osv import expression @@ -284,6 +284,17 @@ class GoogleSync(models.AbstractModel): def _create_from_google(self, gevents, vals_list): return self.create(vals_list) + @api.model + def _get_sync_partner(self, emails): + normalized_emails = [email_normalize(contact) for contact in emails if email_normalize(contact)] + user_partners = self.env['mail.thread']._mail_search_on_user(normalized_emails, extra_domain=[('share', '=', False)]) + partners = [user_partner for user_partner in user_partners] + remaining = [email for email in normalized_emails if + email not in [partner.email_normalized for partner in partners]] + if remaining: + partners += self.env['mail.thread']._mail_find_partner_from_emails(remaining, records=self, force_create=True) + return partners + @api.model def _odoo_values(self, google_event: GoogleEvent, default_reminders=()): """Implements this method to return a dict of Odoo values corresponding diff --git a/addons/google_calendar/tests/test_sync_google2odoo.py b/addons/google_calendar/tests/test_sync_google2odoo.py index 5e38fed597d..f7ce4c9f1ef 100644 --- a/addons/google_calendar/tests/test_sync_google2odoo.py +++ b/addons/google_calendar/tests/test_sync_google2odoo.py @@ -1047,3 +1047,32 @@ class TestSyncGoogle2Odoo(TestSyncGoogle): self.assertEqual(mails, ['odoobot@example.com']) self.assertGoogleAPINotCalled() + + def test_several_users_have_the_same_mail(self): + # We want to chose the internal user + user1 = new_test_user(self.env, login='test@example.com', groups='base.group_portal') + user2 = new_test_user(self.env, login='calendar-user2') + user2.partner_id.email = 'test@example.com' + user1.partner_id.name = "A First in alphabet" + user2.partner_id.name = "B Second in alphabet" + values = { + 'id': "abcd", + 'description': 'coucou', + "updated": self.now, + 'organizer': {'email': 'odoobot@example.com', 'self': True}, + 'summary': False, + 'visibility': 'public', + 'attendees': [{'email': 'test@example.com', 'responseStatus': 'accepted'}, {'email': 'test2@example.com', 'responseStatus': 'accepted'}], + 'reminders': {'useDefault': True}, + 'start': { + 'dateTime': '2020-01-13T16:00:00+01:00', + 'timeZone': 'Europe/Brussels' + }, + 'end': { + 'dateTime': '2020-01-13T20:00:00+01:00', + 'timeZone': 'Europe/Brussels' + }, + } + event = self.env['calendar.event']._sync_google2odoo(GoogleEvent([values])) + new_partner = self.env['res.partner'].search([('email', '=', 'test2@example.com')]) + self.assertEqual(event.partner_ids.ids, [user2.partner_id.id, new_partner.id], "The internal user should be chosen")