diff options
Diffstat (limited to 'addons/microsoft_calendar/models/calendar_recurrence_rule.py')
| -rw-r--r-- | addons/microsoft_calendar/models/calendar_recurrence_rule.py | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/addons/microsoft_calendar/models/calendar_recurrence_rule.py b/addons/microsoft_calendar/models/calendar_recurrence_rule.py new file mode 100644 index 00000000..431e01b6 --- /dev/null +++ b/addons/microsoft_calendar/models/calendar_recurrence_rule.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import re + +from odoo import api, fields, models +from dateutil.relativedelta import relativedelta + +from odoo.addons.microsoft_calendar.utils.microsoft_calendar import MicrosoftCalendarService + + +class RecurrenceRule(models.Model): + _name = 'calendar.recurrence' + _inherit = ['calendar.recurrence', 'microsoft.calendar.sync'] + + + # Don't sync by default. Sync only when the recurrence is applied + need_sync_m = fields.Boolean(default=False) + + microsoft_id = fields.Char('Microsoft Calendar Recurrence Id') + + def _apply_recurrence(self, specific_values_creation=None, no_send_edit=False): + events = self.calendar_event_ids + detached_events = super()._apply_recurrence(specific_values_creation, no_send_edit) + + microsoft_service = MicrosoftCalendarService(self.env['microsoft.service']) + + # If a synced event becomes a recurrence, the event needs to be deleted from + # Microsoft since it's now the recurrence which is synced. + # Those events are kept in the database and their microsoft_id is updated + # according to the recurrence microsoft_id, therefore we need to keep an inactive copy + # of those events with the original microsoft_id. The next sync will then correctly + # delete those events from Microsoft. + vals = [] + for event in events.filtered('microsoft_id'): + if event.active and event.microsoft_id and not event.recurrence_id.microsoft_id: + vals += [{ + 'name': event.name, + 'microsoft_id': event.microsoft_id, + 'start': event.start, + 'stop': event.stop, + 'active': False, + 'need_sync_m': True, + }] + event._microsoft_delete(microsoft_service, event.microsoft_id) + event.microsoft_id = False + self.env['calendar.event'].create(vals) + + if not no_send_edit: + for recurrence in self: + values = recurrence._microsoft_values(self._get_microsoft_synced_fields()) + if not values: + continue + values = values[0] + if not recurrence.microsoft_id: + recurrence._microsoft_insert(microsoft_service, values) + else: + recurrence._microsoft_patch(microsoft_service, recurrence.microsoft_id, values) + + self.calendar_event_ids.need_sync_m = False + return detached_events + + def _write_events(self, values, dtstart=None): + # If only some events are updated, sync those events. + # If all events are updated, sync the recurrence instead. + values['need_sync_m'] = bool(dtstart) + if not dtstart: + self.need_sync_m = True + return super()._write_events(values, dtstart=dtstart) + + def _get_microsoft_synced_fields(self): + return {'rrule'} | self.env['calendar.event']._get_microsoft_synced_fields() + + def _get_microsoft_sync_domain(self): + return [('calendar_event_ids.user_id', '=', self.env.user.id)] + + def _cancel_microsoft(self): + self.calendar_event_ids._cancel_microsoft() + self.microsoft_id = False # Set to False to avoid error with unlink from microsoft and avoid to synchronize. + self.unlink() + + @api.model + def _microsoft_to_odoo_values(self, microsoft_recurrence, default_reminders=(), default_values={}): + recurrence = microsoft_recurrence.get_recurrence() + + return { + **recurrence, + 'microsoft_id': microsoft_recurrence.id, + } + + def _microsoft_values(self, fields_to_sync): + events = self.calendar_event_ids.sorted('start') + events_outliers = self.calendar_event_ids.filtered(lambda e: not e.follow_recurrence) + normal_event = (events - events_outliers)[:1] or events[:1] + if not normal_event: + return {} + values = [normal_event._microsoft_values(fields_to_sync, initial_values={'type': 'seriesMaster'})] + + if self.microsoft_id: + values[0]['id'] = self.microsoft_id + for event in events_outliers: + event_value = event._microsoft_values(fields_to_sync) + values += [event_value] + + return values + + def _ensure_attendees_have_email(self): + self.calendar_event_ids.filtered(lambda e: e.active)._ensure_attendees_have_email() + + def _notify_attendees(self): + recurrences = self.filtered( + lambda recurrence: recurrence.base_event_id.alarm_ids and ( + not recurrence.until or recurrence.until >= fields.Date.today() - relativedelta(days=1) + ) and max(recurrence.calendar_event_ids.mapped('stop')) >= fields.Datetime.now() + ) + partners = recurrences.base_event_id.partner_ids + if partners: + self.env['calendar.alarm_manager']._notify_next_alarm(partners.ids) |
