import datetime

from freezegun import freeze_time

from odoo import fields
from odoo.exceptions import UserError, ValidationError

from .common import TestPms


class TestPmsReservations(TestPms):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        # create a room type availability
        cls.room_type_availability = cls.env["pms.availability.plan"].create(
            {
                "name": "Availability plan for TEST",
                "pms_pricelist_ids": [(6, 0, [cls.pricelist1.id])],
            }
        )

        # create room type
        cls.room_type_double = cls.env["pms.room.type"].create(
            {
                "pms_property_ids": [cls.pms_property1.id],
                "name": "Double Test",
                "default_code": "DBL_Test",
                "class_id": cls.room_type_class1.id,
            }
        )

        cls.room_type_triple = cls.env["pms.room.type"].create(
            {
                "pms_property_ids": [cls.pms_property1.id],
                "name": "Triple Test",
                "default_code": "TRP_Test",
                "class_id": cls.room_type_class1.id,
            }
        )

        # create rooms
        cls.room1 = cls.env["pms.room"].create(
            {
                "pms_property_id": cls.pms_property1.id,
                "name": "Double 101",
                "room_type_id": cls.room_type_double.id,
                "capacity": 2,
                "extra_beds_allowed": 1,
            }
        )

        cls.room2 = cls.env["pms.room"].create(
            {
                "pms_property_id": cls.pms_property1.id,
                "name": "Double 102",
                "room_type_id": cls.room_type_double.id,
                "capacity": 2,
                "extra_beds_allowed": 1,
            }
        )

        cls.room3 = cls.env["pms.room"].create(
            {
                "pms_property_id": cls.pms_property1.id,
                "name": "Double 103",
                "room_type_id": cls.room_type_double.id,
                "capacity": 2,
                "extra_beds_allowed": 1,
            }
        )

        cls.room4 = cls.env["pms.room"].create(
            {
                "pms_property_id": cls.pms_property1.id,
                "name": "Triple 104",
                "room_type_id": cls.room_type_triple.id,
                "capacity": 3,
                "extra_beds_allowed": 1,
            }
        )
        cls.partner1 = cls.env["res.partner"].create(
            {
                "firstname": "Jaime",
                "lastname": "García",
                "email": "jaime@example.com",
                "birthdate_date": "1983-03-01",
                "gender": "male",
            }
        )
        cls.id_category = cls.env["res.partner.id_category"].create(
            {"name": "DNI", "code": "D"}
        )
        cls.sale_channel_direct = cls.env["pms.sale.channel"].create(
            {"name": "sale channel direct", "channel_type": "direct"}
        )
        cls.sale_channel1 = cls.env["pms.sale.channel"].create(
            {"name": "saleChannel1", "channel_type": "indirect"}
        )
        cls.agency1 = cls.env["res.partner"].create(
            {
                "name": "partner1",
                "is_agency": True,
                "invoice_to_agency": "always",
                "default_commission": 15,
                "sale_channel_id": cls.sale_channel1.id,
            }
        )

    @freeze_time("2012-01-14")
    def test_reservation_dates_not_consecutive(self):
        """
        Check the constrain if not consecutive dates
        ----------------
        Create correct reservation set 3 reservation lines consecutives (nights)
        """
        # ARRANGE
        today = fields.date.today()
        tomorrow = fields.date.today() + datetime.timedelta(days=1)
        three_days_later = fields.date.today() + datetime.timedelta(days=3)

        # ACT & ASSERT
        with self.assertRaises(
            ValidationError,
            msg="Error, it has been allowed to create a reservation with non-consecutive days",
        ):
            self.env["pms.reservation"].create(
                {
                    "room_type_id": self.room_type_double.id,
                    "partner_id": self.partner1.id,
                    "pms_property_id": self.pms_property1.id,
                    "reservation_line_ids": [
                        (0, False, {"date": today}),
                        (0, False, {"date": tomorrow}),
                        (0, False, {"date": three_days_later}),
                    ],
                }
            )

    @freeze_time("2012-01-14")
    def test_reservation_dates_compute_checkin_out(self):
        """
        Check the reservation creation with specific reservation lines
        anc compute checkin checkout
        ----------------
        Create reservation with correct reservation lines and check
        the checkin and checkout fields. Take into account that the
        checkout of the reservation must be the day after the last night
        (view checkout assertEqual)
        """
        # ARRANGE
        today = fields.date.today()
        tomorrow = fields.date.today() + datetime.timedelta(days=1)
        two_days_later = fields.date.today() + datetime.timedelta(days=2)

        # ACT
        reservation = self.env["pms.reservation"].create(
            {
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
                "reservation_line_ids": [
                    (0, False, {"date": today}),
                    (0, False, {"date": tomorrow}),
                    (0, False, {"date": two_days_later}),
                ],
            }
        )

        # ASSERT
        self.assertEqual(
            reservation.checkin,
            today,
            "The calculated checkin of the reservation does \
            not correspond to the first day indicated in the dates",
        )
        self.assertEqual(
            reservation.checkout,
            two_days_later + datetime.timedelta(days=1),
            "The calculated checkout of the reservation does \
            not correspond to the last day indicated in the dates",
        )

    @freeze_time("2012-01-14")
    def test_create_reservation_start_date(self):
        """
        Check that the reservation checkin and the first reservation date are equal.
        ----------------
        Create a reservation and check if the first reservation line date are the same
        date that the checkin date.
        """
        # reservation should start on checkin day

        # ARRANGE
        today = fields.date.today()
        checkin = today + datetime.timedelta(days=8)
        checkout = checkin + datetime.timedelta(days=11)
        reservation_vals = {
            "checkin": checkin,
            "checkout": checkout,
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }

        # ACT
        reservation = self.env["pms.reservation"].create(reservation_vals)

        self.assertEqual(
            reservation.reservation_line_ids[0].date,
            checkin,
            "Reservation lines don't start in the correct date",
        )

    @freeze_time("2012-01-14")
    def test_create_reservation_end_date(self):
        """
        Check that the reservation checkout and the last reservation date are equal.
        ----------------
        Create a reservation and check if the last reservation line date are the same
        date that the checkout date.
        """
        # ARRANGE
        today = fields.date.today()
        checkin = today + datetime.timedelta(days=8)
        checkout = checkin + datetime.timedelta(days=11)
        reservation_vals = {
            "checkin": checkin,
            "checkout": checkout,
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }

        # ACT
        reservation = self.env["pms.reservation"].create(reservation_vals)

        self.assertEqual(
            reservation.reservation_line_ids[-1].date,
            checkout - datetime.timedelta(1),
            "Reservation lines don't end in the correct date",
        )

    @freeze_time("2012-01-14")
    def test_split_reservation01(self):
        """
        # TEST CASE
        The reservation shouldn't be splitted
        preferred_room_id with availability provided
        +------------+------+------+------+----+----+----+
        | room/date  |  01  |  02  |  03  | 04 | 05 | 06 |
        +------------+------+------+------+----+----+----+
        | Double 101 | test | test | test |    |    |    |
        | Double 102 |      |      |      |    |    |    |
        | Double 103 |      |      |      |    |    |    |
        +------------+------+------+------+----+----+----+
        """
        # ARRANGE

        # ACT
        r_test = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=3),
                "adults": 2,
                "preferred_room_id": self.room1.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r_test.flush()

        # ASSERT
        self.assertTrue(
            all(
                elem.room_id.id == r_test.reservation_line_ids[0].room_id.id
                for elem in r_test.reservation_line_ids
            ),
            "The entire reservation should be allocated in the preferred room",
        )

    @freeze_time("2012-01-14")
    def test_split_reservation02(self):
        """
        # TEST CASE
        The reservation shouldn't be splitted
        room_type_id with availability provided
        +------------+------+------+------+----+----+----+
        | room/date  |  01  |  02  |  03  | 04 | 05 | 06 |
        +------------+------+------+------+----+----+----+
        | Double 101 | test | test | test |    |    |    |
        | Double 102 |      |      |      |    |    |    |
        | Double 103 |      |      |      |    |    |    |
        +------------+------+------+------+----+----+----+
        """
        # ARRANGE

        # ACT
        r_test = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=2),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r_test.flush()

        # ASSERT
        self.assertFalse(r_test.splitted, "The reservation shouldn't be splitted")

    def test_split_reservation03(self):
        """
        # TEST CASE
        The reservation should be splitted in 2 rooms
            (there is only one better option on day 02 and a draw the next day.
             The night before should be prioritized)
        +------------+------+------+------+------+----+----+
        | room/date  |  01  |  02  |  03  | 04   | 05 | 06 |
        +------------+------+------+------+------+----+----+
        | Double 101 | test |  r3  |      |      |    |    |
        | Double 102 |  r1  | test | test | test |    |    |
        | Double 103 |  r2  |  r4  |      |      |    |    |
        +------------+------+------+------+------+----+----+
        """
        # ARRANGE

        r1 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r1.reservation_line_ids[0].room_id = self.room2.id
        r1.flush()

        r2 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r2.reservation_line_ids[0].room_id = self.room3.id
        r2.flush()

        r3 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now() + datetime.timedelta(days=1),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=2),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r3.reservation_line_ids[0].room_id = self.room1.id
        r3.flush()

        r4 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now() + datetime.timedelta(days=1),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=2),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r4.reservation_line_ids[0].room_id = self.room3.id
        r4.flush()
        expected_num_changes = 2

        # ACT
        r_test = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=4),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r_test.flush()
        # ASSERT
        self.assertEqual(
            expected_num_changes,
            len(r_test.reservation_line_ids.mapped("room_id")),
            "The reservation shouldn't have more than 2 changes",
        )

    @freeze_time("2012-01-14")
    def test_split_reservation04(self):
        """
        # TEST CASE
        The reservation should be splitted in 3 rooms
            (there are 2 best options on day 03 and room of last night is not available)
        +------------+------+------+------+------+----+----+
        | room/date  |  01  |  02  |  03  | 04   | 05 | 06 |
        +------------+------+------+------+------+----+----+
        | Double 101 | test |  r3  | test | test |    |    |
        | Double 102 |  r1  | test |  r5  |      |    |    |
        | Double 103 |  r2  |  r4  |      |      |    |    |
        +------------+------+------+------+------+----+----+
        """
        # ARRANGE

        r1 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r1.reservation_line_ids[0].room_id = self.room2.id
        r1.flush()

        r2 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r2.reservation_line_ids[0].room_id = self.room3.id
        r2.flush()

        r3 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now() + datetime.timedelta(days=1),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=2),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r3.reservation_line_ids[0].room_id = self.room1.id
        r3.flush()

        r4 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now() + datetime.timedelta(days=1),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=2),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r4.reservation_line_ids[0].room_id = self.room3.id
        r4.flush()

        r5 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now() + datetime.timedelta(days=2),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=3),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r5.reservation_line_ids[0].room_id = self.room2.id
        r5.flush()

        # ACT
        r_test = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=4),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r_test.flush()

        rooms = 0
        last_room = None
        for line in r_test.reservation_line_ids:
            if line.room_id != last_room:
                last_room = line.room_id
                rooms += 1

        # ASSERT
        self.assertEqual(
            3, rooms, "The reservation shouldn't be splitted in more than 3 roomss"
        )

    @freeze_time("2012-01-14")
    def test_split_reservation05(self):
        """
        # TEST CASE
        The preferred room_id is not available
        +------------+------+------+------+----+----+----+
        | room/date  |  01  |  02  |  03  | 04 | 05 | 06 |
        +------------+------+------+------+----+----+----+
        | Double 101 |r1/tst|      |      |    |    |    |
        | Double 102 |      |      |      |    |    |    |
        | Double 103 |      |      |      |    |    |    |
        +------------+------+------+------+----+----+----+
        """
        # ARRANGE

        r1 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r1.reservation_line_ids[0].room_id = self.room1
        r1.flush()

        # ACT & ASSERT
        with self.assertRaises(ValidationError):
            r_test = self.env["pms.reservation"].create(
                {
                    "pms_property_id": self.pms_property1.id,
                    "checkin": datetime.datetime.now(),
                    "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
                    "adults": 2,
                    "preferred_room_id": self.room1.id,
                    "partner_id": self.partner1.id,
                }
            )
            r_test.flush()

    @freeze_time("2012-01-14")
    def test_split_reservation06(self):
        """
        # TEST CASE
        There's no availability in the preferred_room_id provided
        +------------+------+------+------+----+----+----+
        | room/date  |  01  |  02  |  03  | 04 | 05 | 06 |
        +------------+------+------+------+----+----+----+
        | Double 101 |  r1  |r1/tst|  tst |    |    |    |
        | Double 102 |      |      |      |    |    |    |
        | Double 103 |      |      |      |    |    |    |
        +------------+------+------+------+----+----+----+
        """
        # ARRANGE

        r1 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=2),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r1.reservation_line_ids[0].room_id = self.room1
        r1.reservation_line_ids[1].room_id = self.room1
        r1.flush()

        # ACT & ASSERT
        with self.assertRaises(ValidationError):
            r_test = self.env["pms.reservation"].create(
                {
                    "pms_property_id": self.pms_property1.id,
                    "checkin": datetime.datetime.now() + datetime.timedelta(days=1),
                    "checkout": datetime.datetime.now() + datetime.timedelta(days=3),
                    "adults": 2,
                    "preferred_room_id": self.room1.id,
                    "partner_id": self.partner1.id,
                }
            )
            r_test.flush()

    @freeze_time("2012-01-14")
    def test_split_reservation07(self):
        """
        # TEST CASE
        There's no availability
        +------------+------+------+------+----+----+----+
        | room/date  |  01  |  02  |  03  | 04 | 05 | 06 |
        +------------+------+------+------+----+----+----+
        | Double 101 |  r1  |  r1  |  r1  |    |    |    |
        | Double 102 |  r2  |  r2  |  r2  |    |    |    |
        | Double 103 |  r3  |  r3  |  r3  |    |    |    |
        +------------+------+------+------+----+----+----+
        """
        # ARRANGE
        r1 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=3),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r1.reservation_line_ids[0].room_id = self.room1
        r1.reservation_line_ids[1].room_id = self.room1
        r1.reservation_line_ids[2].room_id = self.room1
        r1.flush()

        r2 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=3),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r2.reservation_line_ids[0].room_id = self.room2
        r2.reservation_line_ids[1].room_id = self.room2
        r2.reservation_line_ids[2].room_id = self.room2
        r2.flush()

        r3 = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=3),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r3.reservation_line_ids[0].room_id = self.room3
        r3.reservation_line_ids[1].room_id = self.room3
        r3.reservation_line_ids[2].room_id = self.room3
        r3.flush()

        # ACT & ASSERT
        with self.assertRaises(ValidationError):
            self.env["pms.reservation"].create(
                {
                    "pms_property_id": self.pms_property1.id,
                    "checkin": datetime.datetime.now(),
                    "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
                    "adults": 2,
                    "room_type_id": self.room_type_double.id,
                    "partner_id": self.partner1.id,
                }
            )

    @freeze_time("2012-01-14")
    def test_manage_children_raise(self):
        # TEST CASE
        """
        Check if the error occurs when trying to put more people than the capacity of the room.
        --------------
         Create a reservation with a double room whose capacity is two and try to create
         it with two adults and a child occupying the room.
        """
        # NO ARRANGE
        # ACT & ASSERT
        with self.assertRaises(
            ValidationError,
            msg="The number of people is greater than the capacity of the room",
        ):
            reservation = self.env["pms.reservation"].create(
                {
                    "adults": 2,
                    "children_occupying": 1,
                    "checkin": datetime.datetime.now(),
                    "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
                    "preferred_room_id": self.room1.id,
                    "partner_id": self.partner1.id,
                    "pms_property_id": self.pms_property1.id,
                }
            )
            reservation.flush()

    @freeze_time("2012-01-14")
    def test_to_assign_priority_reservation(self):
        """
        To assign reservation must have priority = 1
        ------
        Create a reservation with only room_type (to_assign = True),
        regardless of the rest of the fields the priority must be 1

        NOTE:
        WORK FLOW PRIORITY COMPUTE
        Check reservation priority
        --------
        1 - TO ASSIGN, ARRIVAL DELAYED, DEPARTURE DELAYED (= 1)
        2 - CANCELLED with pending amount (= 2)
        3 - DONE with pending amount (= 3)
        4 - ONBOARD with pending amount (= days for checkout)
        5 - CONFIRM/DRAFT with arrival in less than 3 days (= 2 * days for checkin)
        6 - ONBOARD all paid (= 3 * days for checkout)
        7 - DONE with days from checkout < 1 (= 6)
        8 - CONFIRM/DRAFT with arrival between 3 and 20 days (= 3 * days for checkin)
        9 - CONFIRM/DRAFT with arrival in more than 20 days (= 4 * days for checkin)
        10 - DONE with days from checkout < 15 (= 5 * days from checkout)
        11 - DONE with days from checkout between 15 and 90 included (= 10 * days from checkout)
        12 - DONE with days from checkout > 90 (= 100 * days from checkout)
        """
        # ARRANGE
        expected_priority = 1

        # ACT
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=30),
                "checkout": fields.date.today() + datetime.timedelta(days=31),
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        computed_priority = res.priority

        # ASSERT
        error_msm = (
            (
                "The priority of a reservation to be assigned \
                should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("2012-01-14")
    def test_arrival_delayed_priority_reservation(self):
        """
        Arrival delayed reservation must have priority = 1
        ------
        Create a reservation with checkin date yesterday, and without checkin action,
        regardless of the rest of the fields the priority must be 1
        """
        # ARRANGE
        expected_priority = 1
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=-1),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "preferred_room_id": self.room1.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        # ACT
        res.auto_arrival_delayed()
        computed_priority = res.priority

        # ASSERT
        error_msm = (
            (
                "The priority of a arrival delayed reservation \
                should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    # @freeze_time("1981-11-10")
    # def test_departure_delayed_priority_reservation(self):
    #     """
    #     To departure delayed reservation must have priority = 1
    #     ------
    #     Create a reservation and make the work flow to onboard state,
    #     using jump dates, we make the reservation should have left yesterday,
    #     regardless of the rest of the fields the priority must be 1
    #     """
    #     # ARRANGE
    #     expected_priority = 1
    #     freezer = freeze_time("1981-11-08")
    #     freezer.start()
    #     res = self.env["pms.reservation"].create(
    #         {
    #             "checkin": fields.date.today(),
    #             "checkout": fields.date.today() + datetime.timedelta(days=1),
    #             "preferred_room_id": self.room2.id,
    #             "partner_id": self.partner1.id,
    #             "pms_property_id": self.pms_property1.id,
    #         }
    #     )
    #     host1 = self.env["res.partner"].create(
    #         {
    #             "firstname": "Pepe",
    #             "lastname": "Paz",
    #             "email": "pepe@example.com",
    #             "birthdate_date": "1995-12-10",
    #             "gender": "male",
    #         }
    #     )
    #     checkin1 = self.env["pms.checkin.partner"].create(
    #         {
    #             "partner_id": host1.id,
    #             "reservation_id": res.id,
    #             "document_expedition_date": fields.date.today()
    #             + datetime.timedelta(days=665),
    #         }
    #     )
    #     checkin1.action_on_board()
    #     freezer.stop()

    #     # ACT
    #     res.auto_departure_delayed()
    #     computed_priority = res.priority

    #     # ASSERT
    #     error_msm = (
    #         (
    #             "The priority of a departure delayed reservation \
    #             should be %d and this is %d"
    #         )
    #         % (expected_priority, computed_priority)
    #     )

    #     self.assertEqual(
    #         computed_priority,
    #         expected_priority,
    #         error_msm,
    #     )

    @freeze_time("2012-01-14")
    def _test_cancel_pending_amount_priority_reservation(self):
        """
        Cancelled with pending payments reservation must have priority = 2
        ------
        create a reservation and cancel it ensuring that there are
        pending payments in it, the priority must be 2
        """
        # ARRANGE
        expected_priority = 2
        self.room_type_double.list_price = 25
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=55),
                "checkout": fields.date.today() + datetime.timedelta(days=56),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        # ACT
        res.action_cancel()
        res.flush()
        computed_priority = res.priority

        # ASSERT
        error_msm = (
            (
                "The priority of a cancelled reservation with pending amount \
                should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )
        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("1981-11-10")
    def test_done_with_pending_amountpriority_reservation(self):
        """
        Done with pending amount reservation must have priority = 3
        ------
        Create a reservation and make the work flow to onboard - done state,
        using jump dates, we make the checkout reservation with pending amount,
        regardless of the rest of the fields the priority must be 3
        """
        # ARRANGE
        expected_priority = 3
        freezer = freeze_time("1981-10-08")
        freezer.start()
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        host1 = self.env["res.partner"].create(
            {
                "firstname": "Pepe",
                "lastname": "Paz",
                "email": "pepe@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": host1.id,
                "reservation_id": res.id,
                "document_expedition_date": fields.date.today()
                + datetime.timedelta(days=665),
            }
        )
        checkin1.action_on_board()

        freezer.stop()
        freezer = freeze_time("1981-10-09")
        freezer.start()

        res.action_reservation_checkout()

        # ACT
        res.auto_departure_delayed()
        computed_priority = res.priority
        freezer.stop()

        # ASSERT
        error_msm = (
            (
                "The priority of a done reservation with pending amount\
                should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("1981-11-10")
    def test_onboard_with_pending_amount_priority_reservation(self):
        """
        Onboard with pending amount reservation must have priority = days for checkout
        ------
        Create a reservation with 3 nights and make the work flow to onboard,
        using jump dates, we set today in 2 nights before checkout,
        regardless of the rest of the fields the priority must be 2
        """
        # ARRANGE
        expected_priority = 3
        freezer = freeze_time("1981-10-08")
        freezer.start()
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=3),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        host1 = self.env["res.partner"].create(
            {
                "firstname": "Pepe",
                "lastname": "Paz",
                "email": "pepe@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": host1.id,
                "reservation_id": res.id,
                "document_expedition_date": fields.date.today()
                + datetime.timedelta(days=665),
            }
        )

        # ACT
        checkin1.action_on_board()
        computed_priority = res.priority
        freezer.stop()

        # ASSERT
        error_msm = (
            (
                "The priority of a onboard with payment amount reservation \
                should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("2012-01-14")
    def test_confirm_arriva_lt_3_days_priority_reservation(self):
        """
        Confirm reservation with arrival in less than 3 days, priority = 2 * days for checkout
        ------
        Create a reservation with checkin date on 2 days
        regardless of the rest of the fields the priority must be 2 * 2 = 4
        """
        # ARRANGE
        expected_priority = 4

        # ACT
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=2),
                "checkout": fields.date.today() + datetime.timedelta(days=5),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        computed_priority = res.priority

        # ASSERT
        error_msm = (
            (
                "The priority of a confirm with less than 3 days for arrival \
                reservation should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("2012-01-14")
    def test_onboard_all_pay_priority_reservation(self):
        """
        Onboard with all pay reservation must have priority = 3 * days for checkout
        ------
        Create a reservation with 3 nights and make the work flow to onboard,
        using jump dates, we set today in 2 nights before checkout,
        regardless of the rest of the fields the priority must be 3 * 3 = 9
        """
        # ARRANGE
        expected_priority = 9
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=3),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        host1 = self.env["res.partner"].create(
            {
                "firstname": "Pepe",
                "lastname": "Paz",
                "email": "pepe@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": host1.id,
                "reservation_id": res.id,
                "document_expedition_date": fields.date.today()
                + datetime.timedelta(days=665),
            }
        )

        # ACT
        checkin1.action_on_board()
        # REVIEW: set to 0 the price to avoid make the payment
        # (config account company issues in test)
        res.reservation_line_ids.write({"price": 0})
        computed_priority = res.priority

        # ASSERT
        error_msm = (
            (
                "The priority of onboard all pay reservation \
                should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("1981-11-10")
    def test_done_yesterday_all_paid_amountpriority_reservation(self):
        """
        Checkout yesterday without pending amount reservation must have priority = 6
        ------
        Create a reservation and make the work flow to onboard - done state,
        using jump dates, we make the checkout reservation without pending amount,
        and set today 1 day after,
        regardless of the rest of the fields the priority must be 6
        """
        # ARRANGE
        expected_priority = 6
        freezer = freeze_time("1981-10-08")
        freezer.start()
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        host1 = self.env["res.partner"].create(
            {
                "firstname": "Pepe",
                "lastname": "Paz",
                "email": "pepe@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": host1.id,
                "reservation_id": res.id,
                "document_expedition_date": fields.date.today()
                + datetime.timedelta(days=665),
            }
        )
        checkin1.action_on_board()

        freezer.stop()
        freezer = freeze_time("1981-10-09")
        freezer.start()

        res.action_reservation_checkout()
        # REVIEW: set to 0 the price to avoid make the payment
        # (config account company issues in test)
        res.reservation_line_ids.write({"price": 0})

        # ACT
        freezer.stop()
        freezer = freeze_time("1981-10-10")
        freezer.start()

        res.update_daily_priority_reservation()
        computed_priority = res.priority
        freezer.stop()

        # ASSERT
        error_msm = (
            (
                "The priority of a done reservation without pending amount\
                and checkout yesterday should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("2012-01-14")
    def test_confirm_arriva_bt_3_and_20_days_priority_reservation(self):
        """
        Confirm reservation with arrival between 3 and 20 days, priority = 3 * days for checkout
        ------
        Create a reservation with checkin date on 15 days
        regardless of the rest of the fields the priority must be 3 * 15 = 45
        """
        # ARRANGE
        expected_priority = 45

        # ACT
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=15),
                "checkout": fields.date.today() + datetime.timedelta(days=20),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        computed_priority = res.priority

        # ASSERT
        error_msm = (
            (
                "The priority of a confirm with between 3 and 20 days for arrival \
                reservation should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("2012-01-14")
    def test_confirm_arrival_more_than_20_days_priority_reservation(self):
        """
        Confirm reservation with arrival more than 20 days, priority = 4 * days for checkout
        ------
        Create a reservation with checkin date on 21 days
        regardless of the rest of the fields the priority must be 4 * 21 = 84
        """
        # ARRANGE
        expected_priority = 84

        # ACT
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=21),
                "checkout": fields.date.today() + datetime.timedelta(days=25),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        computed_priority = res.priority

        # ASSERT
        error_msm = (
            (
                "The priority of a confirm with more than 20 days for arrival \
                reservation should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("1981-11-10")
    def test_done_checkout_lt_15_days_before_all_paid_priority_reservation(self):
        """
        Checkout less than 15 days before without pending amount reservation
        must have priority = 5 * days from checkout
        ------
        Create a reservation and make the work flow to onboard - done state,
        using jump dates, we make the checkout reservation without pending amount,
        and set today 6 day after,
        regardless of the rest of the fields the priority must be 6 * 5 = 30
        """
        # ARRANGE
        expected_priority = 30
        freezer = freeze_time("1981-10-09")
        freezer.start()
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        host1 = self.env["res.partner"].create(
            {
                "firstname": "Pepe",
                "lastname": "Paz",
                "email": "pepe@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": host1.id,
                "reservation_id": res.id,
                "document_expedition_date": fields.date.today()
                + datetime.timedelta(days=665),
            }
        )
        checkin1.action_on_board()

        freezer.stop()
        freezer = freeze_time("1981-10-10")
        freezer.start()

        res.action_reservation_checkout()
        # REVIEW: set to 0 the price to avoid make the payment
        # (config account company issues in test)
        res.reservation_line_ids.write({"price": 0})

        # ACT
        freezer.stop()
        freezer = freeze_time("1981-10-16")
        freezer.start()

        res.update_daily_priority_reservation()
        computed_priority = res.priority
        freezer.stop()

        # ASSERT
        error_msm = (
            (
                "The priority of a done reservation without pending amount\
                and checkout less than 15 days before should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("1981-11-10")
    def test_done_checkout_bt_30_and_90_days_before_all_paid_priority_reservation(self):
        """
        Checkout between 30 and 90 days before without pending amount reservation
        must have priority = 10 * days from checkout
        ------
        Create a reservation and make the work flow to onboard - done state,
        using jump dates, we make the checkout reservation without pending amount,
        and set today 45 day after,
        regardless of the rest of the fields the priority must be 10 * 45 = 450
        """
        # ARRANGE
        expected_priority = 450
        freezer = freeze_time("1981-10-09")
        freezer.start()
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        host1 = self.env["res.partner"].create(
            {
                "firstname": "Pepe",
                "lastname": "Paz",
                "email": "pepe@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": host1.id,
                "reservation_id": res.id,
                "document_expedition_date": fields.date.today()
                + datetime.timedelta(days=665),
            }
        )
        checkin1.action_on_board()

        freezer.stop()
        freezer = freeze_time("1981-10-10")
        freezer.start()

        res.action_reservation_checkout()
        # REVIEW: set to 0 the price to avoid make the payment
        # (config account company issues in test)
        res.reservation_line_ids.write({"price": 0})

        # ACT
        freezer.stop()
        freezer = freeze_time("1981-11-24")
        freezer.start()

        res.update_daily_priority_reservation()
        computed_priority = res.priority
        freezer.stop()

        # ASSERT
        error_msm = (
            (
                "The priority of a done reservation without pending amount\
                and checkout between 30 and 90 days before should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    @freeze_time("1981-11-10")
    def test_done_checkout_mt_90_days_before_all_paid_priority_reservation(self):
        """
        Checkout more than 90 days before without pending amount reservation
        must have priority = 100 * days from checkout
        ------
        Create a reservation and make the work flow to onboard - done state,
        using jump dates, we make the checkout reservation without pending amount,
        and set today 91 day after,
        regardless of the rest of the fields the priority must be 100 * 91 = 9100
        """
        # ARRANGE
        expected_priority = 9100
        freezer = freeze_time("1981-10-09")
        freezer.start()
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "preferred_room_id": self.room2.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        host1 = self.env["res.partner"].create(
            {
                "firstname": "Pepe",
                "lastname": "Paz",
                "email": "pepe@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": host1.id,
                "reservation_id": res.id,
                "document_expedition_date": fields.date.today()
                + datetime.timedelta(days=665),
            }
        )
        checkin1.action_on_board()

        freezer.stop()
        freezer = freeze_time("1981-10-10")
        freezer.start()

        res.action_reservation_checkout()
        # REVIEW: set to 0 the price to avoid make the payment
        # (config account company issues in test)
        res.reservation_line_ids.write({"price": 0})

        # ACT
        freezer.stop()
        freezer = freeze_time("1982-01-09")
        freezer.start()

        res.update_daily_priority_reservation()
        computed_priority = res.priority
        freezer.stop()

        # ASSERT
        error_msm = (
            (
                "The priority of a done reservation without pending amount\
                and checkout more than 90 days before should be %d and this is %d"
            )
            % (expected_priority, computed_priority)
        )

        self.assertEqual(
            computed_priority,
            expected_priority,
            error_msm,
        )

    def test_reservation_action_assign(self):
        """
        Checks the correct operation of the assign method
        ---------------
        Create a new reservation with only room_type(autoassign -> to_assign = True),
        and the we call to action_assign method to confirm the assignation
        """
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ACT
        res.action_assign()
        # ASSERT
        self.assertFalse(res.to_assign, "The reservation should be marked as assigned")

    def test_reservation_auto_assign_on_create(self):
        """
        When creating a reservation with a specific room,
        it is not necessary to mark it as to be assigned
        ---------------
        Create a new reservation with specific preferred_room_id,
        "to_assign" should be set to false automatically
        """
        # ARRANGE

        # ACT
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "preferred_room_id": self.room1.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        # ASSERT
        self.assertFalse(
            res.to_assign, "Reservation with preferred_room_id set to to_assign = True"
        )

    def test_reservation_auto_assign_after_create(self):
        """
        When assigning a room manually to a reservation marked "to be assigned",
        this field should be automatically unchecked
        ---------------
        Create a new reservation without preferred_room_id (only room_type),
        "to_assign" is True, then set preferred_room_id and "to_assign" should
        be set to false automatically
        """
        # ARRANGE
        # set the priority of the rooms to control the room chosen by auto assign
        self.room1.sequence = 1
        self.room2.sequence = 2

        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        # ACT
        # res shoul be room1 in preferred_room_id (minor sequence)
        res.preferred_room_id = self.room2.id

        # ASSERT
        self.assertFalse(
            res.to_assign,
            "The reservation should be marked as assigned automatically \
            when assigning the specific room",
        )

    def test_reservation_to_assign_on_create(self):
        """
        Check the reservation action assign.
        Create a reservation and change the reservation to 'to_assign' = False
        through action_assign() method
        """
        # ARRANGE
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ACT
        res.action_assign()
        # ASSERT
        self.assertFalse(res.to_assign, "The reservation should be marked as assigned")

    def test_reservation_action_cancel(self):
        """
        Check if the reservation has been cancelled correctly.
        -------------
        Create a reservation and change his state to cancelled
        through the action_cancel() method.
        """
        # ARRANGE
        res = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ACT
        res.action_cancel()
        # ASSERT
        self.assertEqual(res.state, "cancel", "The reservation should be cancelled")

    @freeze_time("1981-11-01")
    def test_reservation_action_checkout(self):
        # TEST CASE
        """
        Check that when the date of a reservation passes, it goes to the 'done' status.
        -------------
        Create a host, a reservation and a check-in partner. Assign the partner and the
        reservation to the check-in partner and after one day of the reservation it
        must be in the 'done' status
        """
        # ARRANGE
        host = self.env["res.partner"].create(
            {
                "name": "Miguel",
                "mobile": "654667733",
                "email": "miguel@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        self.env["res.partner.id_number"].create(
            {
                "category_id": self.id_category.id,
                "name": "30065089H",
                "valid_from": datetime.date.today(),
                "partner_id": host.id,
            }
        )
        r1 = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "room_type_id": self.room_type_double.id,
                "partner_id": host.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r1.flush()
        checkin = self.env["pms.checkin.partner"].create(
            {
                "partner_id": host.id,
                "reservation_id": r1.id,
            }
        )
        checkin.action_on_board()
        checkin.flush()

        # ACT
        with freeze_time("1981-11-02"):
            r1._cache.clear()
            r1.action_reservation_checkout()

        # ASSERT
        self.assertEqual(
            r1.state, "done", "The reservation status should be done after checkout."
        )

    def _test_check_date_order(self):
        """
        Check that the date order of a reservation is correct.
        ---------------
        Create a reservation with today's date and then check that the date order is also today
        """
        reservation = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=3),
                "partner_id": self.partner1.id,
                "room_type_id": self.room_type_double.id,
            }
        )

        date_order = reservation.date_order
        date_order_expected = datetime.datetime(
            date_order.year,
            date_order.month,
            date_order.day,
            date_order.hour,
            date_order.minute,
            date_order.second,
        )

        reservation.flush()
        self.assertEqual(
            date_order,
            date_order_expected,
            "Date Order isn't correct",
        )

    def test_check_checkin_datetime(self):
        """
        Check that the checkin datetime of a reservation is correct.
        ------------------
        Create a reservation and then check if the checkin datetime
        it is correct
        """
        reservation = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": fields.date.today() + datetime.timedelta(days=300),
                "checkout": fields.date.today() + datetime.timedelta(days=305),
                "partner_id": self.partner1.id,
                "room_type_id": self.room_type_double.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        r = reservation.checkin
        checkin_expected = datetime.datetime(r.year, r.month, r.day, 14, 00)
        checkin_expected = self.pms_property1.date_property_timezone(checkin_expected)

        self.assertEqual(
            str(reservation.checkin_datetime),
            str(checkin_expected),
            "Date Order isn't correct",
        )

    def test_check_allowed_room_ids(self):
        """
        Check available rooms after creating a reservation.
        -----------
        Create an availability rule, create a reservation,
        and then check that the allowed_room_ids field filtered by room
        type of the reservation and the room_type_id.room_ids field of the
        availability rule match.
        """
        availability_rule = self.env["pms.availability.plan.rule"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "room_type_id": self.room_type_double.id,
                "availability_plan_id": self.room_type_availability.id,
                "date": fields.date.today() + datetime.timedelta(days=153),
            }
        )
        reservation = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": fields.date.today() + datetime.timedelta(days=150),
                "checkout": fields.date.today() + datetime.timedelta(days=152),
                "partner_id": self.partner1.id,
                "room_type_id": self.room_type_double.id,
                "pricelist_id": self.pricelist1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        self.assertEqual(
            reservation.allowed_room_ids.filtered(
                lambda r: r.room_type_id.id == availability_rule.room_type_id.id
            ).ids,
            availability_rule.room_type_id.room_ids.ids,
            "Rooms allowed don't match",
        )

    def test_partner_is_agency(self):
        """
        Check that a reservation created with an agency and without a partner
        assigns that agency as a partner.
        -------------
        Create an agency and then create a reservation to which that agency
        assigns but does not associate any partner.
        Then check that the partner of that reservation is the same as the agency
        """
        sale_channel1 = self.env["pms.sale.channel"].create(
            {"name": "Test Indirect", "channel_type": "indirect"}
        )
        agency = self.env["res.partner"].create(
            {
                "name": "partner1",
                "is_agency": True,
                "sale_channel_id": sale_channel1.id,
                "invoice_to_agency": "always",
            }
        )

        reservation = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": fields.date.today() + datetime.timedelta(days=150),
                "checkout": fields.date.today() + datetime.timedelta(days=152),
                "agency_id": agency.id,
                "room_type_id": self.room_type_double.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        reservation.flush()

        self.assertEqual(
            reservation.partner_id.id,
            agency.id,
            "Partner_id doesn't match with agency_id",
        )

    def test_agency_pricelist(self):
        """
        Check that a pricelist of a reservation created with an
        agency and without a partner and the pricelist of that
        agency are the same.
        -------------
        Create an agency with field apply_pricelist is True and
        then create a reservation to which that agency
        assigns but does not associate any partner.
        Then check that the pricelist of that reservation is the same as the agency
        """
        sale_channel1 = self.env["pms.sale.channel"].create(
            {
                "name": "Test Indirect",
                "channel_type": "indirect",
                "product_pricelist_ids": [(6, 0, [self.pricelist1.id])],
            }
        )
        agency = self.env["res.partner"].create(
            {
                "name": "partner1",
                "is_agency": True,
                "sale_channel_id": sale_channel1.id,
                "apply_pricelist": True,
            }
        )

        reservation = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": fields.date.today() + datetime.timedelta(days=150),
                "checkout": fields.date.today() + datetime.timedelta(days=152),
                "agency_id": agency.id,
                "room_type_id": self.room_type_double.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        self.assertEqual(
            reservation.pricelist_id.id,
            reservation.agency_id.property_product_pricelist.id,
            "Rervation pricelist doesn't match with Agency pricelist",
        )

    def test_compute_access_url(self):
        """
        Check that the access_url field of the reservation is created with a correct value.
        -------------
        Create a reservation and then check that the access_url field has the value
        my/reservation/(reservation.id)
        """
        reservation = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": fields.date.today() + datetime.timedelta(days=150),
                "checkout": fields.date.today() + datetime.timedelta(days=152),
                "partner_id": self.partner1.id,
                "room_type_id": self.room_type_double.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        url = "/my/reservations/%s" % reservation.id
        self.assertEqual(reservation.access_url, url, "Reservation url isn't correct")

    @freeze_time("2012-01-14")
    def test_compute_ready_for_checkin(self):
        """
        Check that the ready_for_checkin field is True when the reservation
        checkin day is today.
        ---------------
        Create two hosts, create a reservation with a checkin date today,
        and associate two checkin partners with that reservation and with
        each of the hosts.
        Then check that the ready_for_checkin field of the reservation is True
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Miguel",
                "mobile": "654667733",
                "email": "miguel@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        self.env["res.partner.id_number"].create(
            {
                "category_id": self.id_category.id,
                "name": "30065000H",
                "valid_from": datetime.date.today(),
                "partner_id": self.host1.id,
            }
        )
        self.host2 = self.env["res.partner"].create(
            {
                "name": "Brais",
                "mobile": "654437733",
                "email": "brais@example.com",
                "birthdate_date": "1995-12-10",
                "gender": "male",
            }
        )
        self.env["res.partner.id_number"].create(
            {
                "category_id": self.id_category.id,
                "name": "30065089H",
                "valid_from": datetime.date.today(),
                "partner_id": self.host2.id,
            }
        )
        self.reservation = self.env["pms.reservation"].create(
            {
                "checkin": "2012-01-14",
                "checkout": "2012-01-17",
                "partner_id": self.host1.id,
                "allowed_checkin": True,
                "pms_property_id": self.pms_property1.id,
                "adults": 3,
                "room_type_id": self.room_type_triple.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        self.checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": self.host1.id,
                "reservation_id": self.reservation.id,
            }
        )
        self.checkin2 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": self.host2.id,
                "reservation_id": self.reservation.id,
            }
        )

        self.reservation.checkin_partner_ids = [
            (6, 0, [self.checkin1.id, self.checkin2.id])
        ]
        self.assertTrue(
            self.reservation.ready_for_checkin,
            "Reservation should is ready for checkin",
        )

    def test_check_checkout_less_checkin(self):
        """
        Check that a reservation cannot be created with the
        checkin date greater than the checkout date
        ---------------
        Create a reservation with the checkin date 3 days
        after the checkout date, this should throw an error.
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )
        with self.assertRaises(UserError):
            self.env["pms.reservation"].create(
                {
                    "checkin": fields.date.today() + datetime.timedelta(days=3),
                    "checkout": fields.date.today(),
                    "pms_property_id": self.pms_property1.id,
                    "partner_id": self.host1.id,
                    "room_type_id": self.room_type_double.id,
                }
            )

    @freeze_time("2012-01-14")
    def test_check_more_adults_than_beds(self):
        """
        Check that a reservation cannot be created when the field
        adults is greater than the capacity of the room.
        -------------
        Try to create a reservation with a double room and the
        field 'adults'=4, this should throw a mistake because the
        room capacity is lesser than the number of adults.
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )
        with self.assertRaises(ValidationError):
            reservation = self.env["pms.reservation"].create(
                {
                    "checkin": fields.date.today(),
                    "checkout": fields.date.today() + datetime.timedelta(days=3),
                    "pms_property_id": self.pms_property1.id,
                    "partner_id": self.host1.id,
                    "preferred_room_id": self.room1.id,
                    "adults": 4,
                }
            )
            reservation.flush()

    @freeze_time("2012-01-14")
    def test_check_format_arrival_hour(self):
        """
        Check that the format of the arrival_hour field is correct(HH:mm)
        -------------
        Create a reservation with the wrong arrival hour date
        format (HH:mm:ss), this should throw an error.
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )
        with self.assertRaises(ValidationError):
            self.env["pms.reservation"].create(
                {
                    "checkin": fields.date.today(),
                    "checkout": fields.date.today() + datetime.timedelta(days=3),
                    "pms_property_id": self.pms_property1.id,
                    "partner_id": self.host1.id,
                    "arrival_hour": "14:00:00",
                }
            )

    @freeze_time("2012-01-14")
    def test_check_format_departure_hour(self):
        """
        Check that the format of the departure_hour field is correct(HH:mm)
        -------------
        Create a reservation with the wrong departure hour date
        format (HH:mm:ss), this should throw an error.
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )
        with self.assertRaises(ValidationError):
            self.env["pms.reservation"].create(
                {
                    "checkin": fields.date.today(),
                    "checkout": fields.date.today() + datetime.timedelta(days=3),
                    "pms_property_id": self.pms_property1.id,
                    "partner_id": self.host1.id,
                    "departure_hour": "14:00:00",
                }
            )

    @freeze_time("2012-01-14")
    def test_check_property_integrity_room(self):
        """
        Check that a reservation cannot be created with a room
        of a different property.
        ------------
         Try to create a reservation for property2 with a
         preferred_room that belongs to property1, this
         should throw an error .
        """
        self.property2 = self.env["pms.property"].create(
            {
                "name": "MY PMS TEST",
                "company_id": self.company1.id,
                "default_pricelist_id": self.pricelist1.id,
            }
        )
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )
        self.room_type_double.pms_property_ids = [
            (6, 0, [self.pms_property1.id, self.property2.id])
        ]
        with self.assertRaises(ValidationError):
            self.env["pms.reservation"].create(
                {
                    "checkin": fields.date.today(),
                    "checkout": fields.date.today() + datetime.timedelta(days=3),
                    "pms_property_id": self.property2.id,
                    "partner_id": self.host1.id,
                    "room_type_id": self.room_type_double.id,
                    "preferred_room_id": self.room1.id,
                }
            )

    @freeze_time("2012-01-14")
    def test_shared_folio_true(self):
        """
        Check that the shared_folio field of a reservation whose
        folio has other reservations is True.
        ---------
        Create a reservation and then create another reservation with
        its folio_id = folio_id of the previous reservation. This
        should set shared_folio to True
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )
        self.reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=60),
                "checkout": fields.date.today() + datetime.timedelta(days=65),
                "pms_property_id": self.pms_property1.id,
                "partner_id": self.host1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        self.reservation2 = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=60),
                "checkout": fields.date.today() + datetime.timedelta(days=64),
                "pms_property_id": self.pms_property1.id,
                "partner_id": self.host1.id,
                "folio_id": self.reservation.folio_id.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        self.assertTrue(
            self.reservation.shared_folio,
            "Folio.reservations > 1, so reservation.shared_folio must be True",
        )

    @freeze_time("2012-01-14")
    def test_shared_folio_false(self):
        """
        Check that the shared_folio field for a reservation whose folio has no
        other reservations is False.
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )
        self.reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=60),
                "checkout": fields.date.today() + datetime.timedelta(days=65),
                "pms_property_id": self.pms_property1.id,
                "partner_id": self.host1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        self.assertFalse(
            self.reservation.shared_folio,
            "Folio.reservations = 1, so reservation.shared_folio must be False",
        )

    @freeze_time("2012-01-14")
    def test_reservation_action_cancel_fail(self):
        """
        Check that a reservation cannot be in the cancel state if
        the cancellation is not allowed.
        ---------
         Create a reservation, put its state = "canceled" and then try to
         pass its state to cancel using the action_cancel () method. This
         should throw an error because a reservation with state cancel cannot
         be canceled again.
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )
        reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "room_type_id": self.room_type_double.id,
                "partner_id": self.host1.id,
                "pms_property_id": self.pms_property1.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        with self.assertRaises(ValidationError):
            reservation.state = "cancel"

    @freeze_time("2012-01-14")
    def test_cancelation_reason_noshow(self):
        """
        Check that if a reservation has already passed and there is no check-in,
        the reason for cancellation must be 'no-show'
        ------
        Create a cancellation rule that is assigned to a pricelist. Then create
        a reservation with a past date and the action_cancel method is launched.
        The canceled_reason field is verified to be is equal to "no_show"
        """
        Pricelist = self.env["product.pricelist"]
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "pms_property_ids": [self.pms_property1.id],
                "penalty_noshow": 50,
            }
        )

        self.pricelist = Pricelist.create(
            {
                "name": "Pricelist Test",
                "pms_property_ids": [self.pms_property1.id],
                "cancelation_rule_id": self.cancelation_rule.id,
                "availability_plan_id": self.availability_plan1.id,
                "is_pms_available": True,
            }
        )
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )

        reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=-5),
                "checkout": fields.date.today() + datetime.timedelta(days=3),
                "room_type_id": self.room_type_double.id,
                "partner_id": self.host1.id,
                "pms_property_id": self.pms_property1.id,
                "pricelist_id": self.pricelist.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        reservation.action_cancel()
        reservation.flush()
        self.assertEqual(
            reservation.cancelled_reason,
            "noshow",
            "If reservation has already passed and no checkin,"
            "cancelled_reason must be 'noshow'",
        )

    @freeze_time("2012-01-14")
    def test_cancelation_reason_intime(self):
        """
        Check that if a reservation is canceled on time according
        to the cancellation rules the canceled_reason field must be "intime"
        ------
        Create a cancellation rule assigned to a price list with
        the field days_intime = 3. Then create a reservation with
        a checkin date within 5 days and launch the action_cancel method.
        canceled_reason field must be "intime"
        """
        Pricelist = self.env["product.pricelist"]
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "pms_property_ids": [self.pms_property1.id],
                "days_intime": 3,
            }
        )

        self.pricelist = Pricelist.create(
            {
                "name": "Pricelist Test",
                "pms_property_ids": [self.pms_property1.id],
                "cancelation_rule_id": self.cancelation_rule.id,
                "availability_plan_id": self.availability_plan1.id,
                "is_pms_available": True,
            }
        )
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )

        reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=5),
                "checkout": fields.date.today() + datetime.timedelta(days=8),
                "room_type_id": self.room_type_double.id,
                "partner_id": self.host1.id,
                "pms_property_id": self.pms_property1.id,
                "pricelist_id": self.pricelist.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        reservation.action_cancel()
        reservation.flush()

        self.assertEqual(
            reservation.cancelled_reason, "intime", "Cancelled reason must be 'intime'"
        )

    @freeze_time("2012-01-14")
    def test_cancelation_reason_late(self):
        """
        Check that if a reservation is canceled outside the cancellation
        period, the canceled_reason field of the reservation must be "late" .
        ---------
        Create a cancellation rule with the field days_intime = 3.
        A reservation is created with a checkin date for tomorrow and the
        action_cancel() method is launched. As the reservation was canceled
        after the deadline, the canceled_reason field must be late
        """
        Pricelist = self.env["product.pricelist"]
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "pms_property_ids": [self.pms_property1.id],
                "days_intime": 3,
            }
        )

        self.pricelist = Pricelist.create(
            {
                "name": "Pricelist Test",
                "pms_property_ids": [self.pms_property1.id],
                "cancelation_rule_id": self.cancelation_rule.id,
                "availability_plan_id": self.availability_plan1.id,
                "is_pms_available": True,
            }
        )
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Host1",
            }
        )

        reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=1),
                "checkout": fields.date.today() + datetime.timedelta(days=4),
                "room_type_id": self.room_type_double.id,
                "partner_id": self.host1.id,
                "pms_property_id": self.pms_property1.id,
                "pricelist_id": self.pricelist.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        reservation.action_cancel()
        reservation.flush()
        self.assertEqual(reservation.cancelled_reason, "late", "-----------")

    @freeze_time("2012-01-14")
    def test_compute_checkin_partner_count(self):
        """
        Check that the number of guests of a reservation is equal
        to the checkin_partner_count field of that same reservation.
        -------------
        Create 2 checkin partners. Create a reservation with those
        two checkin partners. The checkin_partner_count field must
        be equal to the number of checkin partners in the reservation.
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Miguel",
                "mobile": "654667733",
                "email": "miguel@example.com",
            }
        )
        self.host2 = self.env["res.partner"].create(
            {
                "name": "Brais",
                "mobile": "654437733",
                "email": "brais@example.com",
            }
        )
        self.reservation = self.env["pms.reservation"].create(
            {
                "checkin": "2012-01-14",
                "checkout": "2012-01-17",
                "partner_id": self.host1.id,
                "pms_property_id": self.pms_property1.id,
                "adults": 3,
                "room_type_id": self.room_type_triple.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        self.checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": self.host1.id,
                "reservation_id": self.reservation.id,
            }
        )
        self.checkin2 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": self.host2.id,
                "reservation_id": self.reservation.id,
            }
        )

        self.reservation.checkin_partner_ids = [
            (6, 0, [self.checkin1.id, self.checkin2.id])
        ]

        self.assertEqual(
            self.reservation.checkin_partner_count,
            len(self.reservation.checkin_partner_ids),
            "Checkin_partner_count must be match with number of checkin_partner_ids",
        )

    @freeze_time("2012-01-14")
    def test_compute_checkin_partner_pending_count(self):
        """
        Check that the checkin_partner_count field gives
        the expected result.
        --------------
        Create a reservation with 3 adults and associate 2
        checkin partners with that reservation. The
        checkin_partner_pending_count field must be the
        same as the difference between the adults in the
        reservation and the number of checkin_partner_ids in
        the reservation
        """
        self.host1 = self.env["res.partner"].create(
            {
                "name": "Miguel",
                "mobile": "654667733",
                "email": "miguel@example.com",
            }
        )
        self.host2 = self.env["res.partner"].create(
            {
                "name": "Brais",
                "mobile": "654437733",
                "email": "brais@example.com",
            }
        )
        self.reservation = self.env["pms.reservation"].create(
            {
                "checkin": "2012-01-14",
                "checkout": "2012-01-17",
                "partner_id": self.host1.id,
                "pms_property_id": self.pms_property1.id,
                "room_type_id": self.room_type_triple.id,
                "adults": 3,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        self.checkin1 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": self.host1.id,
                "reservation_id": self.reservation.id,
            }
        )
        self.checkin2 = self.env["pms.checkin.partner"].create(
            {
                "partner_id": self.host2.id,
                "reservation_id": self.reservation.id,
            }
        )

        self.reservation.checkin_partner_ids = [
            (6, 0, [self.checkin1.id, self.checkin2.id])
        ]

        count_expected = self.reservation.adults - len(
            self.reservation.checkin_partner_ids
        )
        self.assertEqual(
            self.reservation.checkin_partner_pending_count,
            count_expected,
            "Checkin_partner_pending_count isn't correct",
        )

    @freeze_time("2012-01-14")
    def test_reservation_action_checkout_fail(self):
        """
        Check that a reservation cannot be checkout because
        the checkout is not allowed.
        ---------------
        Create a reservation and try to launch the action_reservation_checkout
        method, but this should throw an error, because for the
        checkout to be allowed, the reservation must be in "onboard"
        or "departure_delayed" state
        """
        host = self.env["res.partner"].create(
            {
                "name": "Miguel",
                "mobile": "654667733",
                "email": "miguel@example.com",
            }
        )
        reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today(),
                "checkout": fields.date.today() + datetime.timedelta(days=1),
                "partner_id": host.id,
                "allowed_checkout": True,
                "pms_property_id": self.pms_property1.id,
                "room_type_id": self.room_type_double.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        with self.assertRaises(UserError):
            reservation.action_reservation_checkout()

    @freeze_time("2012-01-14")
    def test_partner_name_folio(self):
        """
        Check that a reservation without a partner_name
        is associated with the partner_name of its folio
        ----------
        Create a folio with a partner_name. Then create a
        reservation with folio_id = folio.id and without
        partner_name. The partner name of the reservation
        and the folio must be the same
        """

        # ARRANGE
        self.folio1 = self.env["pms.folio"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "partner_name": "Solón",
            }
        )

        self.reservation = self.env["pms.reservation"].create(
            {
                "checkin": "2012-01-14",
                "checkout": "2012-01-17",
                "pms_property_id": self.pms_property1.id,
                "folio_id": self.folio1.id,
                "room_type_id": self.room_type_double.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ACT AND ASSERT
        self.assertEqual(
            self.folio1.partner_name,
            self.reservation.partner_name,
            "The folio partner name and the reservation partner name doesn't correspond",
        )

    @freeze_time("2012-01-14")
    def test_partner_is_agency_not_invoice_to_agency(self):
        """
        Check that a reservation without partner_name but with
        an agency whose field invoice_to_agency = False will
        be set as partner_name "Reservation_from (agency name)"
        -------------
        Create an agency with invoice_to_agency = False
        and then create a reservation to which that agency
        assigns but does not associate any partner.
        Then check that the partner_name of that reservation is "Reservation from (agency name)"
        """
        sale_channel1 = self.env["pms.sale.channel"].create(
            {"name": "Test Indirect", "channel_type": "indirect"}
        )
        agency = self.env["res.partner"].create(
            {
                "name": "partner1",
                "is_agency": True,
                "sale_channel_id": sale_channel1.id,
            }
        )

        reservation = self.env["pms.reservation"].create(
            {
                "pms_property_id": self.pms_property1.id,
                "checkin": fields.date.today() + datetime.timedelta(days=150),
                "checkout": fields.date.today() + datetime.timedelta(days=152),
                "agency_id": agency.id,
                "room_type_id": self.room_type_double.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        reservation.flush()

        self.assertEqual(
            reservation.partner_name,
            "Reservation from " + agency.name,
            "Partner name doesn't match with to the expected",
        )

    @freeze_time("2010-11-10")
    def test_cancel_discount_board_service(self):
        """
        When a reservation is cancelled, service discount in case of board_services
        must be equal to the discounts of each reservation_line.

        """

        # ARRANGE
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "penalty_noshow": 50,
                "apply_on_noshow": "all",
            }
        )

        self.pricelist1.cancelation_rule_id = self.cancelation_rule.id

        self.product = self.env["product.product"].create(
            {
                "name": "Product test",
                "per_day": True,
                "consumed_on": "after",
            }
        )
        self.board_service = self.env["pms.service"].create(
            {
                "is_board_service": True,
                "product_id": self.product.id,
            }
        )

        self.room_type_double.list_price = 25
        reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=-3),
                "checkout": fields.date.today() + datetime.timedelta(days=3),
                "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,
                "service_ids": [self.board_service.id],
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ACTION
        reservation.action_cancel()
        reservation.flush()
        # ASSERT
        self.assertEqual(
            reservation.reservation_line_ids.mapped("cancel_discount")[0],
            reservation.service_ids.service_line_ids.mapped("cancel_discount")[0],
            "Cancel discount of reservation service lines must be the same "
            "that reservation board services",
        )

    @freeze_time("2011-10-10")
    def _test_cancel_discount_reservation_line(self):
        """
        When a reservation is cancelled, cancellation discount is given
        by the cancellation rule associated with the reservation pricelist.
        Each reservation_line calculates depending on the cancellation
        reason which is the correspondig discount. In this case the
        cancellation reason is'noshow' and the rule specifies that 50% must
        be reducted every day, that is, on each of reseravtion_lines
        """
        # ARRANGE
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "penalty_noshow": 50,
                "apply_on_noshow": "all",
            }
        )

        self.pricelist1.cancelation_rule_id = self.cancelation_rule.id

        self.room_type_double.list_price = 50
        reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=-3),
                "checkout": fields.date.today() + datetime.timedelta(days=3),
                "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,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        # ACTION
        reservation.action_cancel()
        reservation.flush()

        # ASSERT
        self.assertEqual(
            set(reservation.reservation_line_ids.mapped("cancel_discount")),
            {self.cancelation_rule.penalty_noshow},
            "Cancel discount of reservation_lines must be equal than cancellation rule penalty",
        )

    @freeze_time("2011-11-11")
    def test_cancel_discount_service(self):
        """
        When a reservation is cancelled, service discount in
        services that are not board_services ALWAYS have to be 100%,
        refardless of the cancellation rule associated with the pricelist
        """
        # ARRANGE
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "penalty_noshow": 50,
                "apply_on_noshow": "all",
            }
        )

        self.pricelist1.cancelation_rule_id = self.cancelation_rule.id

        self.product = self.env["product.product"].create(
            {
                "name": "Product test",
                "per_day": True,
                "consumed_on": "after",
                "is_extra_bed": True,
            }
        )
        self.service = self.env["pms.service"].create(
            {
                "is_board_service": False,
                "product_id": self.product.id,
            }
        )

        reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=-3),
                "checkout": fields.date.today() + datetime.timedelta(days=3),
                "preferred_room_id": self.room1.id,
                "partner_id": self.partner1.id,
                "pms_property_id": self.pms_property1.id,
                "pricelist_id": self.pricelist1.id,
                "service_ids": [self.service.id],
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        expected_cancel_discount = 100

        # ACTION
        reservation.action_cancel()
        reservation.flush()
        # ASSERT
        self.assertEqual(
            expected_cancel_discount,
            reservation.service_ids.service_line_ids.mapped("cancel_discount")[0],
            "Cancel discount of services must be 100%",
        )

    @freeze_time("2011-06-06")
    def test_discount_in_service(self):
        """
        Discount in pms.service is calculated from the
        discounts that each if its service lines has,
        in this case when reservation is cancelled a
        50% cancellation discount is applied and
        there aren't other different discounts
        """

        # ARRANGE
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "penalty_noshow": 50,
                "apply_on_noshow": "all",
            }
        )

        self.pricelist1.cancelation_rule_id = self.cancelation_rule.id

        self.product = self.env["product.product"].create(
            {
                "name": "Product test",
                "per_day": True,
                "consumed_on": "after",
            }
        )
        self.board_service = self.env["pms.service"].create(
            {
                "is_board_service": True,
                "product_id": self.product.id,
            }
        )

        self.room_type_double.list_price = 25
        reservation = self.env["pms.reservation"].create(
            {
                "checkin": fields.date.today() + datetime.timedelta(days=-3),
                "checkout": fields.date.today() + datetime.timedelta(days=3),
                "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,
                "service_ids": [self.board_service.id],
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        # ACTION
        reservation.action_cancel()
        reservation.flush()

        expected_discount = sum(
            sl.price_day_total * sl.cancel_discount / 100
            for sl in self.board_service.service_line_ids
        )
        # ASSERT
        self.assertEqual(
            expected_discount,
            self.board_service.discount,
            "Service discount must be the sum of its services_lines discount",
        )

    @freeze_time("2011-11-11")
    def test_services_discount_in_reservation(self):
        """
        Services discount in reservation is equal to the sum of the discounts of all
        its services, whether they are board_services or not
        """
        # ARRANGE
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "penalty_noshow": 50,
                "apply_on_noshow": "all",
            }
        )

        self.pricelist1.cancelation_rule_id = self.cancelation_rule.id

        self.product1 = self.env["product.product"].create(
            {
                "name": "Product test1",
                "per_day": True,
                "consumed_on": "after",
                "is_extra_bed": True,
            }
        )
        self.service = self.env["pms.service"].create(
            {
                "is_board_service": False,
                "product_id": self.product1.id,
            }
        )
        self.service.flush()
        self.product2 = self.env["product.product"].create(
            {
                "name": "Product test 2",
                "per_person": True,
                "consumed_on": "after",
            }
        )
        self.board_service = self.env["pms.service"].create(
            {
                "is_board_service": True,
                "product_id": self.product2.id,
            }
        )

        self.room_type_double.list_price = 25
        checkin = fields.date.today() + datetime.timedelta(days=-3)
        checkout = fields.date.today() + datetime.timedelta(days=3)
        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,
                "service_ids": [self.service.id, self.board_service.id],
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        # ACTION
        reservation.action_cancel()
        reservation.flush()

        expected_discount = sum(s.discount for s in reservation.service_ids)

        # ASSERT
        self.assertEqual(
            expected_discount,
            reservation.services_discount,
            "Services discount isn't the expected",
        )

    @freeze_time("2011-12-12")
    def _test_price_services_in_reservation(self):
        """
        Service price total in a reservation corresponds to the sum of prices
        of all its services less the total discount of that services
        """
        # ARRANGE
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "penalty_noshow": 50,
                "apply_on_noshow": "all",
            }
        )

        self.pricelist1.cancelation_rule_id = self.cancelation_rule.id

        self.product1 = self.env["product.product"].create(
            {
                "name": "Product test1",
                "per_day": True,
                "consumed_on": "after",
                "is_extra_bed": True,
            }
        )
        self.service = self.env["pms.service"].create(
            {
                "is_board_service": False,
                "product_id": self.product1.id,
            }
        )
        self.service.flush()
        self.product2 = self.env["product.product"].create(
            {
                "name": "Product test 2",
                "per_person": True,
                "consumed_on": "after",
            }
        )
        self.board_service = self.env["pms.service"].create(
            {
                "is_board_service": True,
                "product_id": self.product2.id,
            }
        )

        self.room_type_double.list_price = 25
        checkin = fields.date.today() + datetime.timedelta(days=-3)
        checkout = fields.date.today() + datetime.timedelta(days=3)
        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,
                "service_ids": [self.service.id, self.board_service.id],
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        # ACTION
        reservation.action_cancel()
        reservation.flush()
        expected_price = round(
            (
                self.service.price_total
                + self.board_service.price_total * reservation.adults
            )
            - reservation.services_discount,
            2,
        )
        # ASSERT
        self.assertEqual(
            expected_price,
            reservation.price_services,
            "Services price isn't the expected",
        )

    @freeze_time("2011-08-08")
    def test_room_discount_in_reservation(self):
        """
        Discount in pms.reservation is calculated from the
        discounts that each if its reservation lines has,
        in this case when reservation is cancelled a 50%
        cancellation discount is applied and
        there aren't other different discounts
        """
        # ARRANGE
        self.cancelation_rule = self.env["pms.cancelation.rule"].create(
            {
                "name": "Cancelation Rule Test",
                "penalty_noshow": 50,
                "apply_on_noshow": "all",
            }
        )

        self.pricelist1.cancelation_rule_id = self.cancelation_rule.id

        self.room_type_double.list_price = 30
        checkin = fields.date.today() + datetime.timedelta(days=-3)
        checkout = fields.date.today() + datetime.timedelta(days=3)
        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,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        # ACTION
        reservation.action_cancel()
        reservation.flush()

        expected_discount = sum(
            rl.price * rl.cancel_discount / 100
            for rl in reservation.reservation_line_ids
        )

        # ASSERT
        self.assertEqual(
            expected_discount,
            reservation.discount,
            "Room discount isn't the expected",
        )

    @freeze_time("2012-01-14")
    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)
        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,
            }
        )
        # 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,
                "folio_id": folio1.id,
            }
        )
        # ASSERT
        self.assertEqual(
            reservation.reservation_type,
            "normal",
            "The default reservation type should be 'normal'",
        )

    @freeze_time("2012-01-14")
    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,
                "sale_channel_origin_id": self.sale_channel_direct.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",
        )

    @freeze_time("2012-01-14")
    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",
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ASSERT
        self.assertEqual(
            reservation.price_total,
            0.0,
            "The expected price of the reservation is not correct",
        )

    @freeze_time("2012-01-14")
    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)
        closure_reason = self.env["room.closure.reason"].create(
            {
                "name": "test closure reason",
                "description": "test clopsure reason description",
            }
        )
        # 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",
                "closure_reason_id": closure_reason.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ASSERT
        self.assertEqual(
            reservation.price_total,
            0.0,
            "The expected price of the reservation is not correct",
        )

    # @freeze_time("2012-01-14")
    # 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",
    #             "sale_channel_origin_id": self.sale_channel_direct.id,
    #         }
    #     )
    #
    #     self.assertFalse(
    #         reservation.pricelist_id,
    #         "The pricelist of a staff reservation should be False",
    #     )

    @freeze_time("2012-01-14")
    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)
        closure_reason = self.env["room.closure.reason"].create(
            {
                "name": "test closure reason",
                "description": "test clopsure reason description",
            }
        )
        # 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",
                "closure_reason_id": closure_reason.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        self.assertFalse(
            reservation.pricelist_id,
            "The pricelist of a out of service reservation should be False",
        )

    @freeze_time("2012-01-14")
    def test_reservation_type_by_folio(self):
        """
        Check that the reservation type field in a reservation is the
        same as the reservation type on the folio that contains
        that reservation.
        --------------------------
        A folio is created with the field reservation_type as 'staff'.
        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 reservation is the same that reservation_type in the folio:
        '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,
                "reservation_type": "staff",
            }
        )

        reservation1 = 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(
            reservation1.reservation_type,
            "staff",
            "The reservation type of the folio should be 'staff'",
        )

    @freeze_time("2012-01-14")
    def test_no_partner_id_out_reservation(self):
        """
        Check that a reservation of type out of service does not
        have a partner_id.
        ------------------
        A reservation is created without a partner_id and with the
        value of the field reservation_type as '' out. Then it is
        checked that the partner_id field of the reservation is False
        """
        # ARRANGE
        checkin = fields.date.today()
        checkout = fields.date.today() + datetime.timedelta(days=3)
        closure_reason = self.env["room.closure.reason"].create(
            {
                "name": "test closure reason",
                "description": "test clopsure reason description",
            }
        )
        # ACT
        reservation = self.env["pms.reservation"].create(
            {
                "checkin": checkin,
                "checkout": checkout,
                "room_type_id": self.room_type_double.id,
                "pms_property_id": self.pms_property1.id,
                "reservation_type": "out",
                "closure_reason_id": closure_reason.id,
                "partner_name": "Install furniture",
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        self.assertFalse(
            reservation.partner_id,
            "The partner of an out of service reservation should be False",
        )

    @freeze_time("2012-01-14")
    def _test_create_partner_in_reservation(self):
        """
        Check that a res_partner is created from a reservation.
        ------------
        A reservation is created
        and a res.partner
        should also be created, which is what is checked after creating
        the reservation.
        """
        # ARRANGE
        checkin = fields.date.today()
        checkout = fields.date.today() + datetime.timedelta(days=3)
        self.id_category = self.env["res.partner.id_category"].create(
            {"name": "DNI", "code": "D"}
        )
        # ACT
        reservation = self.env["pms.reservation"].create(
            {
                "checkin": checkin,
                "checkout": checkout,
                "room_type_id": self.room_type_double.id,
                "pms_property_id": self.pms_property1.id,
                "partner_name": "Elis",
                "email": "elis@mail.com",
                "mobile": "61568547",
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ASSERT
        self.assertTrue(reservation.partner_id, "The partner has not been created")

    @freeze_time("2012-01-14")
    def test_auto_complete_partner_mobile(self):
        """
        It is checked that the mobile field of the reservation
        is correctly added to
        a res.partner that exists in
        the DB are put in the reservation.
        --------------------
        A res.partner is created with the name, mobile and email fields.
        Then it is verified that the mobile of the res.partner and that of
        the reservation are the same.
        """
        # ARRANGE
        partner = self.env["res.partner"].create(
            {
                "name": "Enrique",
                "mobile": "654667733",
                "email": "enrique@example.com",
            }
        )
        self.id_category = self.env["res.partner.id_category"].create(
            {"name": "DNI", "code": "D"}
        )
        self.document_id = self.env["res.partner.id_number"].create(
            {
                "category_id": self.id_category.id,
                "name": "61645604S",
                "partner_id": partner.id,
            }
        )
        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,
                "pms_property_id": self.pms_property1.id,
                "partner_id": partner.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ASSERT
        self.assertEqual(
            reservation.mobile,
            partner.mobile,
            "The partner mobile has not autocomplete in reservation",
        )

    @freeze_time("2012-01-14")
    def test_auto_complete_partner_email(self):
        """
        It is checked that the email field of the reservation
        is correctly added to
        a res.partner that exists in
        the DB are put in the reservation.
        --------------------
        A res.partner is created with the name, mobile and email fields.
        The document_id is added to the res.partner.
        Then it is verified that the email of the res.partner and that of
        the reservation are the same.
        """
        # ARRANGE
        partner = self.env["res.partner"].create(
            {
                "name": "Simon",
                "mobile": "654667733",
                "email": "simon@example.com",
            }
        )
        self.id_category = self.env["res.partner.id_category"].create(
            {"name": "DNI", "code": "D"}
        )
        self.document_id = self.env["res.partner.id_number"].create(
            {
                "category_id": self.id_category.id,
                "name": "74247377L",
                "partner_id": partner.id,
            }
        )
        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,
                "pms_property_id": self.pms_property1.id,
                "partner_id": partner.id,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ASSERT
        self.assertEqual(
            reservation.email,
            partner.email,
            "The partner email has not autocomplete in reservation",
        )

    @freeze_time("2012-01-14")
    def test_is_possible_customer_by_email(self):
        """
        It is checked that the field possible_existing_customer_ids
        exists in a reservation with an email from a res.partner saved
        in the DB.
        ----------------
        A res.partner is created with the name and email fields. A reservation
        is created by adding the same email as the res.partner. Then it is
        checked that some possible_existing_customer_ids exists.
        """
        # ARRANGE
        partner = self.env["res.partner"].create(
            {
                "name": "Courtney Campbell",
                "email": "courtney@example.com",
            }
        )
        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,
                "pms_property_id": self.pms_property1.id,
                "partner_name": partner.name,
                "email": partner.email,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ASSERT
        self.assertTrue(
            reservation.possible_existing_customer_ids,
            "No customer found with this email",
        )

    @freeze_time("2012-01-14")
    def test_is_possible_customer_by_mobile(self):
        """
        It is checked that the field possible_existing_customer_ids
        exists in a reservation with a mobile from a res.partner saved
        in the DB.
        ----------------
        A res.partner is created with the name and email fields. A reservation
        is created by adding the same mobile as the res.partner. Then it is
        checked that some possible_existing_customer_ids exists.
        """
        # ARRANGE
        partner = self.env["res.partner"].create(
            {
                "name": "Ledicia Sandoval",
                "mobile": "615369231",
            }
        )
        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,
                "pms_property_id": self.pms_property1.id,
                "partner_name": partner.name,
                "mobile": partner.mobile,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ASSERT
        self.assertTrue(
            reservation.possible_existing_customer_ids,
            "No customer found with this mobile",
        )

    @freeze_time("2012-01-14")
    def test_add_possible_customer(self):
        """
        Check that a partner was correctly added to the reservation
        after launching the add_partner() method of the several partners wizard
        ---------------
        A res.partner is created with name, email and mobile. A reservation is
        created with the email field equal to that of the res.partner created before.
        The wizard is created with the reservation id and the partner added to the
        possible_existing_customer_ids field. The add_partner method of the wizard
        is launched and it is checked that the partner was correctly added to the
        reservation.
        """
        # ARRANGE
        partner = self.env["res.partner"].create(
            {
                "name": "Serafín Rivas",
                "email": "serafin@example.com",
                "mobile": "60595595",
            }
        )
        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,
                "pms_property_id": self.pms_property1.id,
                "partner_name": partner.name,
                "email": partner.email,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        several_partners_wizard = self.env["pms.several.partners.wizard"].create(
            {
                "reservation_id": reservation.id,
                "possible_existing_customer_ids": [(6, 0, [partner.id])],
            }
        )

        several_partners_wizard.add_partner()
        # ASSERT
        self.assertEqual(
            reservation.partner_id.id,
            partner.id,
            "The partner was not added to the reservation ",
        )

    @freeze_time("2012-01-14")
    def test_not_add_several_possibles_customers(self):
        """
        Check that multiple partners cannot be added to a reservation
        from the several partners wizard.
        ---------------
        Two res.partner are created with name, email and mobile. A reservation is
        created with the email field equal to that of the partner1 created before.
        The wizard is created with the reservation id and the two partners added to the
        possible_existing_customer_ids field. The add_partner method of the wizard
        is launched and it is verified that a Validation_Error was raised.
        """
        # ARRANGE
        partner1 = self.env["res.partner"].create(
            {
                "name": "Serafín Rivas",
                "email": "serafin@example.com",
                "mobile": "60595595",
            }
        )
        partner2 = self.env["res.partner"].create(
            {
                "name": "Simon",
                "mobile": "654667733",
                "email": "simon@example.com",
            }
        )

        checkin = fields.date.today()
        checkout = fields.date.today() + datetime.timedelta(days=3)
        reservation = self.env["pms.reservation"].create(
            {
                "checkin": checkin,
                "checkout": checkout,
                "room_type_id": self.room_type_double.id,
                "pms_property_id": self.pms_property1.id,
                "partner_name": partner1.name,
                "email": partner1.email,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        several_partners_wizard = self.env["pms.several.partners.wizard"].create(
            {
                "reservation_id": reservation.id,
                "possible_existing_customer_ids": [(6, 0, [partner1.id, partner2.id])],
            }
        )

        # ACT AND ASSERT
        with self.assertRaises(
            ValidationError,
            msg="Two partners cannot be added to the reservation",
        ):
            several_partners_wizard.add_partner()

    @freeze_time("2012-01-14")
    def test_not_add_any_possibles_customers(self):
        """
        Check that the possible_existing_customer_ids field of the several
        partners wizard can be left empty and then launch the add_partner()
        method of this wizard to add a partner in reservation.
        ---------------
        A reservation is created. The wizard is created without the
        possible_existing_customer_ids field. The add_partner method of
        the wizard is launched and it is verified that a Validation_Error
        was raised.
        """

        # ARRANGE
        checkin = fields.date.today()
        checkout = fields.date.today() + datetime.timedelta(days=3)
        reservation = self.env["pms.reservation"].create(
            {
                "checkin": checkin,
                "checkout": checkout,
                "room_type_id": self.room_type_double.id,
                "pms_property_id": self.pms_property1.id,
                "partner_name": "Rosa Costa",
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )

        several_partners_wizard = self.env["pms.several.partners.wizard"].create(
            {
                "reservation_id": reservation.id,
            }
        )

        # ACT AND ASSERT
        with self.assertRaises(
            ValidationError,
            msg="A partner must be added to the reservation",
        ):
            several_partners_wizard.add_partner()

    @freeze_time("1991-11-10")
    def test_commission_amount_with_board_service(self):
        """
        Check if commission in reservation is correctly calculated
        when reservation has services and board_services

        Create a service that isn't board service.
        Create a service that is board service.
        Create a reservation with that service and board_service.

        In this case when the reservation is made through an agency
        that has a default commission, this commission is applied to the
        price of the room and the price of services that correspond with
        board service.

        """
        # ARRANGE
        self.product1 = self.env["product.product"].create(
            {
                "name": "Product test1",
                "per_day": True,
                "consumed_on": "after",
                "is_extra_bed": True,
            }
        )
        self.service = self.env["pms.service"].create(
            {
                "is_board_service": False,
                "product_id": self.product1.id,
                "pms_property_id": self.pms_property1.id,
            }
        )
        self.service.flush()
        self.product_test1 = self.env["product.product"].create(
            {
                "name": "Test Product 1",
                "per_day": True,
                "consumed_on": "after",
            }
        )
        self.board_service_test = self.env["pms.board.service"].create(
            {
                "name": "Test Board Service",
                "default_code": "TPS",
                "pms_property_ids": [self.pms_property1.id],
            }
        )

        self.env["pms.board.service.line"].create(
            {
                "pms_board_service_id": self.board_service_test.id,
                "product_id": self.product_test1.id,
                "amount": 8,
                "adults": True,
            }
        )
        self.board_service_room_type = self.env["pms.board.service.room.type"].create(
            {
                "pms_room_type_id": self.room_type_double.id,
                "pms_board_service_id": self.board_service_test.id,
                "pms_property_id": self.pms_property1.id,
            }
        )
        checkin = fields.date.today()
        checkout = checkin + datetime.timedelta(days=11)
        reservation_vals = {
            "checkin": checkin,
            "checkout": checkout,
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "agency_id": self.agency1.id,
            "service_ids": [self.service.id],
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }
        # ACT
        reservation = self.env["pms.reservation"].create(reservation_vals)
        reservation.write(
            {
                "board_service_room_id": self.board_service_room_type.id,
            }
        )

        self.commission = (
            reservation.price_total * self.agency1.default_commission / 100
        )
        for service in reservation.service_ids:
            if service.is_board_service:
                self.commission = (
                    self.commission
                    + service.price_total * self.agency1.default_commission / 100
                )
        # ASSERT
        self.assertEqual(
            self.commission,
            reservation.commission_amount,
            "Reservation commission is wrong",
        )

    @freeze_time("2012-01-14")
    def test_closure_reason_out_of_service_mandatory_not(self):
        """
        Ouf of service reservation should contain a closure reason id.
        -------------
        Create a reservation of type out of service and check if there's no
        closure reason id should raises an exception.
        """
        # ARRANGE
        checkin = fields.date.today()
        checkout = fields.date.today() + datetime.timedelta(days=1)
        # ACT & ASSERT
        with self.assertRaises(
            ValidationError,
            msg="The reservation has been created and it shouldn't, "
            "because it doesn't have a closure reason.",
        ):
            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",
                }
            )

    @freeze_time("2012-01-14")
    def test_closure_reason_out_of_service_mandatory(self):
        """
        Ouf of service reservation should contain a closure reason id.
        -------------
        Create a reservation of type out of service and with a closure reason.
        """
        # ARRANGE
        checkin = fields.date.today()
        checkout = fields.date.today() + datetime.timedelta(days=1)

        closure_reason = self.env["room.closure.reason"].create(
            {
                "name": "Room revision",
                "description": "Revision of lights, "
                "fire extinguishers, smoke detectors and "
                "emergency lights",
            }
        )
        # ACT
        reservation_out = 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",
                "closure_reason_id": closure_reason,
                "sale_channel_origin_id": self.sale_channel_direct.id,
            }
        )
        # ASSERT
        self.assertTrue(
            reservation_out.closure_reason_id,
            "The out of service reservation should be created properly with "
            "a closure reason.",
        )

    # tests for several sale channels in reservation
    @freeze_time("2000-11-10")
    def test_reservation_sale_channel_origin_in_reservation_lines(self):
        """
        Check that reservation_lines have sale_channel_id
        corresponding to sale_channel_origin_id of their reservation

        When a reservation was created with a sale channel, it corresponds
        to the sale_channel_origin.
        Reservation lines will have as sale_channel_id the sale_channel_origin_id
        of reservation when creating them

        """
        # ARRANGE
        checkin = fields.date.today()
        checkout = checkin + datetime.timedelta(days=3)
        reservation_vals = {
            "checkin": checkin,
            "checkout": checkout,
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }

        # ACT
        reservation = self.env["pms.reservation"].create(reservation_vals)

        # ASSERT
        self.assertEqual(
            reservation.sale_channel_origin_id,
            reservation.reservation_line_ids.mapped("sale_channel_id"),
            "Sale channel of reservation lines must be the same that their reservation",
        )

    @freeze_time("2000-10-10")
    def test_reservation_sale_channel_origin_in_folio(self):
        """
        Check that folio have sale_channel_origin_id
        corresponding to sale_channel_origin_id of the reservation
        that was created before the folio

        When a reservation was created with a sale channel, it corresponds
        to the sale_channel_origin.
        If reservation didn't have folio previously, the folio to be created
        will have the same sale_channel_origin as the reservation

        """
        # ARRANGE
        checkin = fields.date.today()
        checkout = checkin + datetime.timedelta(days=3)
        reservation_vals = {
            "checkin": checkin,
            "checkout": checkout,
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }

        # ACT
        reservation = self.env["pms.reservation"].create(reservation_vals)

        # ASSERT
        self.assertEqual(
            reservation.sale_channel_origin_id,
            reservation.folio_id.sale_channel_origin_id,
            "Sale channel of folio must be the same that it reservation",
        )

    @freeze_time("2001-10-15")
    def test_reservation_sale_channel_origin_of_folio(self):
        """
        Check that the reservation has sale_channel_origin_id
        as the folio sale_channel_origin_id in
        which reservation was created when a folio has already
        another reservations.

        Testing whether it works when the folio sale_channel_origin_id
        is given by a previously created reservation

        When a reservation is created on a folio
        that already has a sale_channel_origin
        that reservation will have the same sale_channel_origin

        """
        # ARRANGE
        reservation_vals = {
            "checkin": datetime.datetime.now(),
            "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }
        reservation1 = self.env["pms.reservation"].create(reservation_vals)
        # ACT
        reservation2 = self.env["pms.reservation"].create(
            {
                "checkin": datetime.datetime.now(),
                "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
                "adults": 2,
                "room_type_id": self.room_type_double.id,
                "partner_id": self.partner1.id,
                "folio_id": reservation1.folio_id.id,
            }
        )
        # ASSERT
        self.assertEqual(
            reservation1.sale_channel_origin_id.id,
            reservation2.sale_channel_origin_id.id,
            "Sale channel of reservations must be the same",
        )

    @freeze_time("2000-10-19")
    def test_reservation_lines_same_sale_channel(self):
        """
        Check if sale_channel_ids of reservation correspond to
        sale_channel_id of its reservation.

        In this case, the reservation has several reservation_lines
        with the same sale_channel_id. Reservation lines are created
        with sale_channel_origin_id of the reservation and haven't been
        modified.

        """
        # ARRANGE
        reservation_vals = {
            "checkin": datetime.datetime.now(),
            "checkout": datetime.datetime.now() + datetime.timedelta(days=4),
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }
        # ACT
        reservation1 = self.env["pms.reservation"].create(reservation_vals)

        # ASSERT
        self.assertEqual(
            reservation1.sale_channel_ids,
            reservation1.reservation_line_ids.mapped("sale_channel_id"),
            "Sale_channel_ids of reservation must be the same as "
            "sale channels of its reservation lines",
        )

    @freeze_time("2000-10-24")
    def test_reservation_sale_channel_origin_change_check_lines(self):
        """
        Check that sale_channel_id of reservation_lines changes when
        sale_channel_origin_id of its reservation has changed
        """
        # ARRANGE
        sale_channel_direct2 = self.env["pms.sale.channel"].create(
            {
                "name": "sale channel 2",
                "channel_type": "direct",
            }
        )
        reservation_vals = {
            "checkin": datetime.datetime.now(),
            "checkout": datetime.datetime.now() + datetime.timedelta(days=4),
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }
        reservation1 = self.env["pms.reservation"].create(reservation_vals)

        # ACT
        reservation1.sale_channel_origin_id = sale_channel_direct2.id

        # ASSERT
        self.assertEqual(
            reservation1.sale_channel_origin_id,
            reservation1.reservation_line_ids.mapped("sale_channel_id"),
            "Sale_channel_id of reservation lines must also be changed",
        )

    @freeze_time("2000-10-29")
    def test_reservation_lines_not_change_sale_channel(self):
        """
            Check that when changing sale_channel_origin_id of a reservation,
            reservation lines that didn't have the same sale_channel_id didn't
            change it

            Reservation1:
                --> sale_channel_origin_id : sale_channel1.id
                --> reservation_lines:
                       --> 1: sale_channel_id: sale_channel1.id
                       --> 2: sale_channel_id: sale_channel1.id
                       --> 3: sale_channel_id: sale_channel1.id
                       --> 4: sale_channel_id: sale_channel_phone.id

            Change reservation1.sale_channel_origin_id = sale_channel_mail.id

            Expected result:
            Reservation1:
               --> sale_channel_origin_id : sale_channel_mail.id
               --> reservation_lines:
                    --> 1: sale_channel_id: sale_channel_mail.id
                    --> 2: sale_channel_id: sale_channel_mail.id
                    --> 3: sale_channel_id: sale_channel_mail.id
                    --> 4: sale_channel_id: sale_channel_phone.id

        In short, sale channel of those reservations lines of the reservation
        that didn't coincide with sale chanel origin that has been modified,
        shouldn't be changed. That is, the last reservation_line must have
        sale_channel_id = sale_channel_phone
        """
        # ARRANGE
        sale_channel_phone = self.env["pms.sale.channel"].create(
            {
                "name": "phone",
                "channel_type": "direct",
            }
        )
        sale_channel_mail = self.env["pms.sale.channel"].create(
            {
                "name": "mail",
                "channel_type": "direct",
            }
        )
        reservation_vals = {
            "checkin": datetime.datetime.now(),
            "checkout": datetime.datetime.now() + datetime.timedelta(days=4),
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }
        reservation1 = self.env["pms.reservation"].create(reservation_vals)

        # ACT
        reservation_lines = reservation1.reservation_line_ids
        reservation_lines[
            len(reservation_lines) - 1
        ].sale_channel_id = sale_channel_phone.id

        reservation1.sale_channel_origin_id = sale_channel_mail

        # ASSERT
        self.assertNotEqual(
            reservation1.sale_channel_origin_id,
            reservation_lines[len(reservation_lines) - 1].sale_channel_id,
            "Sale_channel_id of that reservation line shouldn't have changed",
        )

    @freeze_time("2000-11-29")
    def test_several_sale_channel_in_lines(self):
        """
        Check that when a reservation has more than one sale_channel_id
        in its reservation_lines, sale_channel_ids of reservation is well
        calculated
        """
        # ARRANGE
        sale_channel_phone = self.env["pms.sale.channel"].create(
            {
                "name": "phone",
                "channel_type": "direct",
            }
        )
        reservation_vals = {
            "checkin": datetime.datetime.now(),
            "checkout": datetime.datetime.now() + datetime.timedelta(days=4),
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }
        reservation1 = self.env["pms.reservation"].create(reservation_vals)

        # ACT
        reservation_lines = reservation1.reservation_line_ids
        reservation_lines[0].sale_channel_id = sale_channel_phone.id

        expected_sale_channels = []
        for line in reservation_lines:
            expected_sale_channels.append(line.sale_channel_id.id)

        # ASSERT
        self.assertItemsEqual(
            reservation1.sale_channel_ids.ids,
            list(set(expected_sale_channels)),
            "Sale_channel_ids of that reservation must match those of its lines",
        )

    @freeze_time("2000-12-01")
    def test_reservation_no_sale_channel_origin(self):
        """
        Check that you can't create a reservation without sale_channel_origin
        """
        # ACT & ASSERT
        with self.assertRaises(
            ValidationError,
            msg="Error, it has been allowed to create a reservation without sale channel",
        ):
            self.env["pms.reservation"].create(
                {
                    "room_type_id": self.room_type_double.id,
                    "partner_id": self.partner1.id,
                    "pms_property_id": self.pms_property1.id,
                    "checkin": datetime.datetime.now(),
                    "checkout": datetime.datetime.now() + datetime.timedelta(days=4),
                }
            )

    @freeze_time("2000-12-01")
    def test_one_reservation_change_sale_channel_origin(self):
        """
        Check that when changing the sale_channel_origin of a reservation,
        sale_channel_origin of its folio changes if folio only has one reservation
        """
        # ARRANGE
        sale_channel_phone = self.env["pms.sale.channel"].create(
            {
                "name": "phone",
                "channel_type": "direct",
            }
        )
        reservation_vals = {
            "checkin": datetime.datetime.now(),
            "checkout": datetime.datetime.now() + datetime.timedelta(days=4),
            "room_type_id": self.room_type_double.id,
            "partner_id": self.partner1.id,
            "pms_property_id": self.pms_property1.id,
            "sale_channel_origin_id": self.sale_channel_direct.id,
        }
        reservation1 = self.env["pms.reservation"].create(reservation_vals)

        # ACT
        reservation1.sale_channel_origin_id = sale_channel_phone.id

        # ASSERT
        self.assertEqual(
            reservation1.folio_id.sale_channel_origin_id,
            reservation1.sale_channel_origin_id,
            "Sale_channel_origin_id of folio must be the same as "
            "sale_channel_origin of rservation",
        )

    # TEMPORAL UNABLE (_check_lines_with_sale_channel_id in pms_reservation.py
    # unable to allow updagrade version)
    # @freeze_time("2000-12-10")
    # def test_check_sale_channel_origin_in_reservation_lines(self):
    #     """
    #     Check that a reservation has at least one reservation_line woth the
    #     same sale_channel_id as its sale_channel_origin_id
    #     """
    #     # ARRANGE
    #     sale_channel_phone = self.env["pms.sale.channel"].create(
    #         {
    #             "name": "phone",
    #             "channel_type": "direct",
    #         }
    #     )
    #     reservation_vals = {
    #         "checkin": datetime.datetime.now(),
    #         "checkout": datetime.datetime.now() + datetime.timedelta(days=1),
    #         "room_type_id": self.room_type_double.id,
    #         "partner_id": self.partner1.id,
    #         "pms_property_id": self.pms_property1.id,
    #         "sale_channel_origin_id": self.sale_channel_direct.id,
    #     }
    #     reservation1 = self.env["pms.reservation"].create(reservation_vals)
    #     reservation1.fetch()
    #     # ACT & ASSERT
    #     with self.assertRaises(
    #         ValidationError,
    #         msg="""
    #             Error, there cannot be a reservation
    #             in which at least one of its reservation
    #         """
    #         "lines doesn't have as sale_channel_id the sale_channel_origin_id of reservation",
    #     ):
    #         reservation1.reservation_line_ids.write(
    #             {"sale_channel_id": sale_channel_phone}
    #         )
    #         reservation1.flush()
