[FIX] google_calendar: not sending emails to existing event attendees
Before this commit: syncing with google led to sending emails to attendees of existing future events on Odoo. Steps to reproduce the first issue: Install 'google_calendar' module Integrate with Google Calendar in setting Add an event to the Odoo calendar for future date Add one external attendee to the event Sync with Google Invitation emails would be sent to the attendees of the events. Solution It's possible to not send emails to the attendees in api calls. So the solution is to not send emails to the attendees for the syncing time. opw-2819046 closes odoo/odoo#102870 X-original-commit: 5a56e37a5f54662b1f3593930738e51c010abab7 Signed-off-by: Arnaud Joset <arj@odoo.com> Signed-off-by: Pedram Bi Ria (pebr) <pebr@odoo.com>
This commit is contained in:
@@ -351,6 +351,7 @@ class Meeting(models.Model):
|
||||
recurrence_fields = self._get_recurrent_fields()
|
||||
false_values = {field: False for field in recurrence_fields} # computes need to set a value
|
||||
defaults = self.env['calendar.recurrence'].default_get(recurrence_fields)
|
||||
default_rrule_values = self.recurrence_id.default_get(recurrence_fields)
|
||||
for event in self:
|
||||
if event.recurrency:
|
||||
event.update(defaults) # default recurrence values are needed to correctly compute the recurrence params
|
||||
@@ -360,6 +361,7 @@ class Meeting(models.Model):
|
||||
for field in recurrence_fields
|
||||
if event.recurrence_id[field]
|
||||
}
|
||||
rrule_values = rrule_values or default_rrule_values
|
||||
event.update({**false_values, **defaults, **event_values, **rrule_values})
|
||||
else:
|
||||
event.update(false_values)
|
||||
|
||||
@@ -220,6 +220,12 @@ class TestCalendar(SavepointCaseWithUserDemo):
|
||||
f.start = '2022-07-07 01:00:00' # This is in UTC. In NY, it corresponds to the 6th of july at 9pm.
|
||||
f.recurrency = True
|
||||
self.assertEqual(f.weekday, 'WED')
|
||||
self.assertEqual(f.event_tz, 'US/Eastern', "The value should correspond to the user tz")
|
||||
self.assertEqual(f.count, 1, "The default value should be displayed")
|
||||
self.assertEqual(f.interval, 1, "The default value should be displayed")
|
||||
self.assertEqual(f.month_by, "date", "The default value should be displayed")
|
||||
self.assertEqual(f.end_type, "count", "The default value should be displayed")
|
||||
self.assertEqual(f.rrule_type, "weekly", "The default value should be displayed")
|
||||
|
||||
def test_event_activity_timezone(self):
|
||||
activty_type = self.env['mail.activity.type'].create({
|
||||
|
||||
@@ -247,6 +247,7 @@ class GoogleSync(models.AbstractModel):
|
||||
if token:
|
||||
try:
|
||||
send_updates = self._context.get('send_updates', True)
|
||||
google_service.google_service = google_service.google_service.with_context(send_updates=send_updates)
|
||||
google_id = google_service.insert(values, token=token, timeout=timeout)
|
||||
# Everything went smoothly
|
||||
self.with_context(dont_notify=True).write({
|
||||
|
||||
@@ -63,6 +63,7 @@ class User(models.Model):
|
||||
self.google_calendar_account_id.calendar_sync_token = next_sync_token
|
||||
|
||||
# Google -> Odoo
|
||||
send_updates = not full_sync
|
||||
events.clear_type_ambiguity(self.env)
|
||||
recurrences = events.filter(lambda e: e.is_recurrence())
|
||||
synced_recurrences = self.env['calendar.recurrence']._sync_google2odoo(recurrences)
|
||||
@@ -71,11 +72,11 @@ class User(models.Model):
|
||||
# Odoo -> Google
|
||||
recurrences = self.env['calendar.recurrence']._get_records_to_sync(full_sync=full_sync)
|
||||
recurrences -= synced_recurrences
|
||||
recurrences._sync_odoo2google(calendar_service)
|
||||
recurrences.with_context(send_updates=send_updates)._sync_odoo2google(calendar_service)
|
||||
synced_events |= recurrences.calendar_event_ids - recurrences._get_outliers()
|
||||
synced_events |= synced_recurrences.calendar_event_ids - synced_recurrences._get_outliers()
|
||||
events = self.env['calendar.event']._get_records_to_sync(full_sync=full_sync)
|
||||
(events - synced_events)._sync_odoo2google(calendar_service)
|
||||
(events - synced_events).with_context(send_updates=send_updates)._sync_odoo2google(calendar_service)
|
||||
|
||||
return bool(events | synced_events) or bool(recurrences | synced_recurrences)
|
||||
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.addons.google_calendar.utils.google_calendar import GoogleCalendarService
|
||||
from odoo.addons.google_account.models.google_service import GoogleService
|
||||
from odoo.addons.google_calendar.models.res_users import User
|
||||
from odoo.addons.google_calendar.models.google_sync import GoogleSync
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
def patch_api(func):
|
||||
@patch.object(GoogleSync, '_google_insert', MagicMock(spec=GoogleSync._google_insert))
|
||||
@@ -17,7 +18,7 @@ def patch_api(func):
|
||||
return patched
|
||||
|
||||
@patch.object(User, '_get_google_calendar_token', lambda user: 'dummy-token')
|
||||
class TestSyncGoogle(TransactionCase):
|
||||
class TestSyncGoogle(HttpCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -57,3 +58,19 @@ class TestSyncGoogle(TransactionCase):
|
||||
self.assertGoogleEventNotPatched()
|
||||
self.assertGoogleEventNotInserted()
|
||||
self.assertGoogleEventNotDeleted()
|
||||
|
||||
def assertGoogleEventSendUpdates(self, expected_value):
|
||||
GoogleService._do_request.assert_called_once()
|
||||
args, _ = GoogleService._do_request.call_args
|
||||
val = "?sendUpdates=%s" % expected_value
|
||||
self.assertTrue(val in args[0], "The URL should contain %s" % val)
|
||||
|
||||
def call_post_commit_hooks(self):
|
||||
"""
|
||||
manually calls postcommit hooks defined with the decorator @after_commit
|
||||
"""
|
||||
|
||||
funcs = self.env.cr.postcommit._funcs.copy()
|
||||
while funcs:
|
||||
func = funcs.popleft()
|
||||
func()
|
||||
|
||||
@@ -6,6 +6,7 @@ from dateutil.relativedelta import relativedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
from odoo.addons.google_calendar.utils.google_calendar import GoogleCalendarService
|
||||
from odoo.addons.google_account.models.google_service import GoogleService
|
||||
from odoo.addons.google_calendar.models.res_users import User
|
||||
from odoo.addons.google_calendar.tests.test_sync_common import TestSyncGoogle, patch_api
|
||||
from odoo.tests.common import users, warmup
|
||||
@@ -589,3 +590,32 @@ class TestSyncOdoo2Google(TestSyncGoogle):
|
||||
'reminders': {'overrides': [], 'useDefault': False},
|
||||
'visibility': 'public',
|
||||
}, timeout=3)
|
||||
|
||||
@patch.object(GoogleService, '_do_request')
|
||||
def test_send_update_do_request(self, mock_do_request):
|
||||
self.env.cr.postcommit.clear()
|
||||
event = self.env['calendar.event'].create({
|
||||
'name': "Event",
|
||||
'allday': True,
|
||||
'start': datetime(2020, 1, 15),
|
||||
'stop': datetime(2020, 1, 15),
|
||||
'need_sync': False,
|
||||
})
|
||||
|
||||
event.with_context(send_updates=True)._sync_odoo2google(self.google_service)
|
||||
self.call_post_commit_hooks()
|
||||
self.assertGoogleEventSendUpdates('all')
|
||||
|
||||
@patch.object(GoogleService, '_do_request')
|
||||
def test_not_send_update_do_request(self, mock_do_request):
|
||||
event = self.env['calendar.event'].create({
|
||||
'name': "Event",
|
||||
'allday': True,
|
||||
'start': datetime(2020, 1, 15),
|
||||
'stop': datetime(2020, 1, 15),
|
||||
'need_sync': False,
|
||||
})
|
||||
|
||||
event.with_context(send_updates=False)._sync_odoo2google(self.google_service)
|
||||
self.call_post_commit_hooks()
|
||||
self.assertGoogleEventSendUpdates('none')
|
||||
|
||||
@@ -66,7 +66,8 @@ class GoogleCalendarService():
|
||||
|
||||
@requires_auth_token
|
||||
def insert(self, values, token=None, timeout=TIMEOUT):
|
||||
url = "/calendar/v3/calendars/primary/events?sendUpdates=all"
|
||||
send_updates = self.google_service._context.get('send_updates', True)
|
||||
url = "/calendar/v3/calendars/primary/events?sendUpdates=%s" % ("all" if send_updates else "none")
|
||||
headers = {'Content-type': 'application/json', 'Authorization': 'Bearer %s' % token}
|
||||
if not values.get('id'):
|
||||
values['id'] = uuid4().hex
|
||||
|
||||
Reference in New Issue
Block a user