mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[RFC] Goodbye split reserves, Hi room by night!
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
77
pms/models/pms_room_type_availability.py
Normal file
77
pms/models/pms_room_type_availability.py
Normal 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
|
||||
@@ -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
|
||||
|
||||
|
@@ -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" />
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user