[RFC] Goodbye split reserves, Hi room by night!

This commit is contained in:
Darío Lodeiros
2020-10-03 11:06:15 +02:00
parent 4dcf81a6bd
commit ec4fc8d77d
9 changed files with 143 additions and 318 deletions

View File

@@ -20,6 +20,7 @@ from . import account_move
from . import product_template
from . import res_company
from . import account_payment
from . import pms_room_type_availability
from . import pms_room_type_restriction
from . import pms_room_type_restriction_item
from . import pms_reservation_line

View File

@@ -857,12 +857,12 @@ class PmsFolio(models.Model):
and not rline.parent_reservation
and rline.state == state
):
dates = (rline.real_checkin, rline.real_checkout)
dates = (rline.checkin, rline.checkout)
vals = {
"num": len(
self.reservation_ids.filtered(
lambda r: r.real_checkin == dates[0]
and r.real_checkout == dates[1]
lambda r: r.checkin == dates[0]
and r.checkout == dates[1]
and r.room_type_id.id == rline.room_type_id.id
and (r.to_send or import_all)
and not r.parent_reservation

View File

@@ -244,8 +244,6 @@ class PmsReservation(models.Model):
out_service_description = fields.Text("Cause of out of service")
checkin = fields.Date("Check In", required=True, default=_get_default_checkin)
checkout = fields.Date("Check Out", required=True, default=_get_default_checkout)
real_checkin = fields.Date("From", compute="_compute_real_checkin", store=True,)
real_checkout = fields.Date("To", compute="_compute_real_checkout", store=True,)
arrival_hour = fields.Char(
"Arrival Hour",
default=_get_default_arrival_hour,
@@ -460,12 +458,12 @@ class PmsReservation(models.Model):
)
return
rooms_available = (
self.env["pms.room.type"].check_availability_room_type(
dfrom=reservation.checkin,
dto=reservation.checkout,
self.env["pms.room.type.availability"].rooms_available(
checkin=reservation.checkin,
checkout=reservation.checkout,
room_type_id=False, # Allow chosen any available room
current_lines=reservation.reservation_line_ids.ids,
)
+ self.room_id
)
if (
reservation.room_id
@@ -572,65 +570,6 @@ class PmsReservation(models.Model):
else:
reservation.adults = 0
@api.depends("checkin")
def _compute_real_checkin(self):
for reservation in self:
reservation.real_checkin = reservation.checkin
if reservation.splitted:
master_reservation = reservation.parent_reservation or reservation
reservation.real_checkin = master_reservation.checkin
splitted_reservations = self.env["pms.reservation"].search(
[
("splitted", "=", True),
("folio_id", "=", self.folio_id.id),
"|",
("parent_reservation", "=", master_reservation.id),
("id", "=", master_reservation.id),
]
)
for split in splitted_reservations:
if reservation.real_checkin > split.checkin:
reservation.real_checkin = split.checkin
@api.depends("checkout")
def _compute_real_checkout(self):
for reservation in self:
reservation.real_checkout = reservation.checkout
if reservation.splitted:
master_reservation = reservation.parent_reservation or reservation
reservation.real_checkout = master_reservation.checkout
splitted_reservations = self.env["pms.reservation"].search(
[
("splitted", "=", True),
("folio_id", "=", self.folio_id.id),
"|",
("parent_reservation", "=", master_reservation.id),
("id", "=", master_reservation.id),
]
)
for split in splitted_reservations:
if reservation.real_checkout < split.checkout:
reservation.real_checkout = split.checkout
@api.depends("splitted", "checkout")
def _compute_real_checkin(self):
for reservation in self:
if reservation.splitted:
master_reservation = reservation.parent_reservation or reservation
first_checkin = master_reservation.checkin
splitted_reservations = self.env["pms.reservation"].search(
[
("splitted", "=", True),
("folio_id", "=", self.folio_id.id),
"|",
("parent_reservation", "=", master_reservation.id),
("id", "=", master_reservation.id),
]
)
for split in splitted_reservations:
if first_checkin > split.checkin:
reservation.real_checkin = split.checkin
@api.depends("checkin", "checkout", "state")
def _compute_to_send(self):
for reservation in self:
@@ -987,9 +926,9 @@ class PmsReservation(models.Model):
def _autoassign(self):
self.ensure_one()
room_chosen = False
rooms_available = self.env["pms.room.type"].check_availability_room_type(
dfrom=self.checkin,
dto=self.checkout,
rooms_available = self.env["pms.room.type.availability"].rooms_available(
checkin=self.checkin,
checkout=self.checkout,
room_type_id=self.room_type_id.id or False,
)
if rooms_available:
@@ -1035,8 +974,6 @@ class PmsReservation(models.Model):
"splitted": self.splitted,
"room_type_id": self.room_type_id.id,
"room_id": self.room_id.id,
"real_checkin": self.real_checkin,
"real_checkout": self.real_checkout,
}
def confirm(self):
@@ -1119,7 +1056,7 @@ class PmsReservation(models.Model):
tz_property = self.env.user.pms_property_id.tz
today = fields.Date.context_today(self.with_context(tz=tz_property))
days_diff = (
fields.Date.from_string(self.real_checkin)
fields.Date.from_string(self.checkin)
- fields.Date.from_string(today)
).days
if days_diff < 0:
@@ -1149,29 +1086,6 @@ class PmsReservation(models.Model):
)
splitted_reservs.draft()
@api.model
def get_reservations(self, dfrom, dto):
"""
@param dfrom: range date from
@param dto: range date to (NO CHECKOUT, only night)
@return: array with the reservations _confirmed_ between both
dates `dfrom` and `dto`
"""
domain = self._get_domain_reservations_occupation(dfrom, dto)
# _logger.info(domain)
return self.env["pms.reservation"].search(domain)
@api.model
def _get_domain_reservations_occupation(self, dfrom, dto):
domain = [
("reservation_line_ids.date", ">=", dfrom),
("reservation_line_ids.date", "<=", dto),
("state", "!=", "cancelled"),
("overbooking", "=", False),
("reselling", "=", False),
]
return domain
# INFO: This function is not in use and should include `dto` in the search
@api.model
def get_reservations_dates(self, dfrom, dto, room_type=False):
@@ -1252,183 +1166,10 @@ class PmsReservation(models.Model):
action["target"] = "new"
return action
def split(self, nights):
for record in self:
date_start_dt = fields.Date.from_string(record.checkin)
date_end_dt = fields.Date.from_string(record.checkout)
date_diff = abs((date_end_dt - date_start_dt).days)
new_start_date_dt = date_start_dt + timedelta(days=date_diff - nights)
if nights >= date_diff or nights < 1:
raise ValidationError(
_(
"Invalid Nights! Max is \
'%d'"
)
% (date_diff - 1)
)
vals = record.generate_copy_values(
new_start_date_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
date_end_dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
)
# Days Price
reservation_lines = [[], []]
for rline in record.reservation_line_ids:
rline_dt = fields.Date.from_string(rline.date)
if rline_dt >= new_start_date_dt:
reservation_lines[1].append(
(
0,
False,
{
"date": rline.date,
"price": rline.price,
"cancel_discount": rline.cancel_discount,
"discount": rline.discount,
"move_line_ids": rline.move_line_ids,
"state": rline.state,
},
)
)
reservation_lines[0].append((2, rline.id, False))
parent_res = record.parent_reservation or record
vals.update(
{
"splitted": True,
"parent_reservation": parent_res.id,
"room_type_id": parent_res.room_type_id.id,
"state": parent_res.state,
"reservation_line_ids": reservation_lines[1],
"preconfirm": False,
}
)
reservation_copy = (
self.env["pms.reservation"]
.with_context({"ignore_avail_restrictions": True})
.create(vals)
)
if not reservation_copy:
raise ValidationError(
_(
"Unexpected error copying record. \
Can't split reservation!"
)
)
record.write(
{
"checkout": new_start_date_dt.strftime(
DEFAULT_SERVER_DATETIME_FORMAT
),
"splitted": True,
"reservation_line_ids": reservation_lines[0],
}
)
return True
def unify(self):
self.ensure_one()
if not self.splitted:
raise ValidationError(_("This reservation can't be unified"))
master_reservation = self.parent_reservation or self
splitted_reservs = self.env["pms.reservation"].search(
[
("splitted", "=", True),
("folio_id", "=", self.folio_id.id),
"|",
("parent_reservation", "=", master_reservation.id),
("id", "=", master_reservation.id),
]
)
self.unify_books(splitted_reservs)
self_is_master = master_reservation == self
if not self_is_master:
return {"type": "ir.actions.act_window_close"}
@api.model
def unify_ids(self, reserv_ids):
splitted_reservs = self.env[self._name].browse(reserv_ids)
self.unify_books(splitted_reservs)
@api.model
def unify_books(self, splitted_reservs):
parent_reservation = (
splitted_reservs[0].parent_reservation or splitted_reservs[0]
)
room_type_ids = splitted_reservs.mapped("room_type_id.id")
if len(room_type_ids) > 1 or (
len(room_type_ids) == 1
and parent_reservation.room_type_id.id != room_type_ids[0]
):
raise ValidationError(
_(
"This reservation can't be unified: They \
all need to be in the same nº room and room type"
)
)
# Search checkout
last_checkout = splitted_reservs[0].checkout
first_checkin = splitted_reservs[0].checkin
master_reservation = splitted_reservs[0]
for reserv in splitted_reservs:
if last_checkout < reserv.checkout:
last_checkout = reserv.checkout
if first_checkin > reserv.checkin:
first_checkin = reserv.checkin
master_reservation = reserv
# Agrupate reservation lines
reservation_line_ids = splitted_reservs.mapped("reservation_line_ids")
reservation_line_ids.sorted(key=lambda r: r.date)
rlines = [(5, False, False)]
for rline in reservation_line_ids:
rlines.append(
(
0,
False,
{
"date": rline.date,
"price": rline.price,
"cancel_discount": rline.cancel_discount,
"discount": rline.discount,
"move_line_ids": rline.move_line_ids,
"state": rline.state,
},
)
)
# Unify
osplitted_reservs = splitted_reservs - master_reservation
osplitted_reservs.sudo().unlink()
_logger.info("========== UNIFY")
_logger.info(master_reservation.real_checkin)
_logger.info(first_checkin)
_logger.info(master_reservation.real_checkout)
_logger.info(last_checkout)
master_reservation.write(
{
"checkout": last_checkout,
"splitted": master_reservation.real_checkin != first_checkin
or master_reservation.real_checkout != last_checkout,
"reservation_line_ids": rlines,
}
)
#TODO
return True
def open_master(self):
self.ensure_one()
if not self.parent_reservation:
raise ValidationError(_("This is the parent reservation"))
action = self.env.ref("pms.open_pms_reservation_form_tree_all").read()[0]
action["views"] = [(self.env.ref("pms.pms_reservation_view_form").id, "form")]
action["res_id"] = self.parent_reservation.id
return action
def send_reservation_mail(self):
return self.folio_id.send_reservation_mail()

View File

@@ -30,6 +30,15 @@ class PmsReservationLine(models.Model):
required=True,
copy=False,
)
room_id = fields.Many2one(
"pms.room",
string="Room",
ondelete="restrict",
compute="_compute_room_id",
store=True,
readonly=False,
domain="[('id', 'in', reservation_id.allowed_room_ids)]",
)
move_line_ids = fields.Many2many(
"account.move.line",
"reservation_line_move_rel",
@@ -63,8 +72,27 @@ class PmsReservationLine(models.Model):
readonly=False,
)
discount = fields.Float(string="Discount (%)", digits=("Discount"), default=0.0)
occupies_availability = fields.Boolean(
string = "Occupies",
compute="_compute_occupies_availability",
store=True,
help="This record is taken into account to calculate availability")
# Compute and Search methods
@api.depends(
"reservation_id.adults",
"reservation_id.room_type_id",
"reservation_id.room_id")
def _compute_room_id(self):
lines_no_room = self.filtered_domain([("room_id", "=", False)])
lines_with_room = self - lines_no_room
for line in lines_no_room:
if line.reservation_id.room_id:
line.room_id = line.reservation_id.room_id
# TODO: check_split reservation
# TODO: Allow with confirmation message to
# change de room if the user change the room_type?
@api.depends(
"reservation_id",
"reservation_id.pricelist_id",
@@ -99,6 +127,15 @@ class PmsReservationLine(models.Model):
else:
line.price = line._origin.price
@api.depends("reservation_id.state", "reservation_id.overbooking")
def _compute_occupies_availability(self):
for line in self:
if line.reservation_id.state == "cancelled" or \
line.reservation_id.overbooking == True:
line.occupies_availability = False
else:
line.occupies_availability = True
def _recompute_price(self):
#REVIEW: Conditional to avoid overriding already calculated prices,
# I'm not sure it's the best way
@@ -131,10 +168,10 @@ class PmsReservationLine(models.Model):
# and pricelist.cancelation_rule_id
# ):
# date_start_dt = fields.Date.from_string(
# reservation.real_checkin or reservation.checkin
# reservation.checkin
# )
# date_end_dt = fields.Date.from_string(
# reservation.real_checkout or reservation.checkout
# reservation.checkout
# )
# days = abs((date_end_dt - date_start_dt).days)
# rule = pricelist.cancelation_rule_id
@@ -153,7 +190,7 @@ class PmsReservationLine(models.Model):
# elif reservation.cancelled_reason == "intime":
# discount = 100
# checkin = reservation.real_checkin or reservation.checkin
# checkin = reservation.checkin
# dates = []
# for i in range(0, days):
# dates.append(

View File

@@ -57,6 +57,14 @@ class PmsRoomType(models.Model):
total_rooms_count = fields.Integer(compute="_compute_total_rooms", store=True)
active = fields.Boolean("Active", default=True)
sequence = fields.Integer("Sequence", default=0)
default_max_avail = fields.Integer("Max. Availability", default=-1,
help="Maximum simultaneous availability on own Booking Engine "
"given no availability rules. "
"Use `-1` for using maximum simultaneous availability.")
default_quota = fields.Integer("Default Quota", default=-1,
help="Quota assigned to the own Booking Engine given no availability rules. "
"Use `-1` for managing no quota.")
_sql_constraints = [
(
@@ -93,25 +101,6 @@ class PmsRoomType(models.Model):
capacities = self.room_ids.mapped("capacity")
return min(capacities) if any(capacities) else 0
# TODO: Change name method by rooms_available()
@api.model
def check_availability_room_type(self, dfrom, dto, room_type_id=False, notthis=[]):
"""
Check the max availability for an specific
type of room in a range of dates
"""
reservations = self.env["pms.reservation"].get_reservations(dfrom, dto - timedelta(1))
reservations_rooms = reservations.mapped("room_id.id")
free_rooms = self.env["pms.room"].search(
[("id", "not in", reservations_rooms), ("id", "not in", notthis)]
) # TODO: Review if with the new caché V13 We need notthis []¿?
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_rate_room_types(self, **kwargs):
"""

View File

@@ -0,0 +1,77 @@
# Copyright 2017 Alexandre Díaz
# Copyright 2017 Dario Lodeiros
# Copyright 2018 Pablo Quesada
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from datetime import timedelta
class PmsRoomTypeAvailability(models.Model):
_name = "pms.room.type.availability"
_description = "Availability"
_inherit = 'mail.thread'
@api.model
def _default_max_avail(self):
return self.room_type_id.default_max_avail
@api.model
def _default_quota(self):
return self.room_type_id.default_quota
# Fields declaration
room_type_id = fields.Many2one('hotel.room.type', 'Room Type',
required=True,
ondelete='cascade')
date = fields.Date('Date', required=True, track_visibility='always')
quota = fields.Integer("Quota", default=_default_quota,
track_visibility='always',
help="Generic Quota assigned.")
max_avail = fields.Integer("Max. Availability", default=-1, readonly=True,
track_visibility='always',
help="Maximum simultaneous availability on own Booking Engine.")
no_web = fields.Boolean('No Web', default=False,
track_visibility='onchange',
help="Set zero availability to the own Booking Engine "
"even when the availability is positive,")
_sql_constraints = [
(
"unique_availability_room_type_rule_date",
"unique(room_type_id, date)",
"The availability rule for this date in this room type already exists, "
"modify it instead of trying to create a new one",
),
]
# Business Methods
@api.model
def rooms_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 = [
("date", ">=", dfrom),
("date", "<=", dto),
("occupies_availability", "=", True),
("id","not in", current_lines),
]
return domain

View File

@@ -22,8 +22,8 @@ user_access_pms_board_service_line,user_access_pms_board_service_line,model_pms_
user_access_account_partial_reconcile,user_access_account_partial_reconcile,account.model_account_partial_reconcile,pms.group_pms_user,1,1,1,1
user_access_pms_cancelation_rule,user_access_pms_cancelation_rule,model_pms_cancelation_rule,pms.group_pms_user,1,0,0,0
user_access_account_full_reconcile,user_access_account_full_reconcile,account.model_account_full_reconcile,pms.group_pms_user,1,1,1,1
call_access_pms_cancelation_rule,call_access_pms_cancelation_rule,model_pms_cancelation_rule,base.group_user,1,0,0,0
user_access_property,user_access_property,model_pms_property,pms.group_pms_user,1,0,0,0
user_access_availability,user_access_availability,model_pms_room_type_availability,pms.group_pms_user,1,0,0,0
manager_access_pms_floor,manager_access_pms_floor,model_pms_floor,pms.group_pms_manager,1,1,1,1
manager_access_pms_amenity,manager_access_pms_amenity,model_pms_amenity,pms.group_pms_manager,1,1,1,1
manager_access_pms_amenity_type,manager_access_pms_amenity_type,model_pms_amenity_type,pms.group_pms_manager,1,1,1,1
@@ -45,25 +45,5 @@ manager_access_pms_board_service_room_type,manager_access_pms_board_service_room
manager_access_pms_board_service_room_type_line,manager_access_pms_board_service_room_type_line,model_pms_board_service_room_type_line,pms.group_pms_manager,1,1,1,1
manager_access_pms_board_service_line,manager_access_pms_board_service_line,model_pms_board_service_line,pms.group_pms_manager,1,1,1,1
manager_access_property,manager_access_property,model_pms_property,pms.group_pms_manager,1,1,1,1
manager_access_pms_cancelation_rule,manager_access_pms_cancelation_rule,model_pms_cancelation_rule,base.group_user,1,1,1,1
call_access_pms_floor,call_access_pms_floor,model_pms_floor,pms.group_pms_call,1,0,0,0
call_access_pms_amenity,call_access_pms_amenity,model_pms_amenity,pms.group_pms_call,1,0,0,0
call_access_pms_amenity_type,call_access_pms_amenity_type,model_pms_amenity_type,pms.group_pms_call,1,0,0,0
call_access_pms_service,call_access_pms_service,model_pms_service,pms.group_pms_call,1,1,1,1
call_access_pms_room_type_restriction,call_access_pms_room_type_restriction,model_pms_room_type_restriction,pms.group_pms_call,1,0,0,0
call_access_pms_reservation_line,call_access_pms_reservation_line,model_pms_reservation_line,pms.group_pms_call,1,1,1,1
call_access_room_closure_reason,call_access_room_closure_reason,model_room_closure_reason,pms.group_pms_call,1,0,0,0
call_access_pms_service_line,call_access_pms_service_line,model_pms_service_line,pms.group_pms_call,1,1,1,1
call_access_pms_board_service,call_access_pms_board_service,model_pms_board_service,pms.group_pms_call,1,0,0,0
call_access_pms_checkin_partner,call_access_pms_checkin_partner,model_pms_checkin_partner,pms.group_pms_call,1,1,1,1
call_access_pms_room_type_class,call_access_pms_room_type_class,model_pms_room_type_class,pms.group_pms_call,1,0,0,0
call_access_pms_room,call_access_pms_room,model_pms_room,pms.group_pms_call,1,0,0,0
call_access_pms_shared_room,call_access_pms_shared_room,model_pms_shared_room,pms.group_pms_call,1,0,0,0
call_access_pms_room_type_restriction_item,call_access_pms_room_type_restriction_item,model_pms_room_type_restriction_item,pms.group_pms_call,1,0,0,0
call_access_pms_reservation,call_access_pms_reservation,model_pms_reservation,pms.group_pms_call,1,1,1,1
call_access_pms_folio,call_access_pms_folio,model_pms_folio,pms.group_pms_call,1,1,1,1
call_access_pms_room_type,call_access_pms_room_type,model_pms_room_type,pms.group_pms_call,1,0,0,0
call_access_pms_board_service_room_type,call_access_pms_board_service_room_type,model_pms_board_service_room_type,pms.group_pms_call,1,0,0,0
call_access_pms_board_service_room_type_line,call_access_pms_board_service_room_type_line,model_pms_board_service_room_type_line,pms.group_pms_call,1,0,0,0
call_access_pms_board_service_line,call_access_pms_board_service_line,model_pms_board_service_line,pms.group_pms_call,1,0,0,0
call_access_property,call_access_property,model_pms_property,pms.group_pms_call,1,0,0,0
manager_access_pms_cancelation_rule,manager_access_pms_cancelation_rule,model_pms_cancelation_rule,pms.group_pms_manager,1,1,1,1
user_access_availability,user_access_availability,model_pms_room_type_availability,pms.group_pms_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
22 user_access_account_partial_reconcile user_access_account_partial_reconcile account.model_account_partial_reconcile pms.group_pms_user 1 1 1 1
23 user_access_pms_cancelation_rule user_access_pms_cancelation_rule model_pms_cancelation_rule pms.group_pms_user 1 0 0 0
24 user_access_account_full_reconcile user_access_account_full_reconcile account.model_account_full_reconcile pms.group_pms_user 1 1 1 1
call_access_pms_cancelation_rule call_access_pms_cancelation_rule model_pms_cancelation_rule base.group_user 1 0 0 0
25 user_access_property user_access_property model_pms_property pms.group_pms_user 1 0 0 0
26 user_access_availability user_access_availability model_pms_room_type_availability pms.group_pms_user 1 0 0 0
27 manager_access_pms_floor manager_access_pms_floor model_pms_floor pms.group_pms_manager 1 1 1 1
28 manager_access_pms_amenity manager_access_pms_amenity model_pms_amenity pms.group_pms_manager 1 1 1 1
29 manager_access_pms_amenity_type manager_access_pms_amenity_type model_pms_amenity_type pms.group_pms_manager 1 1 1 1
45 manager_access_pms_board_service_room_type_line manager_access_pms_board_service_room_type_line model_pms_board_service_room_type_line pms.group_pms_manager 1 1 1 1
46 manager_access_pms_board_service_line manager_access_pms_board_service_line model_pms_board_service_line pms.group_pms_manager 1 1 1 1
47 manager_access_property manager_access_property model_pms_property pms.group_pms_manager 1 1 1 1
48 manager_access_pms_cancelation_rule manager_access_pms_cancelation_rule model_pms_cancelation_rule base.group_user pms.group_pms_manager 1 1 1 1
49 call_access_pms_floor user_access_availability call_access_pms_floor user_access_availability model_pms_floor model_pms_room_type_availability pms.group_pms_call pms.group_pms_manager 1 0 1 0 1 0 1
call_access_pms_amenity call_access_pms_amenity model_pms_amenity pms.group_pms_call 1 0 0 0
call_access_pms_amenity_type call_access_pms_amenity_type model_pms_amenity_type pms.group_pms_call 1 0 0 0
call_access_pms_service call_access_pms_service model_pms_service pms.group_pms_call 1 1 1 1
call_access_pms_room_type_restriction call_access_pms_room_type_restriction model_pms_room_type_restriction pms.group_pms_call 1 0 0 0
call_access_pms_reservation_line call_access_pms_reservation_line model_pms_reservation_line pms.group_pms_call 1 1 1 1
call_access_room_closure_reason call_access_room_closure_reason model_room_closure_reason pms.group_pms_call 1 0 0 0
call_access_pms_service_line call_access_pms_service_line model_pms_service_line pms.group_pms_call 1 1 1 1
call_access_pms_board_service call_access_pms_board_service model_pms_board_service pms.group_pms_call 1 0 0 0
call_access_pms_checkin_partner call_access_pms_checkin_partner model_pms_checkin_partner pms.group_pms_call 1 1 1 1
call_access_pms_room_type_class call_access_pms_room_type_class model_pms_room_type_class pms.group_pms_call 1 0 0 0
call_access_pms_room call_access_pms_room model_pms_room pms.group_pms_call 1 0 0 0
call_access_pms_shared_room call_access_pms_shared_room model_pms_shared_room pms.group_pms_call 1 0 0 0
call_access_pms_room_type_restriction_item call_access_pms_room_type_restriction_item model_pms_room_type_restriction_item pms.group_pms_call 1 0 0 0
call_access_pms_reservation call_access_pms_reservation model_pms_reservation pms.group_pms_call 1 1 1 1
call_access_pms_folio call_access_pms_folio model_pms_folio pms.group_pms_call 1 1 1 1
call_access_pms_room_type call_access_pms_room_type model_pms_room_type pms.group_pms_call 1 0 0 0
call_access_pms_board_service_room_type call_access_pms_board_service_room_type model_pms_board_service_room_type pms.group_pms_call 1 0 0 0
call_access_pms_board_service_room_type_line call_access_pms_board_service_room_type_line model_pms_board_service_room_type_line pms.group_pms_call 1 0 0 0
call_access_pms_board_service_line call_access_pms_board_service_line model_pms_board_service_line pms.group_pms_call 1 0 0 0
call_access_property call_access_property model_pms_property pms.group_pms_call 1 0 0 0

View File

@@ -53,7 +53,7 @@
<t t-esc="r.room_type_id.name" />
</td>
<td>
<t t-esc="r.real_checkin" />
<t t-esc="r.checkin" />
</td>
<td>
<t t-esc="r.nights" />

View File

@@ -380,7 +380,7 @@ class PmsRoomTypeWizards(models.TransientModel):
[("room_type_id", "=", res.room_type_id.id)]
)
real_max = len(
res.room_type_id.check_availability_room_type(
self.env["pms.room.type.availability"].rooms_available(
res.checkin,
(
fields.Date.from_string(res.checkout) - timedelta(days=1)