Skip to content
Browse files

[FIX] calendar: invitation for deleted event (recurring)

From calendar create a recursive event and add some guests. Delete one
event of the chain.

Invitations (Mail) will be created for the deleted event, and should not
be the case because the event has been deleted.

This happens because the recursive event is really just a record in the
database representing all the generated events. When the user want to
delete an event in the chain, a new event, copy of the "parent" event
has to be registered and subsequently disabled.
In the process of creating the event the mail is sent as
side effect. Note that the code to prevent this was partially there
because a context flag "dont_notify" is sent by the unlink in
Calendar.Meeting but was ignored from the mail subsystem.

  • Loading branch information...
agr-odoo committed Aug 30, 2019
1 parent c6f1f05 commit 4e0e9dac351a447ea1b8b899ac150f6d8c569bec
Showing with 62 additions and 2 deletions.
  1. +4 −2 addons/calendar/models/
  2. +58 −0 addons/calendar/tests/
@@ -1051,11 +1051,13 @@ def create_attendees(self):
meeting_attendees |= attendee
meeting_partners |= partner

if meeting_attendees:
if meeting_attendees and not self._context.get('detaching'):
to_notify = meeting_attendees.filtered(lambda a: !=

if meeting_attendees:
meeting.write({'attendee_ids': [(4, for meeting_attendee in meeting_attendees]})

if meeting_partners:

@@ -1378,7 +1380,7 @@ def detach_recurring_event(self, values=None):
# do not copy the id
if data.get('id'):
del data['id']
return meeting_origin.copy(default=data)
return meeting_origin.with_context(detaching=True).copy(default=data)

def action_detach_recurring_event(self):
@@ -7,6 +7,7 @@
from odoo import fields
from odoo.tests.common import TransactionCase
import pytz
import re

class TestCalendar(TransactionCase):
@@ -384,3 +385,60 @@ def test_event_allday_activity_timezone(self):

self.assertEqual(activity_id.date_deadline, '2018-10-16')

def test_event_creation_mail(self):
Check that mail are sent to the attendees on event creation
Check that mail are sent to the added attendees on event edit
Check that mail are NOT sent to the attendees when detaching a recurring event

def _test_one_mail_per_attendee(self, m, partners):
# check that every attendee receive a (single) mail for the event
for partner in partners:
mail = self.env['mail.mail'].search([
('recipient_ids', 'in',,
('subject', 'like',,
self.assertEqual(len(mail), 1)

partners = [
self.env['res.partner'].create({'name':'testuser0','email': u''}),
self.env['res.partner'].create({'name':'testuser1','email': u''}),
partner_ids = [(6, False, [ for p in partners]),]
now = fields.Datetime.from_string(
m = self.CalendarEvent.create({
'name': "mailTest1",
'allday': False,
'duration': 0.5,
'partner_ids': partner_ids,
'start': fields.Datetime.to_string(now + timedelta(days=10)),
'stop': fields.Datetime.to_string(now + timedelta(days=15)),

# every partner should have 1 mail sent
_test_one_mail_per_attendee(self, m, partners)

# adding more partners to the event
self.env['res.partner'].create({'name':'testuser2','email': u''}),
self.env['res.partner'].create({'name':'testuser3','email': u''}),
self.env['res.partner'].create({'name':'testuser4','email': u''}),
partner_ids = [(6, False, [ for p in partners]),]
m.write({'partner_ids': partner_ids})

# more email should be sent
_test_one_mail_per_attendee(self, m, partners)

# calculate virtualid to detach one event
virtid = str( + '-' + ''.join(re.split('[\D]', fields.Datetime.to_string(now + timedelta(days=12))))

# detaching a virtual event in the chain

# since the detach actually create an event in the backend
# we check that no mail notifications are sent to the attendees
_test_one_mail_per_attendee(self, m, partners)

0 comments on commit 4e0e9da

Please sign in to comment.
You can’t perform that action at this time.