caldav_sync: no longer create past events in Odoo when synchronizing from CalDAV server
This commit is contained in:
parent
c3af7223de
commit
2e15f18285
3 changed files with 33 additions and 7 deletions
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
{
|
||||
"name": "CalDAV Synchronization",
|
||||
"version": "18.0.0.6.3",
|
||||
"version": "18.0.0.7.0",
|
||||
"license": "LGPL-3",
|
||||
"category": "Productivity",
|
||||
"summary": "Synchronize Odoo Calendar Events with CalDAV Servers",
|
||||
|
|
|
|||
|
|
@ -584,11 +584,11 @@ class CalendarEvent(models.Model):
|
|||
|
||||
@api.model
|
||||
def _sync_event_from_ical(
|
||||
self, ical_event: icalendar.cal.Event, user: User
|
||||
self, ical_event: icalendar.cal.Event, user: User
|
||||
) -> CalendarEvent:
|
||||
"""Given an iCalendar event, compare the event with any existing
|
||||
Odoo event that it matches and synchronize the changes. If no event
|
||||
exists, create one.
|
||||
exists, create one iff the event is in the future.
|
||||
|
||||
:param ical_event: The iCalendar event to synchronize with Odoo.
|
||||
:param user: The res.user record for whom to synchronize the event.
|
||||
|
|
@ -609,12 +609,15 @@ class CalendarEvent(models.Model):
|
|||
existing_instance = self._get_existing_instance(uid, recurrence_id)
|
||||
outdated = self._get_outdated(component, existing_instance, synced_events)
|
||||
owned = (
|
||||
existing_instance and existing_instance.partner_id == user.partner_id
|
||||
existing_instance and existing_instance.partner_id == user.partner_id
|
||||
)
|
||||
# Pass for_creation=True only when creating a new event
|
||||
values = self._get_values_from_ical_component(component, user, for_creation=not existing_instance)
|
||||
recurrency_vals = self._get_recurrency_values_from_ical_event(component)
|
||||
if not existing_instance:
|
||||
# If the event is in the past, we just ignore it.
|
||||
if values.get("stop") < datetime.now(tz=None):
|
||||
continue
|
||||
# If we're creating an instance and it doesn't follow the recurrence,
|
||||
# just scrap the recurrency vals, they're not useful
|
||||
if not recurrency_vals.get("follow_recurrence"):
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ def _get_ics_path(filename):
|
|||
|
||||
|
||||
@contextmanager
|
||||
def _patch_caldav_with_events_from_ics(ics_paths, user, last_modified=None):
|
||||
def _patch_caldav_with_events_from_ics(ics_paths, user, last_modified=None, futurize=True):
|
||||
with (
|
||||
patch("caldav.DAVClient") as MockDAVClient,
|
||||
patch("caldav.Calendar") as MockCalendar,
|
||||
|
|
@ -46,8 +46,8 @@ def _patch_caldav_with_events_from_ics(ics_paths, user, last_modified=None):
|
|||
# Get or create the mock calendar for this user
|
||||
mock_calendar = calendar_side_effect(user.caldav_calendar_url)
|
||||
|
||||
def event_by_uid_side_effect(self, uid):
|
||||
for event in self.events():
|
||||
def event_by_uid_side_effect(uid):
|
||||
for event in mock_calendar.events():
|
||||
if str(event.icalendar_component.get("uid")) == uid:
|
||||
return event
|
||||
return DEFAULT
|
||||
|
|
@ -66,6 +66,18 @@ def _patch_caldav_with_events_from_ics(ics_paths, user, last_modified=None):
|
|||
if subcomponent.name == "VEVENT":
|
||||
subcomponent["last-modified"] = icalendar.vDate(last_modified)
|
||||
subcomponent["dtstamp"] = icalendar.vDate(last_modified)
|
||||
if futurize:
|
||||
for event in ical_events:
|
||||
for subcomponent in event.subcomponents:
|
||||
if subcomponent.name == "VEVENT":
|
||||
start = subcomponent.get("dtstart") and subcomponent.decoded("dtstart")
|
||||
end = subcomponent.get("dtend") and subcomponent.decoded("dtend")
|
||||
if isinstance(start, datetime) and isinstance(end, datetime):
|
||||
duration = end - start
|
||||
else:
|
||||
duration = timedelta(hours=1)
|
||||
subcomponent["dtstart"] = icalendar.vDDDTypes(datetime.now())
|
||||
subcomponent["dtend"] = icalendar.vDDDTypes(datetime.now() + duration)
|
||||
|
||||
base_events = [event for event in ical_events if not event.get("recurrence-id")]
|
||||
for base_event in base_events:
|
||||
|
|
@ -123,6 +135,16 @@ class TestCalendarEvent(TransactionCase, CaldavTestCommon):
|
|||
new_events = events_after_sync - current_events
|
||||
self.assertEqual(len(new_events), 1)
|
||||
|
||||
def test_basic_past_event_from_server_no_create(self):
|
||||
user = self.user_1
|
||||
ics_path = _get_ics_path("basic.ics")
|
||||
with _patch_caldav_with_events_from_ics(ics_path, user, futurize=False):
|
||||
current_events = self.env["calendar.event"].search([])
|
||||
self.env["calendar.event"].poll_caldav_server()
|
||||
events_after_sync = self.env["calendar.event"].search([])
|
||||
new_events = events_after_sync - current_events
|
||||
self.assertEqual(len(new_events), 0)
|
||||
|
||||
def test_basic_event_from_server_update(self):
|
||||
user = self.user_1
|
||||
ics_path = _get_ics_path("basic.ics")
|
||||
|
|
@ -239,6 +261,7 @@ class TestCalendarEvent(TransactionCase, CaldavTestCommon):
|
|||
self.assertIn(user2.partner_id, event.partner_ids)
|
||||
self.assertIn(user3.partner_id, event.partner_ids)
|
||||
|
||||
|
||||
def test_multiple_user_attendees_event_from_server_update(self):
|
||||
"""Test event has (as in above test):
|
||||
Organizer: user1 (test1@example.com)
|
||||
|
|
|
|||
Loading…
Reference in a new issue