From d9bc27b9adbbadbeebda76ddaaa89208ff21e6e8 Mon Sep 17 00:00:00 2001 From: "Gabriel de Paula Felix (gdpf)" Date: Wed, 15 Nov 2023 06:28:44 -0300 Subject: [PATCH] [FIX] microsoft_calendar: traceback batch recurrence update in microsoft A traceback was being thrown when multiple recurrent events were being updated by a batch microsoft update due to a `self.ensure_one()` validation: ``` Traceback (most recent call last): File "/home/odoo/src/odoo/odoo/http.py", line 2003, in __call__ response = request._serve_db() File "/home/odoo/src/odoo/odoo/http.py", line 1589, in _serve_db return service_model.retrying(self._serve_ir_http, self.env) File "/home/odoo/src/odoo/odoo/service/model.py", line 133, in retrying result = func() File "/home/odoo/src/odoo/odoo/http.py", line 1616, in _serve_ir_http response = self.dispatcher.dispatch(rule.endpoint, args) File "/home/odoo/src/odoo/odoo/http.py", line 1820, in dispatch result = self.request.registry['ir.http']._dispatch(endpoint) File "/home/odoo/src/odoo/addons/website/models/ir_http.py", line 237, in _dispatch response = super()._dispatch(endpoint) File "/home/odoo/src/odoo/odoo/addons/base/models/ir_http.py", line 154, in _dispatch result = endpoint(**request.params) File "/home/odoo/src/odoo/odoo/http.py", line 697, in route_wrapper result = endpoint(self, *args, **params_ok) File "/home/odoo/src/odoo/addons/microsoft_calendar/controllers/main.py", line 55, in sync_data need_refresh = request.env.user.sudo().with_context(sync_context)._sync_microsoft_calendar() File "/home/odoo/src/odoo/addons/microsoft_calendar/models/res_users.py", line 106, in _sync_microsoft_calendar synced_events, synced_recurrences = self.env['calendar.event']._sync_microsoft2odoo(events) if events else (self.env['calendar.event'], self.env['calendar.recurrence']) File "/home/odoo/src/odoo/addons/microsoft_calendar/models/microsoft_sync.py", line 385, in _sync_microsoft2odoo update_events = odoo_event._update_microsoft_recurrence(mevent, microsoft_events) File "/home/odoo/src/odoo/addons/microsoft_calendar/models/microsoft_sync.py", line 319, in _update_microsoft_recurrence odoo_event.with_context(dont_notify=True).write(dict(event_values, need_sync_m=False)) File "/home/odoo/src/odoo/addons/base_automation/models/base_automation.py", line 401, in write return write.origin(self, vals, **kw) File "/home/odoo/src/odoo/addons/microsoft_calendar/models/calendar.py", line 180, in write self._recreate_event_different_organizer(values, sender_user) File "/home/odoo/src/odoo/addons/microsoft_calendar/models/calendar.py", line 203, in _recreate_event_different_organizer self.ensure_one() File "/home/odoo/src/odoo/odoo/models.py", line 5161, in ensure_one raise ValueError("Expected singleton: %s" % self) ValueError: Expected singleton: calendar.event() ``` After this commit, this traceback is now fixed because the validation iterates over each event, avoiding the batch conflict with the `self.ensure_one()` function and skipping the validation of recurring events since these updates are exclusively on the Microsoft side, which does not allow changing the organizer. Issue from: 3450045 closes odoo/odoo#142099 X-original-commit: 7c064a1 Signed-off-by: Arnaud Joset (arj) Signed-off-by: Gabriel de Paula Felix (gdpf) --- addons/microsoft_calendar/models/calendar.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/addons/microsoft_calendar/models/calendar.py b/addons/microsoft_calendar/models/calendar.py index 64ff343d801..eaf47cf9db0 100644 --- a/addons/microsoft_calendar/models/calendar.py +++ b/addons/microsoft_calendar/models/calendar.py @@ -176,14 +176,16 @@ class Meeting(models.Model): self._forbid_recurrence_update() # When changing the organizer, check its sync status and verify if the user is listed as attendee. + # Updates from Microsoft must skip this check since changing the organizer on their side is not possible. change_from_microsoft = self.env.context.get('dont_notify', False) + deactivated_events_ids = [] for event in self: if values.get('user_id') and event.user_id.id != values['user_id'] and not change_from_microsoft: sender_user, partner_ids = event._get_organizer_user_change_info(values) partner_included = sender_user.partner_id in event.attendee_ids.partner_id or sender_user.partner_id.id in partner_ids event._check_organizer_validation(sender_user, partner_included) event._recreate_event_different_organizer(values, sender_user) - values['active'] = False + deactivated_events_ids.append(event.id) # check a Outlook limitation in overlapping the actual recurrence if recurrence_update_setting == 'self_only' and 'start' in values: @@ -197,7 +199,12 @@ class Meeting(models.Model): event._microsoft_delete(event._get_organizer(), event.ms_organizer_event_id, timeout=3) event.microsoft_id = False - res = super(Meeting, self.with_context(dont_notify=notify_context)).write(values) + deactivated_events = self.browse(deactivated_events_ids) + res = super(Meeting, (self - deactivated_events).with_context(dont_notify=notify_context)).write(values) + + # Deactivate events that were recreated after changing organizer. + if deactivated_events: + res |= super(Meeting, deactivated_events.with_context(dont_notify=notify_context)).write({**values, 'active': False}) if recurrence_update_setting in ('all_events',) and len(self) == 1 \ and values.keys() & self._get_microsoft_synced_fields():