From 8884b44d456be18e354b2dfb2bee92e9bc5eb50c Mon Sep 17 00:00:00 2001 From: miguelpadin Date: Wed, 5 Jan 2022 11:38:47 +0100 Subject: [PATCH 1/2] [FIX] pms: add url @ property view --- pms_l10n_es/views/pms_property_views.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pms_l10n_es/views/pms_property_views.xml b/pms_l10n_es/views/pms_property_views.xml index 6e0e83900..bd2130bc6 100644 --- a/pms_l10n_es/views/pms_property_views.xml +++ b/pms_l10n_es/views/pms_property_views.xml @@ -44,6 +44,7 @@ +
From 739daf73d4f0363e847507f515e9bf67b44737b1 Mon Sep 17 00:00:00 2001 From: miguelpadin Date: Wed, 5 Jan 2022 18:26:21 +0100 Subject: [PATCH 2/2] [FIX] pms_l10n_es: fix ine statistics when not all checkins are done or onboard --- pms_l10n_es/tests/test_wizard_ine.py | 233 ++++++++++++++++++++++++--- pms_l10n_es/wizards/wizard_ine.py | 70 +++++++- 2 files changed, 281 insertions(+), 22 deletions(-) diff --git a/pms_l10n_es/tests/test_wizard_ine.py b/pms_l10n_es/tests/test_wizard_ine.py index fb4025278..867ec34f2 100644 --- a/pms_l10n_es/tests/test_wizard_ine.py +++ b/pms_l10n_es/tests/test_wizard_ine.py @@ -37,11 +37,19 @@ class TestWizardINE(TestPms): "capacity": 2, } ) - self.room_single_1 = self.env["pms.room"].create( + self.room_double_3 = self.env["pms.room"].create( { "pms_property_id": self.pms_property1.id, "name": "Room test 3", "room_type_id": self.room_type.id, + "capacity": 2, + } + ) + self.room_single_1 = self.env["pms.room"].create( + { + "pms_property_id": self.pms_property1.id, + "name": "Room test 4", + "room_type_id": self.room_type.id, "capacity": 1, "extra_beds_allowed": 1, } @@ -49,7 +57,7 @@ class TestWizardINE(TestPms): self.room_triple1 = self.env["pms.room"].create( { "pms_property_id": self.pms_property1.id, - "name": "Room test 4", + "name": "Room test 5", "room_type_id": self.room_type.id, "capacity": 3, } @@ -79,6 +87,8 @@ class TestWizardINE(TestPms): self.country_italy.ensure_one() self.country_afghanistan = self.env["res.country"].search([("code", "=", "AF")]) self.country_afghanistan.ensure_one() + + def ideal_scenario(self): # Create partner 1 (italy) self.partner_1 = self.env["res.partner"].create( { @@ -282,7 +292,7 @@ class TestWizardINE(TestPms): "pms_property_id": self.pms_property2.id, } ) - self.checkin5 = self.env["pms.checkin.partner"].create( + self.checkin5_other_property = self.env["pms.checkin.partner"].create( { "partner_id": self.partner_5.id, "reservation_id": self.reservation_property_2.id, @@ -345,6 +355,117 @@ class TestWizardINE(TestPms): self.reservation_4.reservation_line_ids[0].price = 21.50 self.reservation_4.reservation_line_ids[1].price = 21.50 + def pending_checkins_scenario(self): + # Create 3 checkin partners from russia + self.partner_russia_1 = self.env["res.partner"].create( + { + "name": "partner1", + "country_id": self.country_russia.id, + "nationality_id": self.country_russia.id, + "birthdate_date": "2000-06-25", + "gender": "male", + } + ) + self.partner_russia_2 = self.env["res.partner"].create( + { + "name": "partner2", + "country_id": self.country_russia.id, + "nationality_id": self.country_russia.id, + "birthdate_date": "2000-06-25", + "gender": "male", + } + ) + self.partner_russia_3 = self.env["res.partner"].create( + { + "name": "partner3", + "country_id": self.country_russia.id, + "nationality_id": self.country_russia.id, + "birthdate_date": "2000-06-25", + "gender": "male", + } + ) + # Create document for 3 checkin partners (russia) + self.env["res.partner.id_number"].create( + { + "category_id": self.id_category_passport.id, + "name": "15103354T", + "valid_from": datetime.date.today(), + "partner_id": self.partner_russia_1.id, + } + ) + self.env["res.partner.id_number"].create( + { + "category_id": self.id_category_passport.id, + "name": "25103354T", + "valid_from": datetime.date.today(), + "partner_id": self.partner_russia_2.id, + } + ) + self.env["res.partner.id_number"].create( + { + "category_id": self.id_category_passport.id, + "name": "35103354T", + "valid_from": datetime.date.today(), + "partner_id": self.partner_russia_3.id, + } + ) + + # Create 3 reservations + self.reservation_1 = self.env["pms.reservation"].create( + { + "checkin": datetime.date.today(), + "checkout": datetime.date.today() + datetime.timedelta(days=1), + "preferred_room_id": self.room_double_1.id, + "partner_id": self.partner_russia_1.id, + "adults": 2, + "pms_property_id": self.pms_property1.id, + } + ) + self.reservation_2 = self.env["pms.reservation"].create( + { + "checkin": datetime.date.today() + datetime.timedelta(days=1), + "checkout": datetime.date.today() + datetime.timedelta(days=2), + "preferred_room_id": self.room_double_2.id, + "partner_id": self.partner_russia_2.id, + "adults": 2, + "pms_property_id": self.pms_property1.id, + } + ) + self.reservation_3 = self.env["pms.reservation"].create( + { + "checkin": datetime.date.today() + datetime.timedelta(days=1), + "checkout": datetime.date.today() + datetime.timedelta(days=3), + "preferred_room_id": self.room_double_3.id, + "partner_id": self.partner_russia_3.id, + "adults": 2, + "pms_property_id": self.pms_property1.id, + } + ) + # Create 3 checkin partners (1 russian -> r1, 2 russian -> r3 ) + self.checkin_partner_r1_1 = self.env["pms.checkin.partner"].create( + { + "partner_id": self.partner_russia_1.id, + "reservation_id": self.reservation_1.id, + } + ) + self.checkin_partner_r3_1 = self.env["pms.checkin.partner"].create( + { + "partner_id": self.partner_russia_2.id, + "reservation_id": self.reservation_3.id, + } + ) + self.checkin_partner_r3_2 = self.env["pms.checkin.partner"].create( + { + "partner_id": self.partner_russia_3.id, + "reservation_id": self.reservation_3.id, + } + ) + # checkin partners on board + self.checkin_partner_r1_1.action_on_board() + with freeze_time("2021-02-02"): + self.checkin_partner_r3_1.action_on_board() + self.checkin_partner_r3_2.action_on_board() + def test_room_type_num_by_date(self): """ +============================+==============+==============+=============+ @@ -365,6 +486,7 @@ class TestWizardINE(TestPms): +============================+==============+==============+=============+ """ # ARRANGE + self.ideal_scenario() start_date = datetime.date(2021, 2, 1) second_date = datetime.date(2021, 2, 2) end_date = datetime.date(2021, 2, 3) @@ -425,24 +547,13 @@ class TestWizardINE(TestPms): +===========================+==============+==============+=============+=============+ """ # ARRANGE + self.ideal_scenario() start_date = datetime.date(2021, 2, 1) second_date = datetime.date(2021, 2, 2) third_date = datetime.date(2021, 2, 3) end_date = datetime.date(2021, 2, 4) expected_result = { - self.country_afghanistan.code: { - second_date: { - "arrivals": 3, - "pernoctations": 3, - }, - third_date: { - "pernoctations": 3, - }, - end_date: { - "departures": 3, - }, - }, self.country_italy.code: { start_date: { "arrivals": 1, @@ -466,6 +577,18 @@ class TestWizardINE(TestPms): "departures": 1, }, }, + self.country_afghanistan.code: { + second_date: { + "arrivals": 3, + "pernoctations": 3, + }, + third_date: { + "pernoctations": 3, + }, + end_date: { + "departures": 3, + }, + }, } # ACT nationalities = self.env["pms.ine.wizard"].ine_nationalities( @@ -504,6 +627,7 @@ class TestWizardINE(TestPms): +==========================+============+============+=========+========+ """ # ARRANGE + self.ideal_scenario() start_date = datetime.date(2021, 2, 1) second_date = datetime.date(2021, 2, 2) third_date = datetime.date(2021, 2, 3) @@ -615,6 +739,7 @@ class TestWizardINE(TestPms): +-------------+-------+-------+-------+ """ # ARRANGE + self.ideal_scenario() start_date = datetime.date(2021, 2, 1) expected_monthly_adr = 23.58 @@ -640,13 +765,14 @@ class TestWizardINE(TestPms): +----------------+-------+-------+-------+ | monthly revpar | 23.58 | +----------------+-------+-------+-------+ - num rooms avail. = 4 + num rooms avail. = 5 income = 25.00 + 21.00 + 25.00 + 25.00 + 21.50 + 21.50 = 139 - monthly revpar = 139 / (4 * 28) + monthly revpar = 139 / (5 * 28) = 0.99 """ # ARRANGE + self.ideal_scenario() start_date = datetime.date(2021, 2, 1) - expected_monthly_revpar = 1.24 + expected_monthly_revpar = 0.99 # ACT monthly_revpar = self.env["pms.ine.wizard"].ine_calculate_monthly_revpar( @@ -657,3 +783,74 @@ class TestWizardINE(TestPms): expected_monthly_revpar, monthly_revpar, ) + + def test_arrivals_departures_pernoctations_by_date_pending_checkins(self): + """ + if unknown checkin => Madrid + +==========================+============+============+=========+========+ + | | 01 | 02 | 03 | 04 | + +==========================+============+============+=========+========+ + | r1 2 adults | Russia | Russia | | | + | | unknown | unknown | | | + +--------------------------+------------+------------+---------+--------+ + | r2 2 adults | | unknown | unknown | | + | | | unknown | unknown | | + +--------------------------+------------+------------+---------+--------+ + | r3 2 adults | | Russia | Russia | Russia | + | | | Russia | Russia | Russia | + +==========================+============+============+=========+========+ + | arrivals Russia | 2 | 2 | | | + | arrivals Madrid | | 2 | | | + +==========================+============+============+=========+========+ + | pernoctations Russia | 2 | 2 | 2 | | + | pernoctations Madrid | | 2 | | | + 0+=========================+============+============+=========+========+ + | departures Russia | | 2 | | 2 | + | departures Madrid | | | 2 | | + +==========================+============+============+=========+========+ + """ + # ARRANGE + self.pending_checkins_scenario() + start_date = datetime.date(2021, 2, 1) + second_date = datetime.date(2021, 2, 2) + third_date = datetime.date(2021, 2, 3) + end_date = datetime.date(2021, 2, 4) + + country_spain = self.env["res.country"].search([("code", "=", "ES")]) + state_madrid = self.env["res.country.state"].search([("name", "=", "Madrid")]) + expected_result = { + self.country_russia.code: { + start_date: { + "arrivals": 2, + "pernoctations": 2, + }, + second_date: { + "arrivals": 2, + "pernoctations": 2, + "departures": 2, + }, + third_date: { + "pernoctations": 2, + }, + end_date: { + "departures": 2, + }, + }, + country_spain.code: { + state_madrid.ine_code: { + second_date: { + "arrivals": 2, + "pernoctations": 2, + }, + third_date: { + "departures": 2, + }, + }, + }, + } + # ACT + nationalities = self.env["pms.ine.wizard"].ine_nationalities( + start_date, end_date, self.pms_property1.id + ) + # ASSERT + self.assertDictEqual(nationalities, expected_result) diff --git a/pms_l10n_es/wizards/wizard_ine.py b/pms_l10n_es/wizards/wizard_ine.py index 881e10bbd..2df9d8326 100644 --- a/pms_l10n_es/wizards/wizard_ine.py +++ b/pms_l10n_es/wizards/wizard_ine.py @@ -251,6 +251,13 @@ class WizardIne(models.TransientModel): # result object nationalities = dict() + # fake partners to remove when process finished + fake_partners_ids = list() + + # default country and state + country_spain = self.env["res.country"].search([("code", "=", "ES")]) + state_madrid = self.env["res.country.state"].search([("name", "=", "Madrid")]) + # iterate days between start_date and end_date for p_date in [ start_date + datetime.timedelta(days=x) @@ -259,14 +266,55 @@ class WizardIne(models.TransientModel): # search for checkin partners hosts = self.env["pms.checkin.partner"].search( [ - ("partner_id", "!=", False), ("pms_property_id", "=", pms_property_id), ("checkin", "<=", p_date), ("checkout", ">=", p_date), + ("reservation_id.state", "!=", "cancel"), + ("reservation_id.reservation_type", "=", "normal"), ] ) + for host in hosts: + # host without checkin + if host.state not in ["onboard", "done"]: + # search other host same reservation with checkin + chk_part_same_reserv_with_checkin = ( + hosts.reservation_id.checkin_partner_ids.filtered( + lambda x: x.partner_id + and x.id != host.id + and x.state in ["onboard", "done"] + and x.reservation_id.id == host.reservation_id.id + ) + ) + # if there are some checkin partners in the same reservation + if chk_part_same_reserv_with_checkin: + # create partner with same country & state + country_other = ( + chk_part_same_reserv_with_checkin.partner_id.country_id.id + ) + state_other = ( + chk_part_same_reserv_with_checkin.partner_id.state_id.id + ) + dummy_partner = self.env["res.partner"].create( + { + "name": "partner1", + "country_id": country_other, + "nationality_id": country_other, + "state_id": state_other, + } + ) - # only checkin partners housed in "in_ine" rooms + else: + # create partner from madrid + dummy_partner = self.env["res.partner"].create( + { + "name": "partner1", + "country_id": country_spain.id, + "nationality_id": country_spain.id, + "state_id": state_madrid.id, + } + ) + fake_partners_ids.append(dummy_partner.id) + host.partner_id = dummy_partner hosts = hosts.filtered( lambda x: x.reservation_id.reservation_line_ids.mapped("room_id").in_ine ) @@ -279,6 +327,7 @@ class WizardIne(models.TransientModel): [("id", "in", arrivals.mapped("partner_id").ids)], ["nationality_id"], ["nationality_id"], + orderby="nationality_id", lazy=False, ) @@ -290,6 +339,7 @@ class WizardIne(models.TransientModel): [("id", "in", departures.mapped("partner_id").ids)], ["nationality_id"], ["nationality_id"], + orderby="nationality_id", lazy=False, ) @@ -301,6 +351,7 @@ class WizardIne(models.TransientModel): [("id", "in", pernoctations.mapped("partner_id").ids)], ["nationality_id"], ["nationality_id"], + orderby="nationality_id", lazy=False, ) @@ -314,6 +365,19 @@ class WizardIne(models.TransientModel): p_date, "pernoctations", read_by_pernoctations ) + checkin_partners_to_unlink = self.env["pms.checkin.partner"].search( + [ + ("partner_id", "in", fake_partners_ids), + ] + ) + checkin_partners_to_unlink.partner_id = False + + partners_to_unlink = self.env["res.partner"].search( + [ + ("id", "in", fake_partners_ids), + ] + ) + partners_to_unlink.unlink() return nationalities @api.model @@ -388,7 +452,6 @@ class WizardIne(models.TransientModel): revpar = round( sum_group_price[0]["price"] / (available_rooms * last_day.day), 2 ) - self.revpar = revpar return revpar @api.model @@ -586,7 +649,6 @@ class WizardIne(models.TransientModel): rooms = self.ine_rooms(self.start_date, self.end_date, self.pms_property_id) # INE XML -> ROOMS for key_date, value_rooms in rooms.items(): - rooms_move = ET.SubElement(rooms_tag, "HABITACIONES_MOVIMIENTO") ET.SubElement(rooms_move, "HABITACIONES_N_DIA").text = f"{key_date.day:02}" ET.SubElement(rooms_move, "PLAZAS_SUPLETORIAS").text = str(