Files
enterprise-addons/appointment_google_reserve/models/calendar_event.py
T

106 lines
4.6 KiB
Python

from odoo import api, fields, models
from ..tools.google_reserve_iap import GoogleReserveIAP
class CalendarEvent(models.Model):
_inherit = 'calendar.event'
is_google_reserve = fields.Boolean("From Google Reserve", readonly=True)
@api.model_create_multi
def create(self, vals_list):
""" Update the availability based on the new events created if needed. """
events = super().create(vals_list)
events._sync_google_reserve_availabilities()
return events
def write(self, vals):
""" Update the google booking and availabilities. """
google_sync_modifying_fields = {
'active',
'duration',
'start',
'stop',
'total_capacity_reserved',
}
old_dates_by_event = False
if 'start' in vals or 'stop' in vals:
old_dates_by_event = {
event: (event.start, event.stop) for event in self
}
result = super().write(vals)
if not vals.keys() & google_sync_modifying_fields:
return result
self._sync_google_reserve_availabilities(old_dates_by_event)
if not self.env.context.get('google_reserve_service_rpc'):
# if the modification does not come from a Google Reserve call -> update the booking
google_reserve = GoogleReserveIAP()
events_by_appointment = self.filtered(
lambda event: event.appointment_type_id.google_reserve_enable
).grouped('appointment_type_id')
for appointment_type, appointment_events in events_by_appointment.items():
if google_reserve_events := appointment_events.filtered('is_google_reserve'):
if 'stop' in vals and 'start' not in vals:
# special case: Google will only accept "start" and "duration"
# -> manually add start for each event
for google_reserve_event in google_reserve_events:
google_reserve.update_booking(
appointment_type,
google_reserve_events.ids,
{'start': google_reserve_event.start, **vals}
)
else:
google_reserve.update_booking(appointment_type, google_reserve_events.ids, vals)
return result
@api.ondelete(at_uninstall=False)
def _unlink_update_availabilities(self):
""" Cancel the google booking and update availabilities."""
google_reserve = GoogleReserveIAP()
dates_by_appointment = {}
deleted_bookings_by_appointment = {}
events_by_appointment = self.grouped('appointment_type_id')
for appointment_type, appointment_events in events_by_appointment.items():
if not appointment_type or not appointment_type.google_reserve_enable:
continue
dates_by_appointment[appointment_type] = (
min(appointment_events.mapped('start')),
max(appointment_events.mapped('stop')),
)
if google_reserve_events := appointment_events.filtered('is_google_reserve'):
deleted_bookings_by_appointment[appointment_type] = google_reserve_events.ids
for appointment_type, (start, end) in dates_by_appointment.items():
google_reserve.update_availabilities(appointment_type, start, end)
for appointment_type, google_reserve_events_ids in deleted_bookings_by_appointment.items():
google_reserve.update_booking(appointment_type, google_reserve_events_ids, {'active': False})
def _sync_google_reserve_availabilities(self, old_dates_by_event=False):
google_reserve = GoogleReserveIAP()
events_by_appointment = self.grouped('appointment_type_id')
for appointment_type, appointment_events in events_by_appointment.items():
if not appointment_type or not appointment_type.google_reserve_enable:
continue
min_start = min(appointment_events.mapped('start'))
max_stop = max(appointment_events.mapped('stop'))
if old_dates_by_event:
old_starts = [old_date[0] for event, old_date in old_dates_by_event.items() if event in appointment_events]
old_stops = [old_date[1] for event, old_date in old_dates_by_event.items() if event in appointment_events]
min_start = min([min_start] + old_starts)
max_stop = max([max_stop] + old_stops)
google_reserve.update_availabilities(appointment_type, min_start, max_stop)