[FIX] google_calendar: Sync partner with attendee

Create an event with at least one attendee.
Synchronize the event between Odoo and Google.
Add/Remove an attendee in Google.

Observed behavior
-----------------
After synchronisation, the partner is not added/removed in Odoo

Expected behavior
-----------------
The partner should be added/removed

Task 2241572
This commit is contained in:
Lucas Lefèvre
2020-04-20 10:12:33 +00:00
parent 430cfa76f5
commit e3af2ea39c
2 changed files with 52 additions and 15 deletions
+15 -14
View File
@@ -55,13 +55,15 @@ class Meeting(models.Model):
return {'active': False}
alarm_commands = self._odoo_reminders_commands(google_event.reminders.get('overrides') or default_reminders)
attendee_commands, partner_commands = self._odoo_attendee_commands(google_event)
values = {
'name': google_event.summary or _("(No title)"),
'description': google_event.description,
'location': google_event.location,
'user_id': google_event.owner(self.env).id,
'privacy': google_event.visibility or self.default_get(['privacy'])['privacy'],
'attendee_ids': self._odoo_attendee_commands(google_event),
'attendee_ids': attendee_commands,
'partner_ids': partner_commands,
'alarm_ids': alarm_commands,
'recurrency': google_event.is_recurrent()
}
@@ -83,33 +85,33 @@ class Meeting(models.Model):
@api.model
def _odoo_attendee_commands(self, google_event):
commands = []
if not google_event.attendees:
return commands
emails = [a.get('email') for a in google_event.attendees]
attendee_commands = []
partner_commands = []
google_attendees = google_event.attendees or []
emails = [a.get('email') for a in google_attendees]
existing_attendees = self.env['calendar.attendee']
if google_event.exists(self.env):
existing_attendees = self.env['calendar.attendee'].search([
('event_id', '=', google_event.odoo_id(self.env)),
('email', 'in', emails)])
existing_attendees = self.browse(google_event.odoo_id(self.env)).attendee_ids
attendees_by_emails = {a.email: a for a in existing_attendees}
for attendee in google_event.attendees:
for attendee in google_attendees:
email = attendee.get('email')
if email in attendees_by_emails:
# Update existing attendees
commands += [(1, attendees_by_emails[email].id, {'state': attendee.get('responseStatus')})]
attendee_commands += [(1, attendees_by_emails[email].id, {'state': attendee.get('responseStatus')})]
else:
# Create new attendees
partner = self.env['res.partner'].find_or_create(attendee.get('email'))
commands += [(0, 0, {'state': attendee.get('responseStatus'), 'partner_id': partner.id})]
attendee_commands += [(0, 0, {'state': attendee.get('responseStatus'), 'partner_id': partner.id})]
partner_commands += [(4, partner.id)]
if attendee.get('displayName') and not partner.name:
partner.name = attendee.get('displayName')
for odoo_attendee in attendees_by_emails.values():
# Remove old attendees
if odoo_attendee.email not in emails:
commands += [(2, odoo_attendee.id)]
return commands
attendee_commands += [(2, odoo_attendee.id)]
partner_commands += [(3, odoo_attendee.partner_id.id)]
return attendee_commands, partner_commands
@api.model
def _odoo_reminders_commands(self, reminders=()):
@@ -139,7 +141,6 @@ class Meeting(models.Model):
duration = minutes
name = _("%s - %s Minutes") % (alarm_type_label, duration)
commands += [(0, 0, {'duration': duration, 'interval': interval, 'name': name, 'alarm_type': alarm_type})]
reminders = {()}
return commands
def _google_values(self):
@@ -4,7 +4,7 @@
from addons.google_calendar.utils.google_calendar import GoogleEvent
import pytz
from datetime import datetime, date
from odoo.tests.common import SavepointCase
from odoo.tests.common import SavepointCase, new_test_user
class TestSyncGoogle2Odoo(SavepointCase):
@@ -50,6 +50,7 @@ class TestSyncGoogle2Odoo(SavepointCase):
self.assertEqual(event.stop, datetime(2020, 1, 13, 18, 55))
self.assertEqual('admin@yourcompany.example.com', event.attendee_ids.email)
self.assertEqual('Mitchell Admin', event.attendee_ids.partner_id.name)
self.assertEqual(event.partner_ids, event.attendee_ids.partner_id)
self.assertEqual('needsAction', event.attendee_ids.state)
def test_cancelled(self):
@@ -89,6 +90,41 @@ class TestSyncGoogle2Odoo(SavepointCase):
self.assertTrue(user_attendee)
self.assertEqual(user_attendee.state, 'declined')
def test_attendee_removed(self):
user = new_test_user(self.env, login='calendar-user')
google_id = 'oj44nep1ldf8a3ll02uip0c9aa'
event = self.env['calendar.event'].with_user(user).create({
'name': 'coucou',
'start': date(2020, 1, 6),
'stop': date(2020, 1, 6),
'google_id': google_id,
'user_id': False, # user is not owner
'partner_ids': [(6, 0, user.partner_id.ids)], # but user is attendee
})
gevent = GoogleEvent([{
'id': google_id,
'description': 'Small mini desc',
"updated": self.now,
'organizer': {'email': 'odoocalendarref@gmail.com', 'self': True},
'summary': 'Pricing new update',
'visibility': 'public',
'attendees': [], # <= attendee removed in Google
'reminders': {'useDefault': True},
'start': {
'dateTime': '2020-01-13T16:55:00+01:00',
'timeZone': 'Europe/Brussels'
},
'end': {
'dateTime': '2020-01-13T19:55:00+01:00',
'timeZone': 'Europe/Brussels'
},
}])
self.assertEqual(event.partner_ids, user.partner_id)
self.assertEqual(event.attendee_ids.partner_id, user.partner_id)
self.sync(gevent)
self.assertFalse(event.attendee_ids, "The attendee should have been removed")
self.assertFalse(event.partner_ids, "The partner should have been removed")
def test_recurrence(self):
recurrence_id = 'oj44nep1ldf8a3ll02uip0c9aa'
values = {