Files
enterprise-addons/appointment/models/res_partner.py
T

65 lines
3.1 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import pytz
from datetime import datetime, time
from odoo import fields, models
class ResPartner(models.Model):
_inherit = "res.partner"
upcoming_appointment_ids = fields.Many2many('calendar.event', string="Upcoming Appointments", compute="_compute_upcoming_appointment_ids")
def _compute_upcoming_appointment_ids(self):
partner_upcoming_appointments = dict(self.env['calendar.event']._read_group(
[('appointment_booker_id', 'in', self.ids), ('appointment_type_id', '!=', False), ('start', '>', datetime.now())],
['appointment_booker_id'],
['id:recordset'],
))
for partner in self:
partner.upcoming_appointment_ids = partner_upcoming_appointments.get(partner, False)
def calendar_verify_availability(self, date_start, date_end, appointment_type=None):
""" Verify availability of the partner(s) for the appointment between 2 datetimes on their
calendar. We only verify events that are not linked to an appointment type with resources since
someone could take multiple appointment for multiple resources. The availability of
resources is managed separately by booking lines (see ``appointment.booking.line`` model)
:param datetime date_start: beginning of slot boundary. Not timezoned UTC;
:param datetime date_end: end of slot boundary. Not timezoned UTC;
"""
all_events = self.env['calendar.event'].search(
['&',
('partner_ids', 'in', self.ids),
'&', '&',
('show_as', '=', 'busy'),
('stop', '>', datetime.combine(date_start, time.min)),
('start', '<', datetime.combine(date_end, time.max)),
],
order='start asc',
)
events_excluding_appointment_resource = all_events.filtered(lambda ev: ev.appointment_type_id.schedule_based_on != 'resources')
for event in events_excluding_appointment_resource:
if event.allday or (event.start < date_end and event.stop > date_start):
# Skip marking the staff user unavailable for the same appointment
if (appointment_type and self <= appointment_type.staff_user_ids.partner_id and
event.appointment_type_id == appointment_type):
continue
tz = pytz.timezone(event.user_id.tz) if event.user_id.tz else pytz.utc
if event.allday:
start_utc = tz.localize(event.start).astimezone(pytz.utc).replace(tzinfo=None)
stop_utc = tz.localize(event.stop).astimezone(pytz.utc).replace(tzinfo=None)
else:
start_utc = event.start
stop_utc = event.stop
if start_utc < date_end and stop_utc > date_start:
if event.attendee_ids.filtered_domain(
[('state', '!=', 'declined'),
('partner_id', 'in', self.ids)]
):
return False
return True