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

  1. import pytz
  2. from dateutil.relativedelta import relativedelta
  3. from odoo import fields, _
  4. from odoo.http import request, route
  5. from odoo.addons.appointment.controllers.appointment import AppointmentController
  6. from odoo.addons.base.models.ir_qweb import keep_query
  7. from werkzeug.exceptions import NotFound
  8. class AppointmentEventController(AppointmentController):
  9. @route(
  10. ["/appointment/<int:appointment_type_id>/submit"],
  11. type="http",
  12. auth="public",
  13. website=True,
  14. methods=["POST"],
  15. )
  16. def appointment_form_submit(
  17. self,
  18. appointment_type_id,
  19. datetime_str,
  20. duration_str,
  21. staff_user_id,
  22. name,
  23. phone,
  24. email,
  25. **kwargs
  26. ):
  27. appointment_type = self._fetch_and_check_private_appointment_types(
  28. kwargs.get("filter_appointment_type_ids"),
  29. kwargs.get("filter_staff_user_ids"),
  30. kwargs.get("invite_token"),
  31. current_appointment_type_id=int(appointment_type_id),
  32. )
  33. if not appointment_type:
  34. raise NotFound()
  35. if not appointment_type.create_events:
  36. return super().appointment_form_submit(
  37. appointment_type_id,
  38. datetime_str,
  39. duration_str,
  40. staff_user_id,
  41. name,
  42. phone,
  43. email,
  44. **kwargs
  45. )
  46. # new process i
  47. # if booking a slot should create an event
  48. timezone = request.session.get("timezone") or appointment_type.appointment_tz
  49. tz_session = pytz.timezone(timezone)
  50. date_start = (
  51. tz_session.localize(fields.Datetime.from_string(datetime_str))
  52. .astimezone(pytz.utc)
  53. .replace(tzinfo=None)
  54. )
  55. duration = float(duration_str)
  56. date_end = date_start + relativedelta(hours=duration)
  57. invite_token = kwargs.get("invite_token")
  58. # check availability of the selected user again (in case someone else booked while the client was entering the form)
  59. staff_user = request.env["res.users"].sudo().browse(int(staff_user_id)).exists()
  60. if staff_user not in appointment_type.sudo().staff_user_ids:
  61. raise NotFound()
  62. if staff_user and not staff_user.partner_id.calendar_verify_availability(
  63. date_start, date_end
  64. ):
  65. return request.redirect(
  66. "/appointment/%s?%s"
  67. % (appointment_type.id, keep_query("*", state="failed-staff-user"))
  68. )
  69. Partner = self._get_customer_partner() or request.env[
  70. "res.partner"
  71. ].sudo().search([("email", "=like", email)], limit=1)
  72. if Partner:
  73. if not Partner.calendar_verify_availability(date_start, date_end):
  74. return request.redirect(
  75. "/appointment/%s?%s"
  76. % (appointment_type.id, keep_query("*", state="failed-partner"))
  77. )
  78. if not Partner.mobile:
  79. Partner.write({"mobile": phone})
  80. if not Partner.email:
  81. Partner.write({"email": email})
  82. else:
  83. Partner = Partner.create(
  84. {
  85. "name": name,
  86. "mobile": Partner._phone_format(
  87. phone, country=self._get_customer_country()
  88. ),
  89. "email": email,
  90. "lang": request.lang.code,
  91. }
  92. )
  93. # partner_inputs dictionary structures all answer inputs received on the appointment submission: key is question id, value
  94. # is answer id (as string) for choice questions, text input for text questions, array of ids for multiple choice questions.
  95. partner_inputs = {}
  96. event_type = appointment_type.event_type_id
  97. event = (
  98. request.env["event.event"]
  99. .sudo()
  100. .create(
  101. {
  102. "name": event_type.name,
  103. "date_begin": date_start,
  104. "date_end": date_end,
  105. "date_tz": timezone,
  106. "event_type_id": event_type.id,
  107. "user_id": int(staff_user_id),
  108. "address_id": appointment_type.location_id.id,
  109. }
  110. )
  111. )
  112. event = event.sudo()
  113. event.sudo().with_user(int(staff_user_id)).add_to_agenda()
  114. event.activity_schedule(
  115. act_type_xmlid="appointment_event.mail_activity_type_validate_date",
  116. summary=_("New booking to check"),
  117. note=_(
  118. "Check date availability and set automatic validation for next bookers."
  119. ),
  120. user_id=staff_user_id,
  121. )
  122. event.write({"website_published": True})
  123. return request.redirect(event.website_url)