From dc9b3df431c0c971b73870bcb9eaf90c07a84da8 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Mon, 10 Sep 2018 18:10:26 +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 != '155-20120301120100' : Last event should be found searching it by date range note: for 10.0 up to not including 11.0 which is solved with #26901 opw-1866151 closes #26887 --- addons/calendar/models/calendar.py | 5 ++++- .../test_calendar_recurrent_event_case2.py | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/addons/calendar/models/calendar.py b/addons/calendar/models/calendar.py index 8929eb30c3a..0653621ed96 100644 --- a/addons/calendar/models/calendar.py +++ b/addons/calendar/models/calendar.py @@ -563,7 +563,10 @@ class Meeting(models.Model): recurring_meetings = self.search([('recurrent_id', '=', self.id), '|', ('active', '=', False), ('active', '=', True)]) for meeting in recurring_meetings: - rset1._exdate.append(todate(meeting.recurrent_id_date)) + date = todate(meeting.recurrent_id_date) + if date_field == 'stop': + date = date + timedelta(hours=self.duration) + rset1._exdate.append(date) return [d.astimezone(pytz.UTC) if d.tzinfo else d for d in rset1] @api.multi diff --git a/addons/calendar/tests/test_calendar_recurrent_event_case2.py b/addons/calendar/tests/test_calendar_recurrent_event_case2.py index 892c0ffe2aa..bd6ad89e212 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"})