From 3d09560ffc779e169ed9488e4e07928204dd234d Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Tue, 11 Sep 2018 13:05:32 +0200 Subject: [PATCH] [FIX] calendar: keep recurring after edited one Since 76b7242 if we have a recurring event with 3 occurences: [4th 4:00-4th 5:00] [14th 4:00-14th 5:00] [24th 4:00-24th 4:00] And we detach the first one to modify it, then when getting the info of reccurring events not detached the system get: - starts: [14th 4:00] [24th 4:00] - stops: [4th 5:00] [14th 5:00] [24th 5:00] And wrongly apply the current filtering over: [14th 4:00-4th 5:00] [24th 4:00-14th 5:00] So the issue hides recurrences of event wrongly if: - they have not been detached - they don't have a duration of 0 - one or several previous events have been detached - the stop date of the nth previous event occurrence (nth equaling number of detached previous events) is not in the current filtering. With this change, the stops are also filtered based on start of occurrence + duration. Without the change, the added test fails with: False != '27-20120301120100' : Last event should be found searching it by date range note: 11.0 version of 10.0 #26887 opw-1866151 closes #26901 --- addons/calendar/models/calendar.py | 2 ++ .../test_calendar_recurrent_event_case2.py | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/addons/calendar/models/calendar.py b/addons/calendar/models/calendar.py index 1fd4bcbf1c4..f75e66c2b54 100644 --- a/addons/calendar/models/calendar.py +++ b/addons/calendar/models/calendar.py @@ -630,6 +630,8 @@ class Meeting(models.Model): recurring_date = recurring_date.replace(tzinfo=None) else: recurring_date = todate(meeting.recurrent_id_date) + if date_field == "stop": + recurring_date += timedelta(hours=self.duration) rset1.exdate(recurring_date) invalidate = True return [d.astimezone(pytz.UTC) if d.tzinfo else d for d in rset1 if d.year < MAXYEAR] diff --git a/addons/calendar/tests/test_calendar_recurrent_event_case2.py b/addons/calendar/tests/test_calendar_recurrent_event_case2.py index 456a47fd9b9..e43d7c7843c 100644 --- a/addons/calendar/tests/test_calendar_recurrent_event_case2.py +++ b/addons/calendar/tests/test_calendar_recurrent_event_case2.py @@ -85,14 +85,23 @@ class TestRecurrentEvent(common.TransactionCase): for meeting in meetings: self.assertEqual(meeting.name, 'Sprint Review for google modules', 'Name not changed for id: %s' % meeting.id) + # I detach first occurrence to check it is not modified by changing recurrent event. + min(meetings, key=lambda m: m.start).detach_recurring_event() + # I change description of my weekly meeting Review code with programmer. idval = '%d-%s' % (self.calendar_event_sprint_review.id, '20110425124700') self.CalendarEvent.browse(idval).write({'description': 'Review code of the module: sync_google_calendar.'}) - # I check whether that all the records of this recurrence has been edited. - meetings = self.CalendarEvent.search([('recurrent_id', '=', self.calendar_event_sprint_review.id)]) - for meeting in meetings: - self.assertEqual(meeting.description, 'Review code of the module: sync_google_calendar.', 'Description not changed for id: %s' % meeting.id) + # I check that detached event has not been edited. + detached_meeting = self.CalendarEvent.search([('recurrent_id', '=', self.calendar_event_sprint_review.id)]) + self.assertEqual(detached_meeting.description, False, 'Detached event description changed for id: %s' % meeting.id) + + # I verify wether I find an event by date range when subsequent to a detached one. + last_meeting = max(meetings, key=lambda m: m.start) + meetings = self.CalendarEvent.with_context({'virtual_id': True}).search([ + ('start', '<=', last_meeting.stop), ('stop', '>=', last_meeting.start) + ]) + self.assertEqual(meetings.id, last_meeting.id, 'Last event should be found searching it by date range') # I update the description of two meetings, and check that both have been updated self.calendar_event_sprint_review.write({'description': "Some description"})