mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[IMP]pms: Changes in staff and out type reservations
This commit is contained in:
@@ -604,16 +604,20 @@ class PmsFolio(models.Model):
|
||||
)
|
||||
def _compute_sale_line_ids(self):
|
||||
for folio in self:
|
||||
for reservation in folio.reservation_ids:
|
||||
# RESERVATION LINES
|
||||
# res = self.env['pms.reservation'].browse(reservation.id)
|
||||
self.generate_reservation_lines_sale_lines(folio, reservation)
|
||||
if folio.reservation_type == "normal":
|
||||
for reservation in folio.reservation_ids:
|
||||
# RESERVATION LINES
|
||||
# res = self.env['pms.reservation'].browse(reservation.id)
|
||||
self.generate_reservation_lines_sale_lines(folio, reservation)
|
||||
|
||||
# RESERVATION SERVICES
|
||||
self.generate_reservation_services_sale_lines(folio, reservation)
|
||||
# RESERVATION SERVICES
|
||||
self.generate_reservation_services_sale_lines(folio, reservation)
|
||||
|
||||
# FOLIO SERVICES
|
||||
self.generate_folio_services_sale_lines(folio)
|
||||
# FOLIO SERVICES
|
||||
self.generate_folio_services_sale_lines(folio)
|
||||
else:
|
||||
for reservation in folio.reservation_ids:
|
||||
reservation.sale_line_ids = False
|
||||
|
||||
@api.depends("pms_property_id")
|
||||
def _compute_company_id(self):
|
||||
@@ -765,7 +769,7 @@ class PmsFolio(models.Model):
|
||||
else:
|
||||
order.invoice_status = "no"
|
||||
|
||||
@api.depends("partner_id", "partner_id.name", "agency_id")
|
||||
@api.depends("partner_id", "partner_id.name", "agency_id", "reservation_type")
|
||||
def _compute_partner_name(self):
|
||||
for record in self:
|
||||
self._apply_partner_name(record)
|
||||
@@ -841,22 +845,24 @@ class PmsFolio(models.Model):
|
||||
@api.depends("checkin_partner_ids", "checkin_partner_ids.state")
|
||||
def _compute_pending_checkin_data(self):
|
||||
for folio in self:
|
||||
folio.pending_checkin_data = len(
|
||||
folio.checkin_partner_ids.filtered(lambda c: c.state == "draft")
|
||||
)
|
||||
if folio.reservation_type != "out":
|
||||
folio.pending_checkin_data = len(
|
||||
folio.checkin_partner_ids.filtered(lambda c: c.state == "draft")
|
||||
)
|
||||
|
||||
@api.depends("pending_checkin_data")
|
||||
def _compute_ratio_checkin_data(self):
|
||||
self.ratio_checkin_data = 0
|
||||
for folio in self.filtered("reservation_ids"):
|
||||
folio.ratio_checkin_data = (
|
||||
(
|
||||
sum(folio.reservation_ids.mapped("adults"))
|
||||
- folio.pending_checkin_data
|
||||
if folio.reservation_type != "out":
|
||||
folio.ratio_checkin_data = (
|
||||
(
|
||||
sum(folio.reservation_ids.mapped("adults"))
|
||||
- folio.pending_checkin_data
|
||||
)
|
||||
* 100
|
||||
/ sum(folio.reservation_ids.mapped("adults"))
|
||||
)
|
||||
* 100
|
||||
/ sum(folio.reservation_ids.mapped("adults"))
|
||||
)
|
||||
|
||||
# TODO: Add return_ids to depends
|
||||
@api.depends(
|
||||
@@ -871,7 +877,9 @@ class PmsFolio(models.Model):
|
||||
def _compute_amount(self):
|
||||
for record in self:
|
||||
if record.reservation_type in ("staff", "out"):
|
||||
record.amount_total = 0
|
||||
vals = {
|
||||
"payment_state": False,
|
||||
"pending_amount": 0,
|
||||
"invoices_paid": 0,
|
||||
}
|
||||
|
||||
@@ -867,7 +867,7 @@ class PmsReservation(models.Model):
|
||||
for reservation in self:
|
||||
if reservation.reservation_type in ("out", "staff"):
|
||||
reservation.pricelist_id = False
|
||||
if reservation.agency_id and reservation.agency_id.apply_pricelist:
|
||||
elif reservation.agency_id and reservation.agency_id.apply_pricelist:
|
||||
reservation.pricelist_id = (
|
||||
reservation.agency_id.property_product_pricelist
|
||||
)
|
||||
@@ -986,7 +986,8 @@ class PmsReservation(models.Model):
|
||||
record.allowed_checkin = (
|
||||
True
|
||||
if (
|
||||
record.state in ["draft", "confirm", "arrival_delayed"]
|
||||
record.reservation_type != "out"
|
||||
and record.state in ["draft", "confirm", "arrival_delayed"]
|
||||
and record.checkin <= fields.Date.today()
|
||||
)
|
||||
else False
|
||||
@@ -1133,13 +1134,13 @@ class PmsReservation(models.Model):
|
||||
reservation.commission_amount = 0
|
||||
|
||||
# REVIEW: Dont run with set room_type_id -> room_id(compute)-> No set adults¿?
|
||||
@api.depends("preferred_room_id")
|
||||
@api.depends("preferred_room_id", "reservation_type")
|
||||
def _compute_adults(self):
|
||||
for reservation in self:
|
||||
if reservation.preferred_room_id:
|
||||
if reservation.preferred_room_id and reservation.reservation_type != "out":
|
||||
if reservation.adults == 0:
|
||||
reservation.adults = reservation.preferred_room_id.capacity
|
||||
elif not reservation.adults:
|
||||
elif not reservation.adults or reservation.reservation_type == "out":
|
||||
reservation.adults = 0
|
||||
|
||||
@api.depends("reservation_line_ids", "reservation_line_ids.room_id")
|
||||
@@ -1177,6 +1178,8 @@ class PmsReservation(models.Model):
|
||||
line.invoice_status = "no"
|
||||
else:
|
||||
line.invoice_status = "no"
|
||||
if line.reservation_type != "normal":
|
||||
line.invoice_status = "no"
|
||||
|
||||
@api.depends("reservation_line_ids")
|
||||
def _compute_nights(self):
|
||||
@@ -1262,10 +1265,19 @@ class PmsReservation(models.Model):
|
||||
else:
|
||||
record.shared_folio = False
|
||||
|
||||
@api.depends("partner_id", "partner_id.name", "agency_id")
|
||||
@api.depends(
|
||||
"partner_id",
|
||||
"partner_id.name",
|
||||
"agency_id",
|
||||
"reservation_type",
|
||||
"out_service_description",
|
||||
)
|
||||
def _compute_partner_name(self):
|
||||
for record in self:
|
||||
self.env["pms.folio"]._apply_partner_name(record)
|
||||
if record.reservation_type != "out":
|
||||
self.env["pms.folio"]._apply_partner_name(record)
|
||||
else:
|
||||
record.partner_name = record.out_service_description
|
||||
|
||||
@api.depends("partner_id", "partner_id.email", "agency_id")
|
||||
def _compute_email(self):
|
||||
@@ -1451,6 +1463,7 @@ class PmsReservation(models.Model):
|
||||
if (
|
||||
not record.checkin_partner_ids.filtered(lambda c: c.state == "onboard")
|
||||
and record.state == "onboard"
|
||||
and record.reservation_type != "out"
|
||||
):
|
||||
raise ValidationError(
|
||||
_("No person from reserve %s has arrived", record.name)
|
||||
@@ -1496,6 +1509,19 @@ class PmsReservation(models.Model):
|
||||
record, record.service_ids.service_line_ids
|
||||
)
|
||||
|
||||
@api.constrains("reservation_type")
|
||||
def _check_same_reservation_type(self):
|
||||
for record in self:
|
||||
if len(record.folio_id.reservation_ids) > 1:
|
||||
for reservation in record.folio_id.reservation_ids:
|
||||
if reservation.reservation_type != record.reservation_type:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"The reservation type must be the "
|
||||
"same for all reservations in folio"
|
||||
)
|
||||
)
|
||||
|
||||
# Action methods
|
||||
def open_partner(self):
|
||||
""" Utility method used to add an "View Customer" button in reservation views """
|
||||
|
||||
@@ -353,6 +353,7 @@ class PmsReservationLine(models.Model):
|
||||
not reservation.room_type_id
|
||||
or not reservation.pricelist_id
|
||||
or not reservation.pms_property_id
|
||||
or reservation.reservation_type != "normal"
|
||||
):
|
||||
line.price = 0
|
||||
elif not line.price or self._context.get("force_recompute"):
|
||||
|
||||
@@ -3,6 +3,7 @@ import datetime
|
||||
from freezegun import freeze_time
|
||||
|
||||
from odoo import fields
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
from .common import TestPms
|
||||
|
||||
@@ -333,3 +334,325 @@ class TestPmsFolio(TestPms):
|
||||
"The pending amount on a partially paid folio it \
|
||||
does not correspond to the amount that it should",
|
||||
)
|
||||
|
||||
def test_reservation_type_folio(self):
|
||||
"""
|
||||
Check that the reservation_type of a folio with
|
||||
a reservation with the default reservation_type is equal
|
||||
to 'normal'.
|
||||
---------------
|
||||
A folio is created. A reservation is created to which the
|
||||
value of the folio_id is the id of the previously created
|
||||
folio. Then it is verified that the value of the reservation_type
|
||||
field of the folio is 'normal'.
|
||||
"""
|
||||
# ARRANGE AND ACT
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Ana"})
|
||||
folio1 = self.env["pms.folio"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"partner_id": self.partner1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.env["pms.reservation"].create(
|
||||
{
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"checkin": fields.date.today(),
|
||||
"checkout": fields.date.today() + datetime.timedelta(days=1),
|
||||
"folio_id": folio1.id,
|
||||
}
|
||||
)
|
||||
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
folio1.reservation_type,
|
||||
"normal",
|
||||
"The default reservation type of the folio should be 'normal'",
|
||||
)
|
||||
|
||||
def test_staff_reservation_type_folio(self):
|
||||
"""
|
||||
Check that the reservation type field of a folio is equal
|
||||
to 'staff', if your reservations also have this field
|
||||
as 'staff'.
|
||||
---------------
|
||||
A folio is created. A reservation is created to which the
|
||||
value of the folio_id is the id of the previously created
|
||||
folio and the field reservation_type equal to 'staff'. A
|
||||
second reservation with the same folio_id and reservation_type
|
||||
is created. Then it is verified that the value of the reservation_type
|
||||
field of the folio is 'staff'.
|
||||
"""
|
||||
# ARRANGE AND ACT
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Ana"})
|
||||
folio1 = self.env["pms.folio"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"partner_id": self.partner1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.env["pms.reservation"].create(
|
||||
{
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"checkin": fields.date.today(),
|
||||
"checkout": fields.date.today() + datetime.timedelta(days=1),
|
||||
"folio_id": folio1.id,
|
||||
"reservation_type": "staff",
|
||||
}
|
||||
)
|
||||
|
||||
self.env["pms.reservation"].create(
|
||||
{
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"checkin": fields.date.today(),
|
||||
"checkout": fields.date.today() + datetime.timedelta(days=1),
|
||||
"folio_id": folio1.id,
|
||||
"reservation_type": "staff",
|
||||
}
|
||||
)
|
||||
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
folio1.reservation_type,
|
||||
"staff",
|
||||
"The reservation type of the folio should be 'staff'",
|
||||
)
|
||||
|
||||
def test_out_reservation_type_folio(self):
|
||||
"""
|
||||
Check that the reservation type field of a folio is equal
|
||||
to 'out', if your reservations also have this field
|
||||
as 'out'.
|
||||
---------------
|
||||
A folio is created. A reservation is created to which the
|
||||
value of the folio_id is the id of the previously created
|
||||
folio and the field reservation_type equal to 'out'. A
|
||||
second reservation with the same folio_id and reservation_type
|
||||
is created. Then it is verified that the value of the reservation_type
|
||||
field of the folio is 'out'.
|
||||
"""
|
||||
# ARRANGE AND ACT
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Ana"})
|
||||
folio1 = self.env["pms.folio"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"partner_id": self.partner1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.env["pms.reservation"].create(
|
||||
{
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"checkin": fields.date.today(),
|
||||
"checkout": fields.date.today() + datetime.timedelta(days=1),
|
||||
"folio_id": folio1.id,
|
||||
"reservation_type": "out",
|
||||
}
|
||||
)
|
||||
|
||||
self.env["pms.reservation"].create(
|
||||
{
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"checkin": fields.date.today(),
|
||||
"checkout": fields.date.today() + datetime.timedelta(days=1),
|
||||
"folio_id": folio1.id,
|
||||
"reservation_type": "out",
|
||||
}
|
||||
)
|
||||
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
folio1.reservation_type,
|
||||
"out",
|
||||
"The reservation type of the folio should be 'out'",
|
||||
)
|
||||
|
||||
def test_invoice_status_staff_reservation(self):
|
||||
"""
|
||||
Check that the value of the invoice_status field is 'no'
|
||||
on a page with reservation_type equal to 'staff'.
|
||||
------------
|
||||
A reservation is created with the reservation_type field
|
||||
equal to 'staff'. Then it is verified that the value of
|
||||
the invoice_status field of the folio created with the
|
||||
reservation is equal to 'no'.
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Pedro"})
|
||||
# ACT
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"pricelist_id": self.pricelist1.id,
|
||||
"reservation_type": "staff",
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
reservation.folio_id.invoice_status,
|
||||
"no",
|
||||
"The invoice status of the folio in a staff reservation should be 'no' ",
|
||||
)
|
||||
|
||||
def test_invoice_status_out_reservation(self):
|
||||
"""
|
||||
Check that the value of the invoice_status field is 'no'
|
||||
on a page with reservation_type equal to 'out'.
|
||||
------------
|
||||
A reservation is created with the reservation_type field
|
||||
equal to 'out'. Then it is verified that the value of
|
||||
the invoice_status field of the folio created with the
|
||||
reservation is equal to 'no'.
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Pedro"})
|
||||
# ACT
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"pricelist_id": self.pricelist1.id,
|
||||
"reservation_type": "out",
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
reservation.folio_id.invoice_status,
|
||||
"no",
|
||||
"The invoice status of the folio in a out reservation should be 'no' ",
|
||||
)
|
||||
|
||||
def test_amount_total_staff_reservation(self):
|
||||
"""
|
||||
Check that the amount_total field of the folio whose
|
||||
reservation has the reservation_type field as staff
|
||||
is not calculated.
|
||||
-------------------------
|
||||
A folio is created. A reservation is created to which the
|
||||
value of the folio_id is the id of the previously created
|
||||
folio and the field reservation_type equal to 'staff'. Then
|
||||
it is verified that the value of the amount_total field of
|
||||
the folio is 0.
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Pedro"})
|
||||
# ACT
|
||||
folio1 = self.env["pms.folio"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"partner_id": self.partner1.id,
|
||||
}
|
||||
)
|
||||
self.env["pms.reservation"].create(
|
||||
{
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"folio_id": folio1.id,
|
||||
"reservation_type": "staff",
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
folio1.amount_total,
|
||||
0.0,
|
||||
"The amount total of the folio in a staff reservation should be 0",
|
||||
)
|
||||
|
||||
def test_amount_total_out_reservation(self):
|
||||
"""
|
||||
Check that the amount_total field of the folio whose
|
||||
reservation has the reservation_type field as out
|
||||
is not calculated.
|
||||
-------------------------
|
||||
A folio is created. A reservation is created to which the
|
||||
value of the folio_id is the id of the previously created
|
||||
folio and the field reservation_type equal to 'out'. Then
|
||||
it is verified that the value of the amount_total field of
|
||||
the folio is 0.
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Pedro"})
|
||||
# ACT
|
||||
folio1 = self.env["pms.folio"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"partner_id": self.partner1.id,
|
||||
}
|
||||
)
|
||||
self.env["pms.reservation"].create(
|
||||
{
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"folio_id": folio1.id,
|
||||
"reservation_type": "out",
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
folio1.amount_total,
|
||||
0.0,
|
||||
"The amount total of the folio in a out of service reservation should be 0",
|
||||
)
|
||||
|
||||
def test_reservation_type_incongruence(self):
|
||||
"""
|
||||
Check that a reservation cannot be created
|
||||
with the reservation_type field different from the
|
||||
reservation_type of its folio.
|
||||
-------------
|
||||
A folio is created. A reservation is created to which the
|
||||
value of the folio_id is the id of the previously created
|
||||
folio and the field reservation_type by default('normal').
|
||||
Then it is tried to create another reservation with its
|
||||
reservation_type equal to 'staff'. But it should throw an
|
||||
error because the value of the reservation_type of the
|
||||
folio is equal to 'normal'.
|
||||
"""
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Ana"})
|
||||
folio1 = self.env["pms.folio"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"partner_id": self.partner1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.env["pms.reservation"].create(
|
||||
{
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"checkin": fields.date.today(),
|
||||
"checkout": fields.date.today() + datetime.timedelta(days=3),
|
||||
"folio_id": folio1.id,
|
||||
}
|
||||
)
|
||||
with self.assertRaises(
|
||||
ValidationError,
|
||||
msg="You cannot create reservations with different reservation_type for a folio",
|
||||
):
|
||||
self.env["pms.reservation"].create(
|
||||
{
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"checkin": fields.date.today(),
|
||||
"checkout": fields.date.today() + datetime.timedelta(days=3),
|
||||
"folio_id": folio1.id,
|
||||
"reservation_type": "staff",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -31,6 +31,14 @@ class TestPmsFolioSaleLine(TestPms):
|
||||
"capacity": 2,
|
||||
}
|
||||
)
|
||||
self.room2 = self.env["pms.room"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"name": "Double 102",
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"capacity": 2,
|
||||
}
|
||||
)
|
||||
|
||||
self.product_test1 = self.env["product.product"].create(
|
||||
{
|
||||
@@ -1179,3 +1187,67 @@ class TestPmsFolioSaleLine(TestPms):
|
||||
expected_folio_service_sale_lines
|
||||
),
|
||||
)
|
||||
|
||||
def test_no_sale_lines_staff_reservation(self):
|
||||
"""
|
||||
Check that the sale_line_ids of a folio whose reservation
|
||||
is of type 'staff' are not created.
|
||||
-----
|
||||
A reservation is created with the reservation_type field
|
||||
with value 'staff'. Then it is verified that the
|
||||
sale_line_ids of the folio created with the creation of
|
||||
the reservation are equal to False.
|
||||
"""
|
||||
# ARRANGE
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Alberto"})
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
# ACT
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"pricelist_id": self.pricelist1.id,
|
||||
"reservation_type": "staff",
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertFalse(
|
||||
reservation.folio_id.sale_line_ids,
|
||||
"Folio sale lines should not be generated for a staff type reservation ",
|
||||
)
|
||||
|
||||
def test_no_sale_lines_out_reservation(self):
|
||||
"""
|
||||
Check that the sale_line_ids of a folio whose reservation
|
||||
is of type 'out' are not created.
|
||||
-----
|
||||
A reservation is created with the reservation_type field
|
||||
with value 'out'. Then it is verified that the
|
||||
sale_line_ids of the folio created with the creation of
|
||||
the reservation are equal to False.
|
||||
"""
|
||||
# ARRANGE
|
||||
self.partner1 = self.env["res.partner"].create({"name": "Alberto"})
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
# ACT
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"pricelist_id": self.pricelist1.id,
|
||||
"reservation_type": "out",
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertFalse(
|
||||
reservation.folio_id.sale_line_ids,
|
||||
"Folio sale lines should not be generated for a out of service type reservation ",
|
||||
)
|
||||
|
||||
@@ -46,6 +46,7 @@ class TestPmsReservations(TestPms):
|
||||
"name": "Double 102",
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"capacity": 2,
|
||||
"extra_beds_allowed": 1,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -55,6 +56,7 @@ class TestPmsReservations(TestPms):
|
||||
"name": "Double 103",
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"capacity": 2,
|
||||
"extra_beds_allowed": 1,
|
||||
}
|
||||
)
|
||||
self.partner1 = self.env["res.partner"].create(
|
||||
@@ -2902,3 +2904,182 @@ class TestPmsReservations(TestPms):
|
||||
reservation.discount,
|
||||
"Room discount isn't the expected",
|
||||
)
|
||||
|
||||
def test_default_normal_reservation_type(self):
|
||||
"""
|
||||
Check that the default reservation type is "normal".
|
||||
-----------
|
||||
A reservation is created without defining the reservation_type
|
||||
field and it is checked that it is 'normal'
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
# ACT
|
||||
self.room_type_double.write({"list_price": 30})
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"pricelist_id": self.pricelist1.id,
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
reservation.reservation_type,
|
||||
"normal",
|
||||
"The default reservation type should be 'normal'",
|
||||
)
|
||||
|
||||
def test_price_normal_reservation(self):
|
||||
"""
|
||||
Check the price of a normal type reservation.
|
||||
-----------
|
||||
A reservation is created for a room with price 30.
|
||||
Then it is verified that the total price of the
|
||||
reservation is equal to the price of the room multiplied
|
||||
by the number of days of the reservation.
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
# ACT
|
||||
self.room_type_double.write({"list_price": 30})
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"pricelist_id": self.pricelist1.id,
|
||||
}
|
||||
)
|
||||
diff_days = (checkout - checkin).days
|
||||
expected_price = self.room_type_double.list_price * diff_days
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
reservation.price_total,
|
||||
expected_price,
|
||||
"The expected price of the reservation is not correct",
|
||||
)
|
||||
|
||||
def test_price_staff_reservation(self):
|
||||
"""
|
||||
Check that the price of a staff type reservation
|
||||
is not calculated.
|
||||
-------------
|
||||
A reservation is created with the reservation_type field as 'staff'.
|
||||
Then it is verified that the price of the reservation is equal to 0.
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
# ACT
|
||||
self.room_type_double.write({"list_price": 30})
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"pricelist_id": self.pricelist1.id,
|
||||
"reservation_type": "staff",
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
reservation.price_total,
|
||||
0.0,
|
||||
"The expected price of the reservation is not correct",
|
||||
)
|
||||
|
||||
def test_price_out_of_service_reservation(self):
|
||||
"""
|
||||
Check that the price of a out type reservation
|
||||
is not calculated.
|
||||
-------------
|
||||
A reservation is created with the reservation_type field as 'out'.
|
||||
Then it is verified that the price of the reservation is equal to 0.
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
# ACT
|
||||
self.room_type_double.write({"list_price": 30})
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"pricelist_id": self.pricelist1.id,
|
||||
"reservation_type": "out",
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
reservation.price_total,
|
||||
0.0,
|
||||
"The expected price of the reservation is not correct",
|
||||
)
|
||||
|
||||
def test_no_pricelist_staff_reservation(self):
|
||||
"""
|
||||
Check that in a staff type reservation the pricelist is False.
|
||||
-------------
|
||||
A reservation is created with the reservation_type field as 'staff'.
|
||||
Then it is verified that the pricelist of the reservation is False.
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
# ACT
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"reservation_type": "staff",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertFalse(
|
||||
reservation.pricelist_id,
|
||||
"The pricelist of a staff reservation should be False",
|
||||
)
|
||||
|
||||
def test_no_pricelist_out_reservation(self):
|
||||
"""
|
||||
Check that in a out type reservation the pricelist is False.
|
||||
-------------
|
||||
A reservation is created with the reservation_type field as 'out'.
|
||||
Then it is verified that the pricelist of the reservation is False.
|
||||
"""
|
||||
# ARRANGE
|
||||
checkin = fields.date.today()
|
||||
checkout = fields.date.today() + datetime.timedelta(days=3)
|
||||
# ACT
|
||||
self.room_type_double.write({"list_price": 30})
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": checkin,
|
||||
"checkout": checkout,
|
||||
"room_type_id": self.room_type_double.id,
|
||||
"partner_id": self.partner1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"reservation_type": "out",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertFalse(
|
||||
reservation.pricelist_id,
|
||||
"The pricelist of a staff reservation should be False",
|
||||
)
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
name="action_checks"
|
||||
attrs="{'invisible': [('reservation_type', 'in', 'out')]}"
|
||||
>
|
||||
<field
|
||||
name="ratio_checkin_data"
|
||||
@@ -148,6 +149,7 @@
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-magic"
|
||||
attrs="{'invisible': [('reservation_type', 'not in', 'normal')]}"
|
||||
>
|
||||
<span class="o_stat_text">Change in Group</span>
|
||||
</button>
|
||||
@@ -165,6 +167,7 @@
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-globe icon"
|
||||
attrs="{'invisible': [('reservation_type', '!=', 'normal')]}"
|
||||
>
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_text">Customer</span>
|
||||
@@ -239,7 +242,10 @@
|
||||
name="sale_details"
|
||||
>
|
||||
<field name="pms_property_id" invisible="0" />
|
||||
<field name="pricelist_id" />
|
||||
<field
|
||||
name="pricelist_id"
|
||||
attrs="{'invisible': [('reservation_type', 'not in', 'normal')]}"
|
||||
/>
|
||||
<field
|
||||
name="company_id"
|
||||
options="{'no_create': True}"
|
||||
@@ -249,10 +255,13 @@
|
||||
name="reservation_type"
|
||||
attrs="{'readonly':[('state','not in',('draft'))]}"
|
||||
/>
|
||||
<field name="agency_id" />
|
||||
<field
|
||||
name="agency_id"
|
||||
attrs="{'invisible': [('reservation_type', 'not in', 'normal')]}"
|
||||
/>
|
||||
<field
|
||||
name="channel_type_id"
|
||||
attrs="{'readonly':[('agency_id','!=', False)]}"
|
||||
attrs="{'readonly':[('agency_id','!=', False)], 'invisible':[('reservation_type', 'not in', 'normal')]}"
|
||||
/>
|
||||
<field name="internal_comment" />
|
||||
</group>
|
||||
@@ -260,6 +269,7 @@
|
||||
class="oe_subtotal_footer oe_right"
|
||||
colspan="2"
|
||||
name="folio_total"
|
||||
attrs="{'invisible':[('reservation_type', '!=', 'normal')]}"
|
||||
>
|
||||
<field
|
||||
name="amount_untaxed"
|
||||
@@ -302,7 +312,10 @@
|
||||
<field name="invoices_paid" invisible="1" />
|
||||
</group>
|
||||
<notebook colspan="4" col="1">
|
||||
<page string="Sale Lines">
|
||||
<page
|
||||
string="Sale Lines"
|
||||
attrs="{'invisible':[('reservation_type', '!=', 'normal')]}"
|
||||
>
|
||||
<field
|
||||
name="sale_line_ids"
|
||||
widget="section_and_note_one2many"
|
||||
@@ -465,7 +478,11 @@
|
||||
}"
|
||||
/>
|
||||
</page>
|
||||
<page name="invoicing" string="Invoicing">
|
||||
<page
|
||||
name="invoicing"
|
||||
string="Invoicing"
|
||||
attrs="{'invisible':[('reservation_type', '!=', 'normal')]}"
|
||||
>
|
||||
<div
|
||||
class="alert alert-info"
|
||||
role="alert"
|
||||
|
||||
@@ -130,8 +130,9 @@
|
||||
string="Print All Checkins"
|
||||
type="object"
|
||||
icon="fa-print"
|
||||
attrs="{'invisible':[
|
||||
('checkin_partner_ids','=', [])
|
||||
attrs="{'invisible':['|',
|
||||
('checkin_partner_ids','=', []),
|
||||
('reservation_type', 'in', ('out'))
|
||||
]}"
|
||||
/>
|
||||
<button
|
||||
@@ -139,6 +140,7 @@
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-globe icon"
|
||||
attrs="{'invisible':[('reservation_type','not in',('normal'))]}"
|
||||
>
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_text">Customer</span>
|
||||
@@ -200,8 +202,8 @@
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
name="action_checkin_partner_view"
|
||||
attrs="{'invisible': [
|
||||
('allowed_checkin', '!=', True),
|
||||
attrs="{'invisible': ['|',
|
||||
('allowed_checkin', '!=', True), ('reservation_type','in',('out'))
|
||||
]}"
|
||||
>
|
||||
<field
|
||||
@@ -286,11 +288,6 @@
|
||||
attrs="{'invisible': [('splitted','=',True)]}"
|
||||
/>
|
||||
</h3>
|
||||
<field
|
||||
name="out_service_description"
|
||||
placeholder="Out service description"
|
||||
attrs="{'invisible':[('reservation_type','not in',('out'))]}"
|
||||
/>
|
||||
<group col="8">
|
||||
<group
|
||||
colspan="2"
|
||||
@@ -298,12 +295,20 @@
|
||||
string="General Info"
|
||||
name="contact_details"
|
||||
>
|
||||
<field name="partner_id" invisible="0" />
|
||||
<field
|
||||
name="partner_id"
|
||||
attrs="{'invisible':[('reservation_type','in',('out'))]}"
|
||||
/>
|
||||
<field
|
||||
name="partner_name"
|
||||
placeholder="Guest"
|
||||
attrs="{'invisible':[('reservation_type','in',('out'))]}"
|
||||
/>
|
||||
<field
|
||||
name="out_service_description"
|
||||
placeholder="Out service description"
|
||||
attrs="{'invisible':[('reservation_type','not in',('out'))]}"
|
||||
/>
|
||||
<field
|
||||
name="email"
|
||||
placeholder="email"
|
||||
@@ -340,6 +345,7 @@
|
||||
<field
|
||||
name="pricelist_id"
|
||||
options="{'no_open':True,'no_create': True}"
|
||||
attrs="{'invisible': [('reservation_type', '!=', 'normal')]}"
|
||||
/>
|
||||
<!--<field
|
||||
name="agency_id"
|
||||
@@ -376,10 +382,13 @@
|
||||
nolabel="1"
|
||||
placeholder="Reservation Notes"
|
||||
/>
|
||||
<field name="agency_id" />
|
||||
<field
|
||||
name="agency_id"
|
||||
attrs="{'invisible': [('reservation_type', '!=', 'normal')]}"
|
||||
/>
|
||||
<field
|
||||
name="channel_type_id"
|
||||
attrs="{'readonly':[('agency_id','!=', False)]}"
|
||||
attrs="{'readonly':[('agency_id','!=', False)], 'invisible': [('reservation_type', '!=', 'normal')]}"
|
||||
/>
|
||||
</group>
|
||||
<group
|
||||
@@ -387,6 +396,7 @@
|
||||
class="oe_subtotal_footer oe_right"
|
||||
name="reservation_total"
|
||||
string="Amounts"
|
||||
attrs="{'invisible':[('reservation_type', '!=', 'normal')]}"
|
||||
>
|
||||
<field
|
||||
name="price_services"
|
||||
@@ -483,7 +493,11 @@
|
||||
<field name="pms_property_id" invisible="1" />
|
||||
</tree>
|
||||
</field>
|
||||
<group string="Services" name="reservation_services">
|
||||
<group
|
||||
string="Services"
|
||||
name="reservation_services"
|
||||
attrs="{'invisible':[('reservation_type', 'not in', ('normal'))]}"
|
||||
>
|
||||
<field
|
||||
name="service_ids"
|
||||
context="{'default_reservation_id': active_id, 'default_folio_id': folio_id, 'form_view_ref':'pms.pms_service_view_form'}"
|
||||
@@ -596,7 +610,7 @@
|
||||
<page
|
||||
name="invoicing"
|
||||
string="Invoicing"
|
||||
attrs="{'invisible': [('reservation_type','in',('out'))]}"
|
||||
attrs="{'invisible': [('reservation_type','in',('out','staff'))]}"
|
||||
>
|
||||
</page>
|
||||
<page name="others" string="Others">
|
||||
|
||||
Reference in New Issue
Block a user