diff --git a/pms/models/pms_checkin_partner.py b/pms/models/pms_checkin_partner.py index 7a762d746..4e411646b 100644 --- a/pms/models/pms_checkin_partner.py +++ b/pms/models/pms_checkin_partner.py @@ -55,14 +55,16 @@ class PmsCheckinPartner(models.Model): ) # Compute - @api.depends("reservation_id", "folio_id", "reservation_id.room_id") + @api.depends("reservation_id", "folio_id", "reservation_id.preferred_room_id") def _compute_identifier(self): for record in self: # TODO: Identifier - if record.reservation_id.filtered("room_id"): + if record.reservation_id.filtered("preferred_room_id"): checkins = record.reservation_id.checkin_partner_ids record.identifier = ( - record.reservation_id.room_id.name + "-" + str(len(checkins) - 1) + record.reservation_id.preferred_room_id.name + + "-" + + str(len(checkins) - 1) ) elif record.folio_id: record.identifier = record.folio_id.name + "-" + str(len(checkins) - 1) @@ -77,18 +79,18 @@ class PmsCheckinPartner(models.Model): @api.depends(lambda self: self._checkin_mandatory_fields(), "reservation_id.state") def _compute_state(self): for record in self: + if not record.state: + record.state = "draft" if record.reservation_id.state == "cancelled": record.state = "cancelled" elif record.state in ("draft", "cancelled"): if any( - not getattr(self, field) + not getattr(record, field) for field in record._checkin_mandatory_fields() ): record.state = "draft" else: record.state = "precheckin" - elif not record.state: - record.state = "draft" def _checkin_mandatory_fields(self): return ["name", "email"] @@ -117,6 +119,22 @@ class PmsCheckinPartner(models.Model): _("This guest is already registered in the room") ) + # CRUD + @api.model + def create(self, vals): + # The checkin records are created automatically from adult depends + # if you try to create one manually, we update one unassigned checkin + if not self._context.get("auto_create_checkin"): + reservation_id = vals.get("reservation_id") + if reservation_id: + reservation = self.env["pms.reservation"].browse(reservation_id) + draft_checkins = reservation.checkin_partner_ids.filtered( + lambda c: c.state in ("draft") + ) + if len(draft_checkins) > 0 and vals.get("partner_id"): + draft_checkins[0].sudo().unlink() + return super(PmsCheckinPartner, self).create(vals) + # Action methods def action_on_board(self): diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py index a410d8bc3..c5ec14cea 100644 --- a/pms/models/pms_reservation.py +++ b/pms/models/pms_reservation.py @@ -572,7 +572,7 @@ class PmsReservation(models.Model): lambda c: c.state in ("precheckin", "onboard", "done") ) unassigned_checkins = reservation.checkin_partner_ids.filtered( - lambda c: c.state not in ("draft") + lambda c: c.state in ("draft") ) leftover_unassigneds_count = ( len(assigned_checkins) + len(unassigned_checkins) - reservation.adults @@ -582,8 +582,8 @@ class PmsReservation(models.Model): _("Remove some of the leftover assigned checkins first") ) elif leftover_unassigneds_count > 0: - for i in range(0, len(unassigned_checkins)): - unassigned_checkins[i].unlink() + for i in range(0, leftover_unassigneds_count): + unassigned_checkins[i].sudo().unlink() elif reservation.adults > len(reservation.checkin_partner_ids): checkins_lst = [] count_new_checkins = reservation.adults - len( @@ -599,7 +599,9 @@ class PmsReservation(models.Model): }, ) ) - reservation.checkin_partner_ids = checkins_lst + reservation.with_context( + {"auto_create_checkin": True} + ).checkin_partner_ids = checkins_lst @api.depends("checkin_partner_ids", "checkin_partner_ids.state") def _compute_count_pending_arrival(self): @@ -851,13 +853,25 @@ class PmsReservation(models.Model): ) ) - # @api.constrains("checkin_partner_ids", "adults") - # def _max_checkin_partner_ids(self): - # for record in self: - # if len(record.checkin_partner_ids) != record.adults: - # raise models.ValidationError( - # _("Reservation Adults and Checkins does not match") - # ) + @api.constrains("checkin_partner_ids", "adults") + def _max_checkin_partner_ids(self): + for record in self: + if len(record.checkin_partner_ids) > record.adults: + raise models.ValidationError(_("The room already is completed")) + + @api.constrains("adults") + def _check_adults(self): + for record in self: + extra_bed = record.service_ids.filtered( + lambda r: r.product_id.is_extra_bed is True + ) + for room in record.reservation_line_ids.room_id: + if record.adults + record.children_occupying > room.get_capacity( + len(extra_bed) + ): + raise ValidationError( + _("Persons can't be higher than room capacity") + ) # @api.constrains("reservation_type", "partner_id") # def _check_partner_reservation(self): @@ -880,12 +894,6 @@ class PmsReservation(models.Model): # _("Only the out reservations can has a clousure reason") # ) - # @api.onchange("checkin_partner_ids") - # def onchange_checkin_partner_ids(self): - # for record in self: - # if len(record.checkin_partner_ids) > record.adults + record.children: - # raise models.ValidationError(_("The room already is completed")) - # self._compute_tax_ids() TODO: refact # Action methods diff --git a/pms/models/pms_reservation_line.py b/pms/models/pms_reservation_line.py index e9252e7db..3415178ff 100644 --- a/pms/models/pms_reservation_line.py +++ b/pms/models/pms_reservation_line.py @@ -394,7 +394,7 @@ class PmsReservationLine(models.Model): # negative discounts (= surcharge) are included in the display price return max(base_price, final_price) - @api.constrains("reservation_id.adults", "room_id") + @api.constrains("room_id") def _check_adults(self): for record in self.filtered("room_id"): extra_bed = record.reservation_id.service_ids.filtered( diff --git a/pms/security/ir.model.access.csv b/pms/security/ir.model.access.csv index 02f4a382b..aeb970f96 100644 --- a/pms/security/ir.model.access.csv +++ b/pms/security/ir.model.access.csv @@ -8,7 +8,7 @@ user_access_pms_reservation_line,user_access_pms_reservation_line,model_pms_rese user_access_room_closure_reason,user_access_room_closure_reason,model_room_closure_reason,pms.group_pms_user,1,0,0,0 user_access_pms_service_line,user_access_pms_service_line,model_pms_service_line,pms.group_pms_user,1,1,1,1 user_access_pms_board_service,user_access_pms_board_service,model_pms_board_service,pms.group_pms_user,1,0,0,0 -user_access_pms_checkin_partner,user_access_pms_checkin_partner,model_pms_checkin_partner,pms.group_pms_user,1,1,1,1 +user_access_pms_checkin_partner,user_access_pms_checkin_partner,model_pms_checkin_partner,pms.group_pms_user,1,1,1,0 user_access_pms_room_type_class,user_access_pms_room_type_class,model_pms_room_type_class,pms.group_pms_user,1,0,0,0 user_access_pms_room,user_access_pms_room,model_pms_room,pms.group_pms_user,1,0,0,0 user_access_shared_pms_room,user_access_pms_shared_room,model_pms_shared_room,pms.group_pms_user,1,0,0,0 @@ -33,7 +33,7 @@ manager_access_pms_reservation_line,manager_access_pms_reservation_line,model_pm manager_access_room_closure_reason,manager_access_room_closure_reason,model_room_closure_reason,pms.group_pms_manager,1,1,1,1 manager_access_pms_service_line,manager_access_pms_service_line,model_pms_service_line,pms.group_pms_manager,1,1,1,1 manager_access_pms_board_service,manager_access_pms_board_service,model_pms_board_service,pms.group_pms_manager,1,1,1,1 -manager_access_pms_checkin_partner,manager_access_pms_checkin_partner,model_pms_checkin_partner,pms.group_pms_manager,1,1,1,1 +manager_access_pms_checkin_partner,manager_access_pms_checkin_partner,model_pms_checkin_partner,pms.group_pms_manager,1,1,1,0 manager_access_pms_room_type_class,manager_access_pms_room_type_class,model_pms_room_type_class,pms.group_pms_manager,1,1,1,1 manager_access_pms_room,manager_access_pms_room,model_pms_room,pms.group_pms_manager,1,1,1,1 manager_access_pms_shared_room,manager_access_pms_shared_room,model_pms_shared_room,pms.group_pms_manager,1,1,1,1 diff --git a/pms/tests/test_pms_checkin_partner.py b/pms/tests/test_pms_checkin_partner.py index e8346fdd5..7b53f97c2 100644 --- a/pms/tests/test_pms_checkin_partner.py +++ b/pms/tests/test_pms_checkin_partner.py @@ -41,6 +41,51 @@ class TestPmsCheckinPartner(TestHotel): } ) + def test_auto_create_checkins(self): + + # ACTION + self.arrange_single_checkin() + checkins_count = len(self.reservation_1.checkin_partner_ids) + + # ASSERT + self.assertEqual( + checkins_count, + 3, + "the automatic partner checkin was not created successful", + ) + + def test_auto_unlink_checkins(self): + + # ARRANGE + self.arrange_single_checkin() + + # ACTION + host2 = self.env["res.partner"].create( + { + "name": "Carlos", + "phone": "654667733", + "email": "carlos@example.com", + } + ) + self.reservation_1.checkin_partner_ids = [ + ( + 0, + False, + { + "partner_id": host2.id, + }, + ) + ] + + checkins_count = len(self.reservation_1.checkin_partner_ids) + + # ASSERT + self.assertEqual( + checkins_count, + 3, + "the automatic partner checkin was not updated successful", + ) + def test_onboard_checkin(self): # ARRANGE @@ -288,7 +333,6 @@ class TestPmsCheckinPartner(TestHotel): ) pending_checkin_data = self.reservation_1.pending_checkin_data ratio_checkin_data = self.reservation_1.ratio_checkin_data - # ASSERT self.assertEqual( pending_checkin_data, diff --git a/pms/views/pms_reservation_views.xml b/pms/views/pms_reservation_views.xml index f8a43f589..f7f7236f4 100644 --- a/pms/views/pms_reservation_views.xml +++ b/pms/views/pms_reservation_views.xml @@ -495,6 +495,7 @@