[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) <arj@odoo.com>
Signed-off-by: Gabriel de Paula Felix (gdpf) <gdpf@odoo.com>
This commit is contained in:
Gabriel de Paula Felix (gdpf)
2023-11-15 11:26:12 +00:00
parent 6ed92b6660
commit d9bc27b9ad
+9 -2
View File
@@ -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():