mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[IMP] Constrain avail on reservation line
This commit is contained in:
@@ -234,6 +234,11 @@ class PmsReservation(models.Model):
|
||||
reservation_type = fields.Selection(
|
||||
related="folio_id.reservation_type", default=lambda *a: "normal"
|
||||
)
|
||||
splitted = fields.Boolean(
|
||||
"Splitted",
|
||||
compute="_compute_splitted",
|
||||
store=True,
|
||||
)
|
||||
invoice_count = fields.Integer(related="folio_id.invoice_count")
|
||||
credit_card_details = fields.Text(related="folio_id.credit_card_details")
|
||||
cancelled_reason = fields.Selection(
|
||||
@@ -284,8 +289,6 @@ class PmsReservation(models.Model):
|
||||
string="Include customer",
|
||||
help="Indicates if the customer sleeps in this room",
|
||||
)
|
||||
# check_rooms = fields.Boolean('Check Rooms')
|
||||
splitted = fields.Boolean("Splitted", default=False)
|
||||
overbooking = fields.Boolean("Is Overbooking", default=False)
|
||||
reselling = fields.Boolean("Is Reselling", default=False)
|
||||
nights = fields.Integer("Nights", compute="_computed_nights", store=True)
|
||||
@@ -448,7 +451,7 @@ class PmsReservation(models.Model):
|
||||
else:
|
||||
reservation.room_type_id = False
|
||||
|
||||
@api.depends("checkin", "checkout", "overbooking", "state", "room_id")
|
||||
@api.depends("reservation_line_ids.date", "overbooking", "state", "room_id")
|
||||
def _compute_allowed_room_ids(self):
|
||||
for reservation in self:
|
||||
if reservation.checkin and reservation.checkout:
|
||||
@@ -582,6 +585,14 @@ class PmsReservation(models.Model):
|
||||
for reservation in self:
|
||||
reservation.last_updated_res = fields.Datetime.now()
|
||||
|
||||
@api.depends("reservation_line_ids", "reservation_line_ids.room_id")
|
||||
def _compute_splitted(self):
|
||||
for reservation in self:
|
||||
if len(reservation.reservation_line_ids.mapped("room_id")) > 1:
|
||||
reservation.splitted = True
|
||||
else:
|
||||
reservation.splitted = False
|
||||
|
||||
@api.depends("state", "qty_to_invoice", "qty_invoiced")
|
||||
def _compute_invoice_status(self):
|
||||
"""
|
||||
@@ -648,11 +659,10 @@ class PmsReservation(models.Model):
|
||||
)
|
||||
line.qty_invoiced = qty_invoiced
|
||||
|
||||
@api.depends("checkin", "checkout")
|
||||
@api.depends("reservation_line_ids")
|
||||
def _computed_nights(self):
|
||||
for res in self:
|
||||
if res.checkin and res.checkout:
|
||||
res.nights = (res.checkout - res.checkin).days
|
||||
res.nights = len(res.reservation_line_ids)
|
||||
|
||||
@api.depends("folio_id", "checkin", "checkout")
|
||||
def _compute_localizator(self):
|
||||
@@ -728,7 +738,7 @@ class PmsReservation(models.Model):
|
||||
|
||||
# TODO: Use default values on checkin /checkout is empty
|
||||
@api.constrains(
|
||||
"checkin", "checkout", "state", "room_id", "overbooking", "reselling"
|
||||
"reservation_line_ids.date", "state", "room_id", "overbooking", "reselling"
|
||||
)
|
||||
def check_dates(self):
|
||||
"""
|
||||
@@ -746,31 +756,6 @@ class PmsReservation(models.Model):
|
||||
less than the Check Out Date!"
|
||||
)
|
||||
)
|
||||
if (
|
||||
not self.overbooking
|
||||
and self.state not in ("cancelled")
|
||||
and not self._context.get("ignore_avail_restrictions", False)
|
||||
):
|
||||
occupied = self.env["pms.reservation"].get_reservations(
|
||||
self.checkin,
|
||||
(fields.Date.from_string(self.checkout) - timedelta(days=1)).strftime(
|
||||
DEFAULT_SERVER_DATE_FORMAT
|
||||
),
|
||||
)
|
||||
occupied = occupied.filtered(
|
||||
lambda r: r.room_id.id == self.room_id.id and r.id != self.id
|
||||
)
|
||||
occupied_name = ", ".join(str(x.folio_id.name) for x in occupied)
|
||||
if occupied:
|
||||
warning_msg = (
|
||||
_(
|
||||
"You tried to change/confirm \
|
||||
reservation with room those already reserved in this \
|
||||
reservation period: %s "
|
||||
)
|
||||
% occupied_name
|
||||
)
|
||||
raise ValidationError(warning_msg)
|
||||
|
||||
@api.constrains("checkin_partner_ids")
|
||||
def _max_checkin_partner_ids(self):
|
||||
@@ -933,6 +918,9 @@ class PmsReservation(models.Model):
|
||||
)
|
||||
if rooms_available:
|
||||
room_chosen = rooms_available[0]
|
||||
else:
|
||||
#We can split reserve night on multi rooms
|
||||
room_chosen = False
|
||||
return room_chosen
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -37,7 +37,6 @@ class PmsReservationLine(models.Model):
|
||||
compute="_compute_room_id",
|
||||
store=True,
|
||||
readonly=False,
|
||||
domain="[('id', 'in', reservation_id.allowed_room_ids)]",
|
||||
)
|
||||
move_line_ids = fields.Many2many(
|
||||
"account.move.line",
|
||||
@@ -78,6 +77,14 @@ class PmsReservationLine(models.Model):
|
||||
store=True,
|
||||
help="This record is taken into account to calculate availability")
|
||||
|
||||
_sql_constraints = [
|
||||
(
|
||||
"rule_availability",
|
||||
"EXCLUDE (room_id WITH =, date WITH =) WHERE (occupies_availability = True)",
|
||||
"Room Occupied"
|
||||
),
|
||||
]
|
||||
|
||||
# Compute and Search methods
|
||||
@api.depends(
|
||||
"reservation_id.adults",
|
||||
|
||||
@@ -22,7 +22,7 @@ class PmsRoomTypeAvailability(models.Model):
|
||||
return self.room_type_id.default_quota
|
||||
|
||||
# Fields declaration
|
||||
room_type_id = fields.Many2one('hotel.room.type', 'Room Type',
|
||||
room_type_id = fields.Many2one('pms.room.type', 'Room Type',
|
||||
required=True,
|
||||
ondelete='cascade')
|
||||
date = fields.Date('Date', required=True, track_visibility='always')
|
||||
@@ -66,6 +66,25 @@ class PmsRoomTypeAvailability(models.Model):
|
||||
free_rooms = free_rooms & rooms_linked
|
||||
return free_rooms.sorted(key=lambda r: r.sequence)
|
||||
|
||||
@api.model
|
||||
def room_types_available(self, checkin, checkout, room_type_id=False, current_lines=False):
|
||||
domain = self._get_domain_reservations_occupation(
|
||||
dfrom=checkin,
|
||||
dto=checkout - timedelta(1),
|
||||
current_lines=current_lines,
|
||||
)
|
||||
reservation_lines = self.env['pms.reservation.line'].search(domain)
|
||||
reservations_rooms = reservation_lines.mapped("room_id.id")
|
||||
free_rooms = self.env["pms.room"].search(
|
||||
[("id", "not in", reservations_rooms)]
|
||||
)
|
||||
if room_type_id:
|
||||
rooms_linked = (
|
||||
self.env["pms.room.type"].search([("id", "=", room_type_id)]).room_ids
|
||||
)
|
||||
free_rooms = free_rooms & rooms_linked
|
||||
return free_rooms.sorted(key=lambda r: r.sequence)
|
||||
|
||||
@api.model
|
||||
def _get_domain_reservations_occupation(self, dfrom, dto, current_lines=False):
|
||||
domain = [
|
||||
|
||||
@@ -496,19 +496,35 @@
|
||||
</group>
|
||||
<notebook>
|
||||
<page
|
||||
name="services"
|
||||
string="Services"
|
||||
attrs="{'invisible': ['|',('reservation_type','in',('out')),
|
||||
('parent_reservation','!=',False)]}"
|
||||
name="detail"
|
||||
string="Detail"
|
||||
>
|
||||
<button
|
||||
name="%(action_service_on_day)d"
|
||||
string="Service on Day"
|
||||
name="%(action_pms_massive_price_change_reservation_days)d"
|
||||
string="Massive Day Prices"
|
||||
type="action"
|
||||
icon="fa-coffee"
|
||||
icon="fa-bolt"
|
||||
/>
|
||||
<field name="reservation_line_ids" nolabel="1">
|
||||
<tree create="false" delete="false" editable="bottom">
|
||||
<field name="room_id" />
|
||||
<field name="date" readonly="1" force_save="1" />
|
||||
<field name="price" />
|
||||
<field name="discount" />
|
||||
<field
|
||||
name="cancel_discount"
|
||||
attrs="{'column_invisible': [('parent.state','!=','cancelled')]}"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
<button
|
||||
name="%(action_service_on_day)d"
|
||||
string="Service on Day"
|
||||
type="action"
|
||||
icon="fa-coffee"
|
||||
/>
|
||||
<group
|
||||
string="Reservation Services"
|
||||
string="Services"
|
||||
name="reservation_services"
|
||||
>
|
||||
<field
|
||||
@@ -577,30 +593,6 @@
|
||||
</field>
|
||||
</group>
|
||||
</page>
|
||||
<page
|
||||
name="days"
|
||||
string="Day Pricing"
|
||||
attrs="{'invisible': [('reservation_type','in',('out'))]}"
|
||||
>
|
||||
<button
|
||||
name="%(action_pms_massive_price_change_reservation_days)d"
|
||||
string="Massive Day Prices"
|
||||
type="action"
|
||||
icon="fa-bolt"
|
||||
/>
|
||||
<field name="reservation_line_ids" nolabel="1">
|
||||
<tree create="false" delete="false" editable="bottom">
|
||||
<field name="id" />
|
||||
<field name="date" readonly="1" force_save="1" />
|
||||
<field name="price" />
|
||||
<field name="discount" />
|
||||
<field
|
||||
name="cancel_discount"
|
||||
attrs="{'column_invisible': [('parent.state','!=','cancelled')]}"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page
|
||||
name="persons"
|
||||
string="Persons"
|
||||
|
||||
Reference in New Issue
Block a user