caldav_sync: further fixes for organizer issues
This commit is contained in:
parent
3ebadcb969
commit
4b19f8262e
2 changed files with 44 additions and 14 deletions
|
|
@ -611,7 +611,8 @@ class CalendarEvent(models.Model):
|
||||||
owned = (
|
owned = (
|
||||||
existing_instance and existing_instance.partner_id == user.partner_id
|
existing_instance and existing_instance.partner_id == user.partner_id
|
||||||
)
|
)
|
||||||
values = self._get_values_from_ical_component(component, user)
|
# 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)
|
recurrency_vals = self._get_recurrency_values_from_ical_event(component)
|
||||||
if not existing_instance:
|
if not existing_instance:
|
||||||
# If we're creating an instance and it doesn't follow the recurrence,
|
# If we're creating an instance and it doesn't follow the recurrence,
|
||||||
|
|
@ -647,7 +648,7 @@ class CalendarEvent(models.Model):
|
||||||
return synced_events
|
return synced_events
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _get_existing_instance(self, uid, recurrence_id: datetime) -> CalendarEvent:
|
def _get_existing_instance(self, uid, recurrence_id: Optional[datetime]) -> CalendarEvent:
|
||||||
"""Find the Odoo calendar.event record matching uid and,
|
"""Find the Odoo calendar.event record matching uid and,
|
||||||
if set, recurrence_id.
|
if set, recurrence_id.
|
||||||
"""
|
"""
|
||||||
|
|
@ -686,7 +687,7 @@ class CalendarEvent(models.Model):
|
||||||
|
|
||||||
return instance or self.env["calendar.event"].search(
|
return instance or self.env["calendar.event"].search(
|
||||||
[
|
[
|
||||||
("caldav_uid", "=", "uid"),
|
("caldav_uid", "=", uid),
|
||||||
("recurrence_id", "=", False),
|
("recurrence_id", "=", False),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
@ -841,14 +842,15 @@ class CalendarEvent(models.Model):
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _get_values_from_ical_component(
|
def _get_values_from_ical_component(
|
||||||
self, component: icalendar.cal.Component, user: User
|
self, component: icalendar.cal.Component, user: User, for_creation: bool = False
|
||||||
) -> Dict:
|
) -> Dict:
|
||||||
"""Get the dictionary representing calendar.event field values from
|
"""Get the dictionary representing calendar.event field values from
|
||||||
an iCalendar event.
|
an iCalendar event.
|
||||||
|
|
||||||
:param component: The iCalendar component from which to extract
|
:param component: The iCalendar component from which to extract values.
|
||||||
values.
|
|
||||||
:param user: The res.users record the event will belong to.
|
:param user: The res.users record the event will belong to.
|
||||||
|
:param for_creation: Whether these values are for creating a new event (True)
|
||||||
|
or updating an existing one (False).
|
||||||
:return: The dictionary of values to construct a calendar.event."""
|
:return: The dictionary of values to construct a calendar.event."""
|
||||||
start = component.get("dtstart") and component.decoded("dtstart")
|
start = component.get("dtstart") and component.decoded("dtstart")
|
||||||
if isinstance(start, datetime):
|
if isinstance(start, datetime):
|
||||||
|
|
@ -856,11 +858,11 @@ class CalendarEvent(models.Model):
|
||||||
end = component.get("dtend") and component.decoded("dtend")
|
end = component.get("dtend") and component.decoded("dtend")
|
||||||
if isinstance(end, datetime):
|
if isinstance(end, datetime):
|
||||||
end = end.astimezone(utc).replace(tzinfo=None)
|
end = end.astimezone(utc).replace(tzinfo=None)
|
||||||
organizer_partner = self._get_organizer_partner(component)
|
|
||||||
# Get the Odoo user ID associated with the organizer partner
|
# Get attendees regardless of creation/update
|
||||||
# If no Odoo user is associated, set to False (external)
|
|
||||||
organizer = organizer_partner.user_ids[0].id if organizer_partner.user_ids else False
|
|
||||||
attendee_ids = self._get_attendee_partners(component, user.partner_id.email)
|
attendee_ids = self._get_attendee_partners(component, user.partner_id.email)
|
||||||
|
|
||||||
|
# Basic values that apply to both creation and updates
|
||||||
values = {
|
values = {
|
||||||
"name": str(component.get("summary")),
|
"name": str(component.get("summary")),
|
||||||
"start": start,
|
"start": start,
|
||||||
|
|
@ -872,10 +874,25 @@ class CalendarEvent(models.Model):
|
||||||
"videocall_location": self._extract_component_text(component, "conference"),
|
"videocall_location": self._extract_component_text(component, "conference"),
|
||||||
"caldav_uid": str(component.get("uid")),
|
"caldav_uid": str(component.get("uid")),
|
||||||
"partner_ids": [(6, 0, attendee_ids.ids)],
|
"partner_ids": [(6, 0, attendee_ids.ids)],
|
||||||
"partner_id": organizer_partner.id if organizer_partner else user.partner_id.id,
|
|
||||||
"user_id": organizer,
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Only set user_id and partner_id during creation
|
||||||
|
if for_creation:
|
||||||
|
organizer_partner = self._get_organizer_partner(component)
|
||||||
|
if organizer_partner:
|
||||||
|
# Get the Odoo user ID associated with the organizer partner
|
||||||
|
organizer = organizer_partner.user_ids[0].id if organizer_partner.user_ids else False
|
||||||
|
values.update({
|
||||||
|
"partner_id": organizer_partner.id,
|
||||||
|
"user_id": organizer,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
# For new events without an organizer, use the current user
|
||||||
|
values.update({
|
||||||
|
"partner_id": user.partner_id.id,
|
||||||
|
"user_id": user.id,
|
||||||
|
})
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from odoo.tests import TransactionCase
|
from odoo.tests import TransactionCase, tagged
|
||||||
from odoo import Command
|
from odoo import Command
|
||||||
from unittest.mock import patch, MagicMock, DEFAULT
|
from unittest.mock import patch, MagicMock, DEFAULT
|
||||||
import icalendar
|
import icalendar
|
||||||
|
|
@ -85,6 +85,7 @@ def _patch_caldav_with_events_from_ics(ics_paths, user, last_modified=None):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@tagged('post_install', '-at_install')
|
||||||
class TestCalendarEvent(TransactionCase, CaldavTestCommon):
|
class TestCalendarEvent(TransactionCase, CaldavTestCommon):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
|
@ -127,17 +128,29 @@ class TestCalendarEvent(TransactionCase, CaldavTestCommon):
|
||||||
ics_path = _get_ics_path("basic.ics")
|
ics_path = _get_ics_path("basic.ics")
|
||||||
with _patch_caldav_with_events_from_ics(ics_path, user):
|
with _patch_caldav_with_events_from_ics(ics_path, user):
|
||||||
self.env["calendar.event"].poll_caldav_server()
|
self.env["calendar.event"].poll_caldav_server()
|
||||||
|
|
||||||
|
# Verify the event was created correctly
|
||||||
event = self.env["calendar.event"].search([("user_id", "=", user.id)])
|
event = self.env["calendar.event"].search([("user_id", "=", user.id)])
|
||||||
|
self.assertEqual(event.name, "Test")
|
||||||
orig_start = event.start
|
orig_start = event.start
|
||||||
orig_stop = event.stop
|
orig_stop = event.stop
|
||||||
|
|
||||||
|
# Now update the event with the updated ICS data
|
||||||
ics_path = _get_ics_path("basic_updated.ics")
|
ics_path = _get_ics_path("basic_updated.ics")
|
||||||
with _patch_caldav_with_events_from_ics(
|
with _patch_caldav_with_events_from_ics(
|
||||||
ics_path,
|
ics_path,
|
||||||
user,
|
user,
|
||||||
last_modified=(datetime.now(UTC)),
|
last_modified=(datetime.now(UTC)),
|
||||||
):
|
):
|
||||||
|
# Clear any caches to ensure fresh data
|
||||||
|
self.env["calendar.event"].invalidate_model()
|
||||||
self.env["calendar.event"].poll_caldav_server()
|
self.env["calendar.event"].poll_caldav_server()
|
||||||
|
|
||||||
|
# Refresh the event from the database to get updated values
|
||||||
|
event.invalidate_recordset()
|
||||||
event = self.env["calendar.event"].search([("user_id", "=", user.id)])
|
event = self.env["calendar.event"].search([("user_id", "=", user.id)])
|
||||||
|
|
||||||
|
# Verify the event was updated correctly
|
||||||
self.assertEqual(event.name, "Test Updated")
|
self.assertEqual(event.name, "Test Updated")
|
||||||
# This next one is just lazy avoiding the HTML stripping
|
# This next one is just lazy avoiding the HTML stripping
|
||||||
self.assertIn("Some note ...", event.description)
|
self.assertIn("Some note ...", event.description)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue