diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py index d844c7c7fc..42caeea24c 100644 --- a/pms/models/pms_reservation.py +++ b/pms/models/pms_reservation.py @@ -940,7 +940,6 @@ def _compute_reservation_line_ids(self): else: if not reservation.reservation_line_ids: reservation.reservation_line_ids = False - reservation.check_in_out_dates() @api.depends("board_service_room_id", "adults", "children") def _compute_board_service_ids(self): @@ -1199,7 +1198,6 @@ def _compute_checkin(self): record.checkin = record.folio_id.reservation_ids[0].checkin else: record.checkin = fields.date.today() - record.check_in_out_dates() @api.depends("reservation_line_ids", "checkin") def _compute_checkout(self): @@ -1218,13 +1216,11 @@ def _compute_checkout(self): # default checkout if checkin is set elif record.checkin and not record.checkout: if len(record.folio_id.reservation_ids) > 1: - record.checkin = record.folio_id.reservation_ids[0].checkout + record.checkout = record.folio_id.reservation_ids[0].checkout else: record.checkout = record.checkin + datetime.timedelta(days=1) elif not record.checkout: record.checkout = False - # date checking - record.check_in_out_dates() # pylint: disable=W8110 def _compute_precheckin_url(self): @@ -1767,6 +1763,7 @@ def _get_default_sale_channel_origin(self): sale_channel_origin_id = folio.sale_channel_origin_id return sale_channel_origin_id + @api.constrains("checkin", "checkout") def check_in_out_dates(self): """ 1.-When date_order is less then checkin date or @@ -1797,6 +1794,10 @@ def checkin_checkout_consecutive_dates(self): of the set of ordinal dates is one more than the length of the set """ for record in self: + if not record.reservation_line_ids: + # an inconsistent checkin/checkout pair builds no lines at all; + # check_in_out_dates is the one reporting it + continue if min(record.reservation_line_ids.mapped("date")) != record.checkin: raise UserError( _( diff --git a/pms/tests/test_pms_reservation.py b/pms/tests/test_pms_reservation.py index 3c19df3131..5fcb297d97 100644 --- a/pms/tests/test_pms_reservation.py +++ b/pms/tests/test_pms_reservation.py @@ -231,6 +231,90 @@ def test_reservation_dates_compute_checkin_out(self): not correspond to the last day indicated in the dates", ) + @freeze_time("2012-01-14") + def test_reservation_default_dates_from_folio(self): + """ + Check the dates defaulted to a reservation added to a folio that + already holds one. + ---------------- + A reservation created with neither dates nor reservation lines takes + them from the first reservation of its folio, so both stays run in + parallel. The checkout was being written on the checkin field, leaving + the new reservation without a checkout of its own. + """ + # ARRANGE + checkin = fields.date.today() + datetime.timedelta(days=8) + checkout = checkin + datetime.timedelta(days=2) + folio = self.env["pms.folio"].create( + { + "pms_property_id": self.pms_property1.id, + "partner_id": self.partner1.id, + "sale_channel_origin_id": self.sale_channel_direct.id, + } + ) + 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, + "folio_id": folio.id, + "sale_channel_origin_id": self.sale_channel_direct.id, + } + ) + + # 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, + "folio_id": folio.id, + "sale_channel_origin_id": self.sale_channel_direct.id, + } + ) + + # ASSERT + self.assertEqual( + reservation.checkin, + checkin, + "The reservation should start the day the folio does", + ) + self.assertEqual( + reservation.checkout, + checkout, + "The reservation should end the day the folio does", + ) + + @freeze_time("2012-01-14") + def test_reservation_checkout_before_checkin(self): + """ + Check that a reservation cannot end before it starts. + ---------------- + The dates are validated by a constraint, so the pair is checked once + both of them have been computed. + """ + # ARRANGE + checkin = fields.date.today() + datetime.timedelta(days=8) + + # ACT & ASSERT + with self.assertRaises( + UserError, + msg="Error, it has been allowed to create a reservation ending " + "before it starts", + ): + self.env["pms.reservation"].create( + { + "checkin": checkin, + "checkout": checkin - 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, + } + ) + @freeze_time("2012-01-14") def test_create_reservation_start_date(self): """