diff --git a/pms/README.rst b/pms/README.rst
index 31c4eee92..c06b14932 100644
--- a/pms/README.rst
+++ b/pms/README.rst
@@ -29,7 +29,7 @@ This module is an all-in-one property management system (PMS) focused on medium-
for managing every aspect of your property's daily operations.
You can manage hotel properties with multi-hotel and multi-company support, including your rooms inventory,
-reservations, check-in, daily reports, board services, rate and restriction plans among other hotel functionalities.
+reservations, check-in, daily reports, board services, rate and availability plans among other hotel functionalities.
.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
diff --git a/pms/__manifest__.py b/pms/__manifest__.py
index f27f6e821..ebc5cdc43 100644
--- a/pms/__manifest__.py
+++ b/pms/__manifest__.py
@@ -52,8 +52,8 @@
"views/account_move_views.xml",
"views/res_users_views.xml",
"views/pms_room_type_class_views.xml",
- "views/pms_room_type_restriction_views.xml",
- "views/pms_room_type_restriction_item_views.xml",
+ "views/pms_room_type_availability_views.xml",
+ "views/pms_room_type_availability_rule_views.xml",
"views/pms_service_views.xml",
"views/pms_service_line_views.xml",
"views/pms_shared_room_views.xml",
diff --git a/pms/data/pms_data.xml b/pms/data/pms_data.xml
index 7eafee0f0..2f5ce7824 100644
--- a/pms/data/pms_data.xml
+++ b/pms/data/pms_data.xml
@@ -2,14 +2,17 @@
-
- Restriction Plan
+
+ Availability Plan
My Property
-
+
Rua Street Demo, s/n
Commitsun city
diff --git a/pms/demo/pms_master_data.xml b/pms/demo/pms_master_data.xml
index 04a899f6f..3c4199e69 100644
--- a/pms/demo/pms_master_data.xml
+++ b/pms/demo/pms_master_data.xml
@@ -298,14 +298,17 @@
-
- Restriction Plan Demo
+
+ Availability Plan Demo
My pms Demo
-
+
diff --git a/pms/models/__init__.py b/pms/models/__init__.py
index 92f2ace63..c24fbd560 100644
--- a/pms/models/__init__.py
+++ b/pms/models/__init__.py
@@ -24,8 +24,7 @@ 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_room_type_availability_rule
from . import pms_reservation_line
from . import pms_checkin_partner
from . import product_pricelist
diff --git a/pms/models/pms_property.py b/pms/models/pms_property.py
index 76295607d..30b5ed88f 100644
--- a/pms/models/pms_property.py
+++ b/pms/models/pms_property.py
@@ -41,11 +41,11 @@ class PmsProperty(models.Model):
required=True,
help="The default pricelist used in this property.",
)
- default_restriction_id = fields.Many2one(
- "pms.room.type.restriction",
- "Restriction Plan",
+ default_availability_id = fields.Many2one(
+ "pms.room.type.availability",
+ "Availability Plan",
required=True,
- help="The default restriction plan used in this property.",
+ help="The default availability plan used in this property.",
)
default_arrival_hour = fields.Char(
"Arrival Hour (GMT)", help="HH:mm Format", default="14:00"
diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py
index ed7da2781..25d5686d5 100644
--- a/pms/models/pms_reservation.py
+++ b/pms/models/pms_reservation.py
@@ -521,7 +521,9 @@ class PmsReservation(models.Model):
[("active", "=", True)]
)
return
- rooms_available = self.env["pms.room.type.restriction"].rooms_available(
+ rooms_available = self.env[
+ "pms.room.type.availability"
+ ].rooms_available(
checkin=reservation.checkin,
checkout=reservation.checkout,
room_type_id=False, # Allow chosen any available room
@@ -1101,7 +1103,7 @@ class PmsReservation(models.Model):
}
def open_reservation_wizard(self):
- rooms_available = self.env["pms.room.type.restriction"].rooms_available(
+ rooms_available = self.env["pms.room.type.availability"].rooms_available(
checkin=self.checkin,
checkout=self.checkout,
current_lines=self.reservation_line_ids.ids,
@@ -1184,7 +1186,7 @@ class PmsReservation(models.Model):
def _autoassign(self):
self.ensure_one()
room_chosen = False
- rooms_available = self.env["pms.room.type.restriction"].rooms_available(
+ 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,
diff --git a/pms/models/pms_reservation_line.py b/pms/models/pms_reservation_line.py
index 1f0f77c51..522d446ca 100644
--- a/pms/models/pms_reservation_line.py
+++ b/pms/models/pms_reservation_line.py
@@ -108,7 +108,9 @@ class PmsReservationLine(models.Model):
# select room_id regardless room_type_id selected on reservation
free_room_select = True if reservation.preferred_room_id else False
# we get the rooms available for the entire stay
- rooms_available = self.env["pms.room.type.restriction"].rooms_available(
+ rooms_available = self.env[
+ "pms.room.type.availability"
+ ].rooms_available(
checkin=line.reservation_id.checkin,
checkout=line.reservation_id.checkout,
room_type_id=reservation.room_type_id.id
@@ -139,7 +141,7 @@ class PmsReservationLine(models.Model):
else:
line.room_id = rooms_available[0]
# check that the reservation cannot be allocated even by dividing it
- elif not self.env["pms.room.type.restriction"].splitted_availability(
+ elif not self.env["pms.room.type.availability"].splitted_availability(
checkin=line.reservation_id.checkin,
checkout=line.reservation_id.checkout,
room_type_id=line.reservation_id.room_type_id.id,
@@ -233,7 +235,7 @@ class PmsReservationLine(models.Model):
def _compute_impact_quota(self):
for line in self:
reservation = line.reservation_id
- line.impacts_quota = self.env["pms.room.type.restriction"].update_quota(
+ line.impacts_quota = self.env["pms.room.type.availability"].update_quota(
pricelist_id=reservation.pricelist_id,
room_type_id=reservation.room_type_id,
date=line.date,
diff --git a/pms/models/pms_room_type_availability.py b/pms/models/pms_room_type_availability.py
index 4b62ae422..2b47ac596 100644
--- a/pms/models/pms_room_type_availability.py
+++ b/pms/models/pms_room_type_availability.py
@@ -1,92 +1,193 @@
# 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 datetime import timedelta
+import datetime
from odoo import api, fields, models
class PmsRoomTypeAvailability(models.Model):
+ """The room type availability is used as a daily availability plan for room types
+ and therefore is related only with one property."""
+
_name = "pms.room.type.availability"
- _description = "Availability"
- _inherit = "mail.thread"
+ _description = "Reservation availability plan"
+ # Default methods
@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
+ def _get_default_pms_property(self):
+ return self.env.user.pms_property_id or None
# Fields declaration
- room_type_id = fields.Many2one(
- "pms.room.type", "Room Type", required=True, ondelete="cascade"
- )
- date = fields.Date(
- "Date",
- required=True,
- tracking=True,
- )
- quota = fields.Integer(
- "Quota",
- default=_default_quota,
- tracking=True,
- help="Generic Quota assigned.",
- )
- max_avail = fields.Integer(
- "Max. Availability",
- default=-1,
- readonly=True,
- tracking=True,
- help="Maximum simultaneous availability on own Booking Engine.",
- )
- no_web = fields.Boolean(
- "No Web",
- default=False,
- tracking=True,
- help="Set zero availability to the own Booking Engine "
- "even when the availability is positive,",
+ name = fields.Char("Availability Plan Name", required=True)
+ pms_property_id = fields.Many2one(
+ comodel_name="pms.property",
+ string="Property",
+ ondelete="restrict",
)
- _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",
- ),
- ]
+ pms_pricelist_ids = fields.One2many(
+ comodel_name="product.pricelist",
+ inverse_name="availability_id",
+ string="Pricelists",
+ required=False,
+ ondelete="restrict",
+ )
+
+ item_ids = fields.One2many(
+ comodel_name="pms.room.type.availability.rule",
+ inverse_name="availability_id",
+ string="Rule Items",
+ copy=True,
+ )
+
+ active = fields.Boolean(
+ string="Active",
+ default=True,
+ help="If unchecked, it will allow you to hide the "
+ "Availability plan without removing it.",
+ )
# Business Methods
+ @classmethod
+ def any_rule_applies(cls, checkin, checkout, item):
+ reservation_len = (checkout - checkin).days
+ return any(
+ [
+ (0 < item.max_stay < reservation_len),
+ (0 < item.min_stay > reservation_len),
+ (0 < item.max_stay_arrival < reservation_len and checkin == item.date),
+ (0 < item.min_stay_arrival > reservation_len and checkin == item.date),
+ item.closed,
+ (item.closed_arrival and checkin == item.date),
+ (item.closed_departure and checkout == item.date),
+ (item.quota == 0 or item.max_avail == 0),
+ ]
+ )
+
@api.model
def rooms_available(
- self, checkin, checkout, room_type_id=False, current_lines=False
+ self,
+ checkin,
+ checkout,
+ room_type_id=False,
+ current_lines=False,
+ pricelist=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
+ if current_lines and not isinstance(current_lines, list):
+ current_lines = [current_lines]
+
+ rooms_not_avail = (
+ self.env["pms.reservation.line"]
+ .search(
+ [
+ ("date", ">=", checkin),
+ ("date", "<=", checkout - datetime.timedelta(1)),
+ ("occupies_availability", "=", True),
+ ("id", "not in", current_lines if current_lines else []),
+ ]
)
- free_rooms = free_rooms & rooms_linked
+ .mapped("room_id.id")
+ )
+
+ domain_rooms = [
+ ("id", "not in", rooms_not_avail if len(rooms_not_avail) > 0 else [])
+ ]
+ domain_rules = [
+ ("date", ">=", checkin),
+ ("date", "<=", checkout),
+ ]
+
+ if room_type_id:
+ domain_rooms.append(("room_type_id", "=", room_type_id))
+ domain_rules.append(("room_type_id", "=", room_type_id))
+
+ free_rooms = self.env["pms.room"].search(domain_rooms)
+
+ if pricelist:
+ domain_rules.append(("availability_id.pms_pricelist_ids", "=", pricelist))
+ rule_items = self.env["pms.room.type.availability.rule"].search(
+ domain_rules
+ )
+
+ if len(rule_items) > 0:
+ room_types_to_remove = []
+ for item in rule_items:
+ if self.any_rule_applies(checkin, checkout, item):
+ room_types_to_remove.append(item.room_type_id.id)
+ free_rooms = free_rooms.filtered(
+ lambda x: x.room_type_id.id not in room_types_to_remove
+ )
+
return free_rooms.sorted(key=lambda r: r.sequence)
@api.model
- def _get_domain_reservations_occupation(self, dfrom, dto, current_lines=False):
- if current_lines and not isinstance(current_lines, list):
- current_lines = [current_lines]
- domain = [
- ("date", ">=", dfrom),
- ("date", "<=", dto),
- ("occupies_availability", "=", True),
- ("id", "not in", current_lines),
- ]
- return domain
+ def splitted_availability(
+ self,
+ checkin,
+ checkout,
+ room_type_id=False,
+ current_lines=False,
+ pricelist=False,
+ ):
+ for date_iterator in [
+ checkin + datetime.timedelta(days=x)
+ for x in range(0, (checkout - checkin).days)
+ ]:
+ rooms_avail = self.rooms_available(
+ checkin=date_iterator,
+ checkout=date_iterator + datetime.timedelta(1),
+ room_type_id=room_type_id,
+ current_lines=current_lines,
+ pricelist=pricelist.id,
+ )
+ if len(rooms_avail) < 1:
+ return False
+ return True
+
+ @api.model
+ def update_quota(self, pricelist_id, room_type_id, date, line):
+ if pricelist_id and room_type_id and date:
+ rule = self.env["pms.room.type.availability.rule"].search(
+ [
+ ("availability_id.pms_pricelist_ids", "=", pricelist_id.id),
+ ("room_type_id", "=", room_type_id.id),
+ ("date", "=", date),
+ ]
+ )
+ # applies a rule
+ if rule:
+ rule.ensure_one()
+ if rule and rule.quota != -1 and rule.quota > 0:
+
+ # the line has no rule item applied before
+ if not line.impacts_quota:
+ rule.quota -= 1
+ return rule.id
+
+ # the line has a rule item applied before
+ elif line.impacts_quota != rule.id:
+
+ # decrement quota on current rule item
+ rule.quota -= 1
+
+ # check old rule item
+ old_rule = self.env["pms.room.type.availability.rule"].search(
+ [("id", "=", line.impacts_quota)]
+ )
+
+ # restore quota in old rule item
+ if old_rule:
+ old_rule.quota += 1
+
+ return rule.id
+
+ # in any case, check old rule item
+ if line.impacts_quota:
+ old_rule = self.env["pms.room.type.availability.rule"].search(
+ [("id", "=", line.impacts_quota)]
+ )
+ # and restore quota in old rule item
+ if old_rule:
+ old_rule.quota += 1
+
+ return False
diff --git a/pms/models/pms_room_type_restriction_item.py b/pms/models/pms_room_type_availability_rule.py
similarity index 89%
rename from pms/models/pms_room_type_restriction_item.py
rename to pms/models/pms_room_type_availability_rule.py
index 35b4cb34c..d2a59f842 100644
--- a/pms/models/pms_room_type_restriction_item.py
+++ b/pms/models/pms_room_type_availability_rule.py
@@ -4,15 +4,15 @@ from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
-class PmsRoomTypeRestrictionItem(models.Model):
- _name = "pms.room.type.restriction.item"
- _description = "Reservation restriction by day"
+class PmsRoomTypeAvailabilityRule(models.Model):
+ _name = "pms.room.type.availability.rule"
+ _description = "Reservation rule by day"
# Field Declarations
- restriction_id = fields.Many2one(
- comodel_name="pms.room.type.restriction",
- string="Restriction Plan",
+ availability_id = fields.Many2one(
+ comodel_name="pms.room.type.availability",
+ string="Availability Plan",
ondelete="cascade",
index=True,
)
@@ -71,8 +71,8 @@ class PmsRoomTypeRestrictionItem(models.Model):
_sql_constraints = [
(
"room_type_registry_unique",
- "unique(restriction_id, room_type_id, date)",
- "Only can exists one restriction in the same \
+ "unique(availability_id, room_type_id, date)",
+ "Only can exists one availability rule in the same \
day for the same room type!",
)
]
diff --git a/pms/models/pms_room_type_restriction.py b/pms/models/pms_room_type_restriction.py
deleted file mode 100644
index 5f3e45bfd..000000000
--- a/pms/models/pms_room_type_restriction.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# Copyright 2017 Alexandre Díaz
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-import datetime
-
-from odoo import api, fields, models
-
-
-class PmsRoomTypeRestriction(models.Model):
- """The room type restriction is used as a daily restriction plan for room types
- and therefore is related only with one property."""
-
- _name = "pms.room.type.restriction"
- _description = "Reservation restriction plan"
-
- # Default methods
- @api.model
- def _get_default_pms_property(self):
- return self.env.user.pms_property_id or None
-
- # Fields declaration
- name = fields.Char("Restriction Plan Name", required=True)
- pms_property_id = fields.Many2one(
- comodel_name="pms.property",
- string="Property",
- ondelete="restrict",
- )
-
- pms_pricelist_ids = fields.One2many(
- comodel_name="product.pricelist",
- inverse_name="restriction_id",
- string="Pricelists",
- required=False,
- ondelete="restrict",
- )
-
- item_ids = fields.One2many(
- comodel_name="pms.room.type.restriction.item",
- inverse_name="restriction_id",
- string="Restriction Items",
- copy=True,
- )
-
- active = fields.Boolean(
- string="Active",
- default=True,
- help="If unchecked, it will allow you to hide the "
- "restriction plan without removing it.",
- )
-
- # Business Methods
- @classmethod
- def any_restriction_applies(cls, checkin, checkout, item):
- reservation_len = (checkout - checkin).days
- return any(
- [
- (0 < item.max_stay < reservation_len),
- (0 < item.min_stay > reservation_len),
- (0 < item.max_stay_arrival < reservation_len and checkin == item.date),
- (0 < item.min_stay_arrival > reservation_len and checkin == item.date),
- item.closed,
- (item.closed_arrival and checkin == item.date),
- (item.closed_departure and checkout == item.date),
- (item.quota == 0 or item.max_avail == 0),
- ]
- )
-
- @api.model
- def rooms_available(
- self,
- checkin,
- checkout,
- room_type_id=False,
- current_lines=False,
- pricelist=False,
- ):
- if current_lines and not isinstance(current_lines, list):
- current_lines = [current_lines]
-
- rooms_not_avail = (
- self.env["pms.reservation.line"]
- .search(
- [
- ("date", ">=", checkin),
- ("date", "<=", checkout - datetime.timedelta(1)),
- ("occupies_availability", "=", True),
- ("id", "not in", current_lines if current_lines else []),
- ]
- )
- .mapped("room_id.id")
- )
-
- domain_rooms = [
- ("id", "not in", rooms_not_avail if len(rooms_not_avail) > 0 else [])
- ]
- domain_restrictions = [
- ("date", ">=", checkin),
- ("date", "<=", checkout),
- ]
-
- if room_type_id:
- domain_rooms.append(("room_type_id", "=", room_type_id))
- domain_restrictions.append(("room_type_id", "=", room_type_id))
-
- free_rooms = self.env["pms.room"].search(domain_rooms)
-
- if pricelist:
- domain_restrictions.append(
- ("restriction_id.pms_pricelist_ids", "=", pricelist)
- )
- restriction_items = self.env["pms.room.type.restriction.item"].search(
- domain_restrictions
- )
-
- if len(restriction_items) > 0:
- room_types_to_remove = []
- for item in restriction_items:
- if self.any_restriction_applies(checkin, checkout, item):
- room_types_to_remove.append(item.room_type_id.id)
- free_rooms = free_rooms.filtered(
- lambda x: x.room_type_id.id not in room_types_to_remove
- )
-
- return free_rooms.sorted(key=lambda r: r.sequence)
-
- @api.model
- def splitted_availability(
- self,
- checkin,
- checkout,
- room_type_id=False,
- current_lines=False,
- pricelist=False,
- ):
- for date_iterator in [
- checkin + datetime.timedelta(days=x)
- for x in range(0, (checkout - checkin).days)
- ]:
- rooms_avail = self.rooms_available(
- checkin=date_iterator,
- checkout=date_iterator + datetime.timedelta(1),
- room_type_id=room_type_id,
- current_lines=current_lines,
- pricelist=pricelist.id,
- )
- if len(rooms_avail) < 1:
- return False
- return True
-
- @api.model
- def update_quota(self, pricelist_id, room_type_id, date, line):
- if pricelist_id and room_type_id and date:
- restriction = self.env["pms.room.type.restriction.item"].search(
- [
- ("restriction_id.pms_pricelist_ids", "=", pricelist_id.id),
- ("room_type_id", "=", room_type_id.id),
- ("date", "=", date),
- ]
- )
- # applies a restriction
- if restriction:
- restriction.ensure_one()
- if restriction and restriction.quota != -1 and restriction.quota > 0:
-
- # the line has no restriction item applied before
- if not line.impacts_quota:
- restriction.quota -= 1
- return restriction.id
-
- # the line has a restriction item applied before
- elif line.impacts_quota != restriction.id:
-
- # decrement quota on current restriction_item
- restriction.quota -= 1
-
- # check old restricition item
- old_restriction = self.env[
- "pms.room.type.restriction.item"
- ].search([("id", "=", line.impacts_quota)])
-
- # restore quota in old restriction item
- if old_restriction:
- old_restriction.quota += 1
-
- return restriction.id
-
- # in any case, check old restricition item
- if line.impacts_quota:
- old_restriction = self.env["pms.room.type.restriction.item"].search(
- [("id", "=", line.impacts_quota)]
- )
- # and restore quota in old restriction item
- if old_restriction:
- old_restriction.quota += 1
-
- return False
diff --git a/pms/models/product_pricelist.py b/pms/models/product_pricelist.py
index ab19b1ae3..fa9772844 100644
--- a/pms/models/product_pricelist.py
+++ b/pms/models/product_pricelist.py
@@ -22,9 +22,9 @@ class ProductPricelist(models.Model):
[("daily", "Daily Plan")], string="Pricelist Type", default="daily"
)
- restriction_id = fields.Many2one(
- comodel_name="pms.room.type.restriction",
- string="restriction",
+ availability_id = fields.Many2one(
+ comodel_name="pms.room.type.availability",
+ string="Availability Plan",
ondelete="restrict",
)
diff --git a/pms/readme/DESCRIPTION.rst b/pms/readme/DESCRIPTION.rst
index 5f6c71a7c..182da89bd 100644
--- a/pms/readme/DESCRIPTION.rst
+++ b/pms/readme/DESCRIPTION.rst
@@ -2,4 +2,4 @@ This module is an all-in-one property management system (PMS) focused on medium-
for managing every aspect of your property's daily operations.
You can manage hotel properties with multi-hotel and multi-company support, including your rooms inventory,
-reservations, check-in, daily reports, board services, rate and restriction plans among other hotel functionalities.
+reservations, check-in, daily reports, board services, rate and availability plans among other hotel functionalities.
diff --git a/pms/security/ir.model.access.csv b/pms/security/ir.model.access.csv
index 2ebaf1009..2305368a7 100644
--- a/pms/security/ir.model.access.csv
+++ b/pms/security/ir.model.access.csv
@@ -3,7 +3,6 @@ user_access_pms_floor,user_access_pms_floor,model_pms_floor,pms.group_pms_user,1
user_access_pms_amenity,user_access_pms_amenity,model_pms_amenity,pms.group_pms_user,1,0,0,0
user_access_pms_amenity_type,user_access_pms_amenity_type,model_pms_amenity_type,pms.group_pms_user,1,0,0,0
user_access_pms_service,user_access_pms_service,model_pms_service,pms.group_pms_user,1,1,1,1
-user_access_pms_room_type_restriction,user_access_pms_room_type_restriction,model_pms_room_type_restriction,pms.group_pms_user,1,0,0,0
user_access_pms_reservation_line,user_access_pms_reservation_line,model_pms_reservation_line,pms.group_pms_user,1,1,1,1
user_access_room_closure_reason,user_access_room_closure_reason,model_room_closure_reason,pms.group_pms_user,1,0,0,0
user_access_pms_service_line,user_access_pms_service_line,model_pms_service_line,pms.group_pms_user,1,1,1,1
@@ -12,7 +11,7 @@ user_access_pms_checkin_partner,user_access_pms_checkin_partner,model_pms_checki
user_access_pms_room_type_class,user_access_pms_room_type_class,model_pms_room_type_class,pms.group_pms_user,1,0,0,0
user_access_pms_room,user_access_pms_room,model_pms_room,pms.group_pms_user,1,0,0,0
user_access_shared_pms_room,user_access_pms_shared_room,model_pms_shared_room,pms.group_pms_user,1,0,0,0
-user_access_pms_room_type_restriction_item,user_access_pms_room_type_restriction_item,model_pms_room_type_restriction_item,pms.group_pms_user,1,0,0,0
+user_access_pms_room_type_availability_rule,user_access_pms_room_type_availability_rule,model_pms_room_type_availability_rule,pms.group_pms_user,1,0,0,0
user_access_pms_reservation,user_access_pms_reservation,model_pms_reservation,pms.group_pms_user,1,1,1,1
user_access_pms_folio,user_access_pms_folio,model_pms_folio,pms.group_pms_user,1,1,1,1
user_access_pms_room_type,user_access_pms_room_type,model_pms_room_type,pms.group_pms_user,1,0,0,0
@@ -29,7 +28,6 @@ manager_access_pms_floor,manager_access_pms_floor,model_pms_floor,pms.group_pms_
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
manager_access_pms_service,manager_access_pms_service,model_pms_service,pms.group_pms_manager,1,1,1,1
-manager_access_pms_room_type_restriction,manager_access_pms_room_type_restriction,model_pms_room_type_restriction,pms.group_pms_manager,1,1,1,1
manager_access_pms_reservation_line,manager_access_pms_reservation_line,model_pms_reservation_line,pms.group_pms_manager,1,1,1,1
manager_access_room_closure_reason,manager_access_room_closure_reason,model_room_closure_reason,pms.group_pms_manager,1,1,1,1
manager_access_pms_service_line,manager_access_pms_service_line,model_pms_service_line,pms.group_pms_manager,1,1,1,1
@@ -38,7 +36,7 @@ manager_access_pms_checkin_partner,manager_access_pms_checkin_partner,model_pms_
manager_access_pms_room_type_class,manager_access_pms_room_type_class,model_pms_room_type_class,pms.group_pms_manager,1,1,1,1
manager_access_pms_room,manager_access_pms_room,model_pms_room,pms.group_pms_manager,1,1,1,1
manager_access_pms_shared_room,manager_access_pms_shared_room,model_pms_shared_room,pms.group_pms_manager,1,1,1,1
-manager_access_pms_room_type_restriction_item,manager_access_pms_room_type_restriction_item,model_pms_room_type_restriction_item,pms.group_pms_manager,1,1,1,1
+manager_access_pms_room_type_availability_rule,manager_access_pms_room_type_availability_rule,model_pms_room_type_availability_rule,pms.group_pms_manager,1,1,1,1
manager_access_pms_reservation,manager_access_pms_reservation,model_pms_reservation,pms.group_pms_manager,1,1,1,1
manager_access_pms_folio,manager_access_pms_folio,model_pms_folio,pms.group_pms_manager,1,1,1,1
manager_access_pms_room_type,manager_access_pms_room_type,model_pms_room_type,pms.group_pms_manager,1,1,1,1
diff --git a/pms/static/description/index.html b/pms/static/description/index.html
index 1fab55358..e93131820 100644
--- a/pms/static/description/index.html
+++ b/pms/static/description/index.html
@@ -371,7 +371,7 @@ ul.auto-toc {
This module is an all-in-one property management system (PMS) focused on medium-sized hotels
for managing every aspect of your property’s daily operations.
You can manage hotel properties with multi-hotel and multi-company support, including your rooms inventory,
-reservations, check-in, daily reports, board services, rate and restriction plans among other hotel functionalities.
+reservations, check-in, daily reports, board services, rate and availability plans among other hotel functionalities.
Important
This is an alpha version, the data model and design can change at any time without warning.
diff --git a/pms/tests/__init__.py b/pms/tests/__init__.py
index 63b77ba65..00f69c03e 100644
--- a/pms/tests/__init__.py
+++ b/pms/tests/__init__.py
@@ -25,4 +25,4 @@ from . import test_pms_pricelist_priority
from . import test_pms_checkin_partner
from . import test_pms_sale_channel
from . import test_pms_folio
-from . import test_pms_room_type_restriction
+from . import test_pms_room_type_availability_rules
diff --git a/pms/tests/test_pms_pricelist_priority.py b/pms/tests/test_pms_pricelist_priority.py
index 1b9442354..58daf1380 100644
--- a/pms/tests/test_pms_pricelist_priority.py
+++ b/pms/tests/test_pms_pricelist_priority.py
@@ -15,19 +15,19 @@ class TestPmsPricelistRules(common.TransactionCase):
{"name": "Category1"}
)
- self.restriction = self.env["pms.room.type.restriction"].create(
- {"name": "Restriction1"}
+ self.availability = self.env["pms.room.type.availability"].create(
+ {"name": "Availability 1"}
)
- self.restriction2 = self.env["pms.room.type.restriction"].create(
- {"name": "Restriction2"}
+ self.availability2 = self.env["pms.room.type.availability"].create(
+ {"name": "Availability"}
)
self.property1 = self.env["pms.property"].create(
{
"name": "Property_1",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.env.ref("product.list0").id,
- "default_restriction_id": self.restriction.id,
+ "default_availability_id": self.availability.id,
}
)
@@ -36,7 +36,7 @@ class TestPmsPricelistRules(common.TransactionCase):
"name": "Property_2",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.env.ref("product.list0").id,
- "default_restriction_id": self.restriction2.id,
+ "default_availability_id": self.availability2.id,
}
)
diff --git a/pms/tests/test_pms_reservation.py b/pms/tests/test_pms_reservation.py
index cd2bdde9d..9997d616f 100644
--- a/pms/tests/test_pms_reservation.py
+++ b/pms/tests/test_pms_reservation.py
@@ -11,9 +11,9 @@ from .common import TestHotel
@freeze_time("2012-01-14")
class TestPmsReservations(TestHotel):
def create_common_scenario(self):
- # create a room type restriction
- self.room_type_restriction = self.env["pms.room.type.restriction"].create(
- {"name": "Restriction plan for TEST"}
+ # create a room type availability
+ self.room_type_availability = self.env["pms.room.type.availability"].create(
+ {"name": "Availability plan for TEST"}
)
# create a property
@@ -22,7 +22,7 @@ class TestPmsReservations(TestHotel):
"name": "MY PMS TEST",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.env.ref("product.list0").id,
- "default_restriction_id": self.room_type_restriction.id,
+ "default_availability_id": self.room_type_availability.id,
}
)
diff --git a/pms/tests/test_pms_room_type_restriction.py b/pms/tests/test_pms_room_type_availability_rules.py
similarity index 83%
rename from pms/tests/test_pms_room_type_restriction.py
rename to pms/tests/test_pms_room_type_availability_rules.py
index 6203c1e44..75c6350ad 100644
--- a/pms/tests/test_pms_room_type_restriction.py
+++ b/pms/tests/test_pms_room_type_availability_rules.py
@@ -10,7 +10,7 @@ from .common import TestHotel
@freeze_time("1980-01-01")
-class TestPmsRoomTypeRestriction(TestHotel):
+class TestPmsRoomTypeAvailabilityRules(TestHotel):
def create_common_scenario(self):
# product.pricelist
self.test_pricelist1 = self.env["product.pricelist"].create(
@@ -18,10 +18,12 @@ class TestPmsRoomTypeRestriction(TestHotel):
"name": "test pricelist 1",
}
)
- # pms.room.type.restriction
- self.test_room_type_restriction1 = self.env["pms.room.type.restriction"].create(
+ # pms.room.type.availability
+ self.test_room_type_availability1 = self.env[
+ "pms.room.type.availability"
+ ].create(
{
- "name": "Restriction plan for TEST",
+ "name": "Availability plan for TEST",
"pms_pricelist_ids": [(6, 0, [self.test_pricelist1.id])],
}
)
@@ -31,7 +33,7 @@ class TestPmsRoomTypeRestriction(TestHotel):
"name": "MY PMS TEST",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.test_pricelist1.id,
- "default_restriction_id": self.test_room_type_restriction1.id,
+ "default_availability_id": self.test_room_type_availability1.id,
}
)
# pms.room.type.class
@@ -115,7 +117,7 @@ class TestPmsRoomTypeRestriction(TestHotel):
@Skip
def test_availability_rooms_all(self):
# TEST CASE
- # get availability withouth restrictions
+ # get availability withouth rules
# ARRANGE
self.create_common_scenario()
@@ -127,7 +129,7 @@ class TestPmsRoomTypeRestriction(TestHotel):
)
# ACT
- result = self.env["pms.room.type.restriction"].rooms_available(
+ result = self.env["pms.room.type.availability"].rooms_available(
checkin=checkin,
checkout=checkout,
)
@@ -136,13 +138,13 @@ class TestPmsRoomTypeRestriction(TestHotel):
self.assertTrue(
obtained,
"Availability should contain the test rooms"
- "because there's no restriction for them.",
+ "because there's no availability rules for them.",
)
@Skip
def test_availability_rooms_all_lines(self):
# TEST CASE
- # get availability withouth restrictions
+ # get availability withouth rules
# given reservation lines to not consider
# ARRANGE
@@ -161,7 +163,7 @@ class TestPmsRoomTypeRestriction(TestHotel):
)
# ACT
- result = self.env["pms.room.type.restriction"].rooms_available(
+ result = self.env["pms.room.type.availability"].rooms_available(
checkin=checkin,
checkout=checkout,
current_lines=test_reservation.reservation_line_ids.ids,
@@ -171,13 +173,13 @@ class TestPmsRoomTypeRestriction(TestHotel):
self.assertTrue(
obtained,
"Availability should contain the test rooms"
- "because there's no restriction for them.",
+ "because there's no availability rules for them.",
)
@Skip
def test_availability_rooms_room_type(self):
# TEST CASE
- # get availability withouth restrictions
+ # get availability withouth rules
# given a room type
# ARRANGE
@@ -190,7 +192,7 @@ class TestPmsRoomTypeRestriction(TestHotel):
)
# ACT
- result = self.env["pms.room.type.restriction"].rooms_available(
+ result = self.env["pms.room.type.availability"].rooms_available(
checkin=fields.date.today(),
checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(),
room_type_id=self.test_room_type_double.id,
@@ -201,30 +203,31 @@ class TestPmsRoomTypeRestriction(TestHotel):
self.assertTrue(
obtained,
"Availability should contain the test rooms"
- "because there's no restriction for them.",
+ "because there's no availability rules for them.",
)
@Skip
def test_availability_closed_no_room_type(self):
# TEST CASE:
# coverage for 2 points:
- # 1. without room type, restrictions associated with the pricelist are applied
- # 2. restriction rule "closed" is taken into account
+ # 1. without room type, availability rules associated
+ # with the pricelist are applied
+ # 2. availability rule "closed" is taken into account
# ARRANGE
self.create_common_scenario()
- self.test_room_type_restriction1_item1 = self.env[
- "pms.room.type.restriction.item"
+ self.test_room_type_availability1_item1 = self.env[
+ "pms.room.type.availability.rule"
].create(
{
- "restriction_id": self.test_room_type_restriction1.id,
+ "availability_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": (fields.datetime.today() + datetime.timedelta(days=2)).date(),
"closed": True, # <- (1/2)
}
)
# ACT
- result = self.env["pms.room.type.restriction"].rooms_available(
+ result = self.env["pms.room.type.availability"].rooms_available(
checkin=fields.date.today(),
checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(),
# room_type_id=False, # <- (2/2)
@@ -235,24 +238,24 @@ class TestPmsRoomTypeRestriction(TestHotel):
self.test_room_type_double,
result.mapped("room_type_id"),
"Availability should not contain rooms of a type "
- "which its restriction rules applies",
+ "which its availability rules applies",
)
@Skip
- def test_availability_restrictions(self):
+ def test_availability_rules(self):
# TEST CASE
- # the availability should take into acount restriction rules:
+ # the availability should take into acount availability rules:
# closed_arrival, closed_departure, min_stay, max_stay,
# min_stay_arrival, max_stay_arrival
# ARRANGE
self.create_common_scenario()
- self.test_room_type_restriction1_item1 = self.env[
- "pms.room.type.restriction.item"
+ self.test_room_type_availability1_item1 = self.env[
+ "pms.room.type.availability.rule"
].create(
{
- "restriction_id": self.test_room_type_restriction1.id,
+ "availability_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": (fields.datetime.today() + datetime.timedelta(days=0)).date(),
}
@@ -364,9 +367,9 @@ class TestPmsRoomTypeRestriction(TestHotel):
with self.subTest(k=test_case):
# ACT
- self.test_room_type_restriction1_item1.write(test_case)
+ self.test_room_type_availability1_item1.write(test_case)
- result = self.env["pms.room.type.restriction"].rooms_available(
+ result = self.env["pms.room.type.availability"].rooms_available(
checkin=checkin,
checkout=checkout,
room_type_id=self.test_room_type_double.id,
@@ -378,23 +381,23 @@ class TestPmsRoomTypeRestriction(TestHotel):
self.test_room_type_double,
result.mapped("room_type_id"),
"Availability should not contain rooms of a type "
- "which its restriction rules applies",
+ "which its availability rules applies",
)
@Skip
@freeze_time("1980-11-01")
- def test_restriction_on_create_reservation(self):
+ def test_rule_on_create_reservation(self):
# TEST CASE
- # a restriction should be applied that would prevent the
+ # an availability rule should be applied that would prevent the
# creation of reservations
# ARRANGE
self.create_common_scenario()
- self.test_room_type_restriction1_item1 = self.env[
- "pms.room.type.restriction.item"
+ self.test_room_type_availability1_item1 = self.env[
+ "pms.room.type.availability.rule"
].create(
{
- "restriction_id": self.test_room_type_restriction1.id,
+ "availability_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": (fields.datetime.today() + datetime.timedelta(days=2)).date(),
"closed": True,
@@ -407,7 +410,7 @@ class TestPmsRoomTypeRestriction(TestHotel):
# ACT & ASSERT
with self.assertRaises(
ValidationError,
- msg="Restriction should be applied that would"
+ msg="Availability rules should be applied that would"
" prevent the creation of the reservation.",
):
self.env["pms.reservation"].create(
@@ -423,18 +426,18 @@ class TestPmsRoomTypeRestriction(TestHotel):
@Skip
@freeze_time("1980-11-01")
- def test_restriction_on_create_splitted_reservation(self):
+ def test_rules_on_create_splitted_reservation(self):
# TEST CASE
- # a restriction should be applied that would prevent the
+ # an availability rule should be applied that would prevent the
# creation of reservations including splitted reservations.
# ARRANGE
self.create_common_scenario()
- self.test_room_type_restriction1_item1 = self.env[
- "pms.room.type.restriction.item"
+ self.test_room_type_availability1_item1 = self.env[
+ "pms.room.type.availability.rule"
].create(
{
- "restriction_id": self.test_room_type_restriction1.id,
+ "availability_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": (fields.datetime.today() + datetime.timedelta(days=2)).date(),
"closed": True,
@@ -469,7 +472,7 @@ class TestPmsRoomTypeRestriction(TestHotel):
# ACT & ASSERT
with self.assertRaises(
ValidationError,
- msg="Restriction should be applied that would"
+ msg="Availability rule should be applied that would"
" prevent the creation of splitted reservation.",
):
self.env["pms.reservation"].create(
@@ -485,19 +488,19 @@ class TestPmsRoomTypeRestriction(TestHotel):
@Skip
@freeze_time("1980-11-01")
- def test_restriction_update_quota_on_create_reservation(self):
+ def test_rule_update_quota_on_create_reservation(self):
# TEST CASE
# quota rule is changed after creating a reservation
- # with pricelist linked to a restriction_item that applies
+ # with pricelist linked to a availability plan that applies
# ARRANGE
self.create_common_scenario()
- self.test_room_type_restriction1_item1 = self.env[
- "pms.room.type.restriction.item"
+ self.test_room_type_availability1_item1 = self.env[
+ "pms.room.type.availability.rule"
].create(
{
- "restriction_id": self.test_room_type_restriction1.id,
+ "availability_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": datetime.date.today(),
"quota": 1,
@@ -530,12 +533,12 @@ class TestPmsRoomTypeRestriction(TestHotel):
)
@freeze_time("1980-11-01")
- def test_restriction_update_quota_on_update_reservation(self):
+ def test_rule_update_quota_on_update_reservation(self):
# TEST CASE
# quota rule is restored after creating a reservation
- # with pricelist linked to a restriction_item that applies
+ # with pricelist linked to a availability rule that applies
# and then modify the pricelist of the reservation and
- # no restriction applies
+ # no rules applies
# ARRANGE
self.create_common_scenario()
@@ -545,9 +548,9 @@ class TestPmsRoomTypeRestriction(TestHotel):
"name": "test pricelist 2",
}
)
- restriction = self.env["pms.room.type.restriction.item"].create(
+ rule = self.env["pms.room.type.availability.rule"].create(
{
- "restriction_id": self.test_room_type_restriction1.id,
+ "availability_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": datetime.date.today(),
"quota": test_quota,
@@ -569,6 +572,6 @@ class TestPmsRoomTypeRestriction(TestHotel):
reservation.flush()
self.assertEqual(
test_quota,
- restriction.quota,
+ rule.quota,
"The quota should be restored after changing the reservation's pricelist",
)
diff --git a/pms/views/pms_property_views.xml b/pms/views/pms_property_views.xml
index e807628ff..3d52280f3 100644
--- a/pms/views/pms_property_views.xml
+++ b/pms/views/pms_property_views.xml
@@ -21,10 +21,10 @@
-
+
diff --git a/pms/views/pms_room_type_restriction_item_views.xml b/pms/views/pms_room_type_availability_rule_views.xml
similarity index 71%
rename from pms/views/pms_room_type_restriction_item_views.xml
rename to pms/views/pms_room_type_availability_rule_views.xml
index da21474cb..7e2f1b64d 100644
--- a/pms/views/pms_room_type_restriction_item_views.xml
+++ b/pms/views/pms_room_type_availability_rule_views.xml
@@ -1,10 +1,10 @@
-
- pms.room.type.restriction.item.form
- pms.room.type.restriction.item
+
+ pms.room.type.availability.rule.form
+ pms.room.type.availability.rule
-
-
- pms.room.type.restriction.item.tree
- pms.room.type.restriction.item
+
+ pms.room.type.availability.rule.tree
+ pms.room.type.availability.rule
-
+
diff --git a/pms/views/pms_room_type_restriction_views.xml b/pms/views/pms_room_type_availability_views.xml
similarity index 69%
rename from pms/views/pms_room_type_restriction_views.xml
rename to pms/views/pms_room_type_availability_views.xml
index c9cbbbf78..1bf9b7c85 100644
--- a/pms/views/pms_room_type_restriction_views.xml
+++ b/pms/views/pms_room_type_availability_views.xml
@@ -1,10 +1,10 @@
-
- pms.room.type.restriction.form
- pms.room.type.restriction
+
+ pms.room.type.availability.form
+ pms.room.type.availability
-