Odoo modules related to appointments (EE)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

132 lines
4.8 KiB

import pytz
from dateutil.relativedelta import relativedelta
from odoo import fields, _
from odoo.http import request, route
from odoo.addons.appointment.controllers.appointment import AppointmentController
from odoo.addons.base.models.ir_qweb import keep_query
from werkzeug.exceptions import NotFound
class AppointmentEventController(AppointmentController):
@route(
["/appointment/<int:appointment_type_id>/submit"],
type="http",
auth="public",
website=True,
methods=["POST"],
)
def appointment_form_submit(
self,
appointment_type_id,
datetime_str,
duration_str,
staff_user_id,
name,
phone,
email,
**kwargs
):
appointment_type = self._fetch_and_check_private_appointment_types(
kwargs.get("filter_appointment_type_ids"),
kwargs.get("filter_staff_user_ids"),
kwargs.get("invite_token"),
current_appointment_type_id=int(appointment_type_id),
)
if not appointment_type:
raise NotFound()
if not appointment_type.create_events:
return super().appointment_form_submit(
appointment_type_id,
datetime_str,
duration_str,
staff_user_id,
name,
phone,
email,
**kwargs
)
# new process i
# if booking a slot should create an event
timezone = request.session.get("timezone") or appointment_type.appointment_tz
tz_session = pytz.timezone(timezone)
date_start = (
tz_session.localize(fields.Datetime.from_string(datetime_str))
.astimezone(pytz.utc)
.replace(tzinfo=None)
)
duration = float(duration_str)
date_end = date_start + relativedelta(hours=duration)
invite_token = kwargs.get("invite_token")
# check availability of the selected user again (in case someone else booked while the client was entering the form)
staff_user = request.env["res.users"].sudo().browse(int(staff_user_id)).exists()
if staff_user not in appointment_type.sudo().staff_user_ids:
raise NotFound()
if staff_user and not staff_user.partner_id.calendar_verify_availability(
date_start, date_end
):
return request.redirect(
"/appointment/%s?%s"
% (appointment_type.id, keep_query("*", state="failed-staff-user"))
)
Partner = self._get_customer_partner() or request.env[
"res.partner"
].sudo().search([("email", "=like", email)], limit=1)
if Partner:
if not Partner.calendar_verify_availability(date_start, date_end):
return request.redirect(
"/appointment/%s?%s"
% (appointment_type.id, keep_query("*", state="failed-partner"))
)
if not Partner.mobile:
Partner.write({"mobile": phone})
if not Partner.email:
Partner.write({"email": email})
else:
Partner = Partner.create(
{
"name": name,
"mobile": Partner._phone_format(
phone, country=self._get_customer_country()
),
"email": email,
"lang": request.lang.code,
}
)
# partner_inputs dictionary structures all answer inputs received on the appointment submission: key is question id, value
# is answer id (as string) for choice questions, text input for text questions, array of ids for multiple choice questions.
partner_inputs = {}
event_type = appointment_type.event_type_id
event = (
request.env["event.event"]
.sudo()
.create(
{
"name": event_type.name,
"date_begin": date_start,
"date_end": date_end,
"date_tz": timezone,
"event_type_id": event_type.id,
"user_id": int(staff_user_id),
"address_id": appointment_type.location_id.id,
}
)
)
event = event.sudo()
event.sudo().with_user(int(staff_user_id)).add_to_agenda()
event.activity_schedule(
act_type_xmlid="appointment_event.mail_activity_type_validate_date",
summary=_("New booking to check"),
note=_(
"Check date availability and set automatic validation for next bookers."
),
user_id=staff_user_id,
)
event.write({"website_published": True})
return request.redirect(event.website_url)