1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/room/models/room_booking.py
2024-12-10 09:04:09 +07:00

88 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class RoomBooking(models.Model):
_name = "room.booking"
_inherit = ["mail.thread"]
_description = "Room Booking"
_order = "start_datetime desc, id"
name = fields.Char(string="Booking Name", required=True, tracking=1)
room_id = fields.Many2one("room.room", string="Room", required=True, ondelete="cascade", group_expand="_read_group_room_id", tracking=4)
start_datetime = fields.Datetime(string="Start Datetime", required=True, tracking=2)
stop_datetime = fields.Datetime(string="End Datetime", required=True, tracking=3)
organizer_id = fields.Many2one("res.users", string="Organizer", default=lambda self: self.env.user.id if not self.env.user._is_public() else False, tracking=5)
# Fields used to group bookings in gantt view
office_id = fields.Many2one(related="room_id.office_id", string="Office", readonly=True, store=True)
company_id = fields.Many2one(related="room_id.company_id", string="Company", readonly=True, store=True)
@api.constrains("start_datetime", "stop_datetime")
def _check_date_boundaries(self):
for booking in self:
if booking.start_datetime >= booking.stop_datetime:
raise ValidationError(_(
"The start date of %(booking_name)s must be earlier than the end date.",
booking_name=booking.name
))
@api.constrains("start_datetime", "stop_datetime")
def _check_unique_slot(self):
min_start = min(self.mapped("start_datetime"))
max_stop = max(self.mapped("stop_datetime"))
bookings_by_room = self.search([("room_id", "in", self.room_id.ids), ("start_datetime", "<", max_stop), ("stop_datetime", ">", min_start)]).grouped("room_id")
for booking in self:
if bookings_by_room.get(booking.room_id) and bookings_by_room[booking.room_id].filtered(
lambda b: b.id != booking.id and b.start_datetime < booking.stop_datetime and b.stop_datetime > booking.start_datetime
):
raise ValidationError(_(
"Room %(room_name)s is already booked during the selected time slot.",
room_name=booking.room_id.name
))
# ------------------------------------------------------
# CRUD / ORM
# ------------------------------------------------------
@api.model_create_multi
def create(self, vals_list):
bookings = super(RoomBooking, self).create(vals_list)
# Notify frontend views of new bookings
for room, bookings in bookings.grouped("room_id").items():
room._notify_booking_view("create", bookings)
return bookings
def unlink(self):
# Notify frontend of deleted bookings
bookings_by_room = self.grouped("room_id")
for room, bookings in bookings_by_room.items():
room._notify_booking_view("delete", bookings)
return super(RoomBooking, self).unlink()
def write(self, vals):
bookings_by_room = self.grouped("room_id")
res = super(RoomBooking, self).write(vals)
# Notify frontend of updated bookings
if new_room_id := vals.get("room_id"):
new_room = self.env["room.room"].browse(new_room_id)
for room, bookings in bookings_by_room.items():
room._notify_booking_view("delete", bookings)
new_room._notify_booking_view("create", bookings)
elif {"name", "start_datetime", "stop_datetime"} & vals.keys():
for room, bookings in bookings_by_room.items():
room._notify_booking_view("update", bookings)
return res
@api.model
def _read_group_room_id(self, rooms, domain, order):
# Display all the rooms in the gantt view even if they have no booking,
# and order them by office first, then by usual order (because the
# office name is shown in the display name)
if self.env.context.get("room_booking_gantt_show_all_rooms"):
room_ids = rooms._search([], order="office_id," + order)
return rooms.browse(room_ids)
return rooms