mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[IMP] pms: generate INE report
This commit is contained in:
@@ -37,9 +37,6 @@ class PmsProperty(models.Model):
|
||||
"Tourism number",
|
||||
help="Registration number in the Ministry of Tourism. Used for INE statistics.",
|
||||
)
|
||||
ine_rooms = fields.Integer(
|
||||
"Rooms Available", default=0, help="Used for INE statistics."
|
||||
)
|
||||
ine_seats = fields.Integer(
|
||||
"Beds available", default=0, help="Used for INE statistics."
|
||||
)
|
||||
|
||||
@@ -3,4 +3,3 @@ user_access_traveller_report_wizard,user_access_traveller_report_wizard,model_tr
|
||||
user_access_traveller_report_logs,user_access_traveller_report_logs,model_pms_log_institution_traveller_report,pms.group_pms_user,1,1,1,1
|
||||
user_access_pms_ine_tourism_category,user_access_pms_ine_tourism_category,model_pms_ine_tourism_category,pms.group_pms_user,1,1,1,1
|
||||
user_access_pms_ine_wizard,user_access_pms_ine_wizard,model_pms_ine_wizard,pms.group_pms_user,1,1,1,1
|
||||
|
||||
|
||||
|
1
pms_l10n_es/tests/__init__.py
Normal file
1
pms_l10n_es/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import test_wizard_ine
|
||||
29
pms_l10n_es/tests/common.py
Normal file
29
pms_l10n_es/tests/common.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
class TestPms(common.SavepointCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.pricelist1 = self.env["product.pricelist"].create(
|
||||
{
|
||||
"name": "Pricelist 1",
|
||||
}
|
||||
)
|
||||
self.company1 = self.env["res.company"].create(
|
||||
{
|
||||
"name": "Company 1",
|
||||
}
|
||||
)
|
||||
self.pms_property1 = self.env["pms.property"].create(
|
||||
{
|
||||
"name": "Property 1",
|
||||
"company_id": self.company1.id,
|
||||
"default_pricelist_id": self.pricelist1.id,
|
||||
}
|
||||
)
|
||||
self.room_type_class1 = self.env["pms.room.type.class"].create(
|
||||
{
|
||||
"name": "Room Type Class 1",
|
||||
"default_code": "RTC1",
|
||||
}
|
||||
)
|
||||
498
pms_l10n_es/tests/test_wizard_ine.py
Normal file
498
pms_l10n_es/tests/test_wizard_ine.py
Normal file
@@ -0,0 +1,498 @@
|
||||
import datetime
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from .common import TestPms
|
||||
|
||||
|
||||
@freeze_time("2021-02-01")
|
||||
class TestWizardINE(TestPms):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
# create room types
|
||||
self.room_type = self.env["pms.room.type"].create(
|
||||
{
|
||||
"name": "Room type test",
|
||||
"default_code": "DBL_Test",
|
||||
"class_id": self.room_type_class1.id,
|
||||
}
|
||||
)
|
||||
# create rooms
|
||||
self.room_double_1 = self.env["pms.room"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"name": "Room test 1",
|
||||
"room_type_id": self.room_type.id,
|
||||
"capacity": 2,
|
||||
}
|
||||
)
|
||||
self.room_double_2 = self.env["pms.room"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"name": "Room test 2",
|
||||
"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 3",
|
||||
"room_type_id": self.room_type.id,
|
||||
"capacity": 1,
|
||||
"extra_beds_allowed": 1,
|
||||
}
|
||||
)
|
||||
self.room_triple1 = self.env["pms.room"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"name": "Room test 4",
|
||||
"room_type_id": self.room_type.id,
|
||||
"capacity": 3,
|
||||
}
|
||||
)
|
||||
|
||||
# create document category
|
||||
self.id_category_passport = self.env["res.partner.id_category"].create(
|
||||
{
|
||||
"name": "Passport",
|
||||
"code": "P",
|
||||
"active": True,
|
||||
}
|
||||
)
|
||||
# get records of russia, italy and afghanistan
|
||||
self.country_russia = self.env["res.country"].search([("code", "=", "RU")])
|
||||
self.country_russia.ensure_one()
|
||||
self.country_italy = self.env["res.country"].search([("code", "=", "IT")])
|
||||
self.country_italy.ensure_one()
|
||||
self.country_afghanistan = self.env["res.country"].search([("code", "=", "AF")])
|
||||
self.country_afghanistan.ensure_one()
|
||||
# Create partner 1 (italy)
|
||||
self.partner_1 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "partner1",
|
||||
"country_id": self.country_italy.id,
|
||||
"birthdate_date": "2000-06-25",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category_passport.id,
|
||||
"name": "55103354T",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.partner_1.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create partner 2 (russia)
|
||||
self.partner_2 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "partner2",
|
||||
"country_id": self.country_russia.id,
|
||||
"birthdate_date": "2000-06-25",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category_passport.id,
|
||||
"name": "45437298Q",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.partner_2.id,
|
||||
}
|
||||
)
|
||||
# Create partner 3 (italy)
|
||||
self.partner_3 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "partner3",
|
||||
"country_id": self.country_italy.id,
|
||||
"birthdate_date": "2000-06-25",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category_passport.id,
|
||||
"name": "81534086Y",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.partner_3.id,
|
||||
}
|
||||
)
|
||||
# Create partner 4 (italy)
|
||||
self.partner_4 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "partner4",
|
||||
"country_id": self.country_italy.id,
|
||||
"birthdate_date": "2000-06-25",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category_passport.id,
|
||||
"name": "00807643K",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.partner_4.id,
|
||||
}
|
||||
)
|
||||
# Create partner 5 (afghanistan)
|
||||
self.partner_5 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "partner5",
|
||||
"country_id": self.country_afghanistan.id,
|
||||
"birthdate_date": "2000-06-25",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category_passport.id,
|
||||
"name": "54564399G",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.partner_5.id,
|
||||
}
|
||||
)
|
||||
# Create partner 6 (afghanistan)
|
||||
self.partner_6 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "partner6",
|
||||
"country_id": self.country_afghanistan.id,
|
||||
"birthdate_date": "2000-06-25",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category_passport.id,
|
||||
"name": "39854152M",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.partner_6.id,
|
||||
}
|
||||
)
|
||||
# Create partner 7 (afghanistan)
|
||||
self.partner_7 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "partner7",
|
||||
"country_id": self.country_afghanistan.id,
|
||||
"birthdate_date": "2000-06-25",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category_passport.id,
|
||||
"name": "39854152O",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.partner_7.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create reservation 1
|
||||
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_1.id,
|
||||
"adults": 2,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
}
|
||||
)
|
||||
self.checkin1 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.partner_1.id,
|
||||
"reservation_id": self.reservation_1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.checkin2 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.partner_2.id,
|
||||
"reservation_id": self.reservation_1.id,
|
||||
}
|
||||
)
|
||||
# Create reservation 2
|
||||
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_triple1.id,
|
||||
"partner_id": self.partner_3.id,
|
||||
"adults": 2,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
}
|
||||
)
|
||||
self.checkin3 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.partner_3.id,
|
||||
"reservation_id": self.reservation_2.id,
|
||||
}
|
||||
)
|
||||
self.checkin4 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.partner_4.id,
|
||||
"reservation_id": self.reservation_2.id,
|
||||
}
|
||||
)
|
||||
# Create reservation 3
|
||||
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_2.id,
|
||||
"partner_id": self.partner_5.id,
|
||||
"adults": 1,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
}
|
||||
)
|
||||
self.checkin5 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.partner_5.id,
|
||||
"reservation_id": self.reservation_3.id,
|
||||
}
|
||||
)
|
||||
# Create extra bed service
|
||||
product_extra_bed = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product test",
|
||||
"is_extra_bed": True,
|
||||
"per_day": True,
|
||||
}
|
||||
)
|
||||
service_extra_bed = self.env["pms.service"].create(
|
||||
{
|
||||
"is_board_service": False,
|
||||
"product_id": product_extra_bed.id,
|
||||
}
|
||||
)
|
||||
# Create reservation 4
|
||||
self.reservation_4 = 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_single_1.id,
|
||||
"partner_id": self.partner_6.id,
|
||||
"adults": 2,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"service_ids": [(6, 0, [service_extra_bed.id])],
|
||||
}
|
||||
)
|
||||
self.checkin6 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.partner_6.id,
|
||||
"reservation_id": self.reservation_4.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.checkin7 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.partner_7.id,
|
||||
"reservation_id": self.reservation_4.id,
|
||||
}
|
||||
)
|
||||
# checkin partners on board
|
||||
self.checkin1.action_on_board()
|
||||
self.checkin2.action_on_board()
|
||||
with freeze_time("2021-02-02"):
|
||||
self.checkin3.action_on_board()
|
||||
self.checkin4.action_on_board()
|
||||
self.checkin5.action_on_board()
|
||||
self.checkin6.action_on_board()
|
||||
self.checkin7.action_on_board()
|
||||
|
||||
# set prices for nights
|
||||
self.reservation_1.reservation_line_ids[0].price = 25.0
|
||||
self.reservation_2.reservation_line_ids[0].price = 21.0
|
||||
self.reservation_3.reservation_line_ids[0].price = 25.0
|
||||
self.reservation_3.reservation_line_ids[1].price = 25.0
|
||||
self.reservation_4.reservation_line_ids[0].price = 21.50
|
||||
self.reservation_4.reservation_line_ids[1].price = 21.50
|
||||
|
||||
def test_room_type_num_by_date(self):
|
||||
"""
|
||||
+============================+==============+==============+=============+
|
||||
| | 01 | 02 | 03 |
|
||||
+============================+==============+==============+=============+
|
||||
| r1 2 adults | DOUBLE ROOM | | |
|
||||
| r2 2 adults | | TRIPLE ROOM | |
|
||||
| r3 1 adult | | DOUBLE ROOM | DOUBLE ROOM |
|
||||
| r4 2 adults (1 extra bed) | | SINGLE ROOM | SINGLE ROOM |
|
||||
+============================+==============+==============+=============+
|
||||
| double rooms (use double) | 1 | 0 | 0 |
|
||||
+============================+==============+==============+=============+
|
||||
| double rooms (use single) | 0 | 1 | 1 |
|
||||
+============================+==============+==============+=============+
|
||||
| other rooms | 0 | 2 | 1 |
|
||||
+============================+==============+==============+=============+
|
||||
| extra beds | 0 | 1 | 1 |
|
||||
+============================+==============+==============+=============+
|
||||
"""
|
||||
# ARRANGE
|
||||
start_date = datetime.date(2021, 2, 1)
|
||||
second_date = datetime.date(2021, 2, 2)
|
||||
end_date = datetime.date(2021, 2, 3)
|
||||
|
||||
expected_result = {
|
||||
start_date: {
|
||||
"double_rooms_double_use": 1,
|
||||
"double_rooms_single_use": 0,
|
||||
"other_rooms": 0,
|
||||
"extra_beds": 0,
|
||||
},
|
||||
second_date: {
|
||||
"double_rooms_double_use": 0,
|
||||
"double_rooms_single_use": 1,
|
||||
"other_rooms": 2,
|
||||
"extra_beds": 1,
|
||||
},
|
||||
end_date: {
|
||||
"double_rooms_double_use": 0,
|
||||
"double_rooms_single_use": 1,
|
||||
"other_rooms": 1,
|
||||
"extra_beds": 1,
|
||||
},
|
||||
}
|
||||
|
||||
# ACT
|
||||
rooms = self.env["pms.ine.wizard"].ine_rooms(
|
||||
start_date, end_date, self.pms_property1.id
|
||||
)
|
||||
# ASSERT
|
||||
self.assertDictEqual(rooms, expected_result)
|
||||
|
||||
def test_arrivals_departures_pernoctations_by_date(self):
|
||||
"""
|
||||
+===========================+==============+==============+=============+=============+
|
||||
| | 01 | 02 | 03 | 04 |
|
||||
+===========================+==============+==============+=============+=============+
|
||||
| r1 2 adults | italy,russia | italy,russia | | |
|
||||
+---------------------------+--------------+--------------+-------------+-------------+
|
||||
| r2 2 adults | | italy,italy | italy,italy | |
|
||||
+---------------------------+--------------+--------------+-------------+-------------+
|
||||
| r3 1 adult | | afghanistan | afghanistan | afghanistan |
|
||||
+---------------------------+--------------+--------------+-------------+-------------+
|
||||
| r4 2 adults | | afghanistan | afghanistan | afghanistan |
|
||||
| | | afghanistan | afghanistan | afghanistan |
|
||||
+===========================+==============+==============+=============+=============+
|
||||
| arrivals Afghanistan | | 3 | | |
|
||||
| arrivals Italy | 1 | 2 | | |
|
||||
| arrivals Russia | 1 | | | |
|
||||
+===========================+==============+==============+=============+=============+
|
||||
| pernoctations Afghanistan | | 3 | 3 | |
|
||||
| pernoctations Italy | 1 | 2 | | |
|
||||
| pernoctations Russia | 1 | | | |
|
||||
+===========================+==============+==============+=============+=============+
|
||||
| departures Afghanistan | | | | 3 |
|
||||
| departures Italy | | 1 | 2 | |
|
||||
| departures Russia | | 1 | | |
|
||||
+===========================+==============+==============+=============+=============+
|
||||
"""
|
||||
# ARRANGE
|
||||
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.id: {
|
||||
second_date: {
|
||||
"arrivals": 3,
|
||||
"pernoctations": 3,
|
||||
},
|
||||
third_date: {
|
||||
"pernoctations": 3,
|
||||
},
|
||||
end_date: {
|
||||
"departures": 3,
|
||||
},
|
||||
},
|
||||
self.country_italy.id: {
|
||||
start_date: {
|
||||
"arrivals": 1,
|
||||
"pernoctations": 1,
|
||||
},
|
||||
second_date: {
|
||||
"arrivals": 2,
|
||||
"pernoctations": 2,
|
||||
"departures": 1,
|
||||
},
|
||||
third_date: {
|
||||
"departures": 2,
|
||||
},
|
||||
},
|
||||
self.country_russia.id: {
|
||||
start_date: {
|
||||
"arrivals": 1,
|
||||
"pernoctations": 1,
|
||||
},
|
||||
second_date: {
|
||||
"departures": 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
# ACT
|
||||
nationalities = self.env["pms.ine.wizard"].ine_nationalities(
|
||||
start_date, end_date, self.pms_property1.id
|
||||
)
|
||||
# ASSERT
|
||||
self.assertDictEqual(nationalities, expected_result)
|
||||
|
||||
def test_calculate_monthly_adr(self):
|
||||
"""
|
||||
+-------------+-------+-------+-------+
|
||||
| | 01 | 02 | 03 |
|
||||
+-------------+-------+-------+-------+
|
||||
| r1 | 25.00 | | |
|
||||
| r2 | | 21.00 | |
|
||||
| r3 | | 25.00 | 25.00 |
|
||||
| r4 | | 21.50 | 21.50 |
|
||||
+-------------+-------+-------+-------+
|
||||
| adr | 25.00 | 22.50 | 23.25 |
|
||||
+-------------+-------+-------+-------+
|
||||
| monthly adr | 23.58 |
|
||||
+-------------+-------+-------+-------+
|
||||
"""
|
||||
# ARRANGE
|
||||
start_date = datetime.date(2021, 2, 1)
|
||||
expected_monthly_adr = 23.58
|
||||
|
||||
# ACT
|
||||
monthly_adr = self.env["pms.ine.wizard"].ine_calculate_monthly_adr(
|
||||
start_date, self.pms_property1.id
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
expected_monthly_adr,
|
||||
monthly_adr,
|
||||
)
|
||||
|
||||
def test_calculate_monthly_revpar(self):
|
||||
"""
|
||||
+----------------+-------+-------+-------+
|
||||
| | 01 | 02 | 03 |
|
||||
+----------------+-------+-------+-------+
|
||||
| r1 | 25.00 | | |
|
||||
| r2 | | 21.00 | |
|
||||
| r3 | | 25.00 | 25.00 |
|
||||
| r4 | | 21.50 | 21.50 |
|
||||
+----------------+-------+-------+-------+
|
||||
| monthly revpar | 23.58 |
|
||||
+----------------+-------+-------+-------+
|
||||
num rooms avail. = 4
|
||||
income = 25.00 + 21.00 + 25.00 + 25.00 + 21.50 + 21.50 = 139
|
||||
monthly revpar = 139 / (4 * 28)
|
||||
"""
|
||||
# ARRANGE
|
||||
start_date = datetime.date(2021, 2, 1)
|
||||
expected_monthly_revpar = 1.24
|
||||
|
||||
# ACT
|
||||
monthly_revpar = self.env["pms.ine.wizard"].ine_calculate_monthly_revpar(
|
||||
start_date, self.pms_property1.id
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
expected_monthly_revpar,
|
||||
monthly_revpar,
|
||||
)
|
||||
@@ -48,7 +48,6 @@
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<group>
|
||||
<field name="ine_rooms" />
|
||||
<field name="ine_seats" />
|
||||
<field name="ine_permanent_staff" />
|
||||
<field name="ine_eventual_staff" />
|
||||
|
||||
612
pms_l10n_es/wizards/wizard_ine.py
Normal file
612
pms_l10n_es/wizards/wizard_ine.py
Normal file
@@ -0,0 +1,612 @@
|
||||
import base64
|
||||
import calendar
|
||||
import datetime
|
||||
import xml.etree.cElementTree as ET
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
CODE_SPAIN = 68
|
||||
|
||||
|
||||
class WizardIne(models.TransientModel):
|
||||
_name = "pms.ine.wizard"
|
||||
_description = "Wizard to generate statistical info."
|
||||
|
||||
pms_property_id = fields.Many2one(
|
||||
string="Property",
|
||||
comodel_name="pms.property",
|
||||
default=lambda self: self.env["pms.property"].browse(
|
||||
self.env.user.get_active_property_ids()[0]
|
||||
),
|
||||
check_pms_properties=True,
|
||||
required=True,
|
||||
)
|
||||
|
||||
txt_filename = fields.Text()
|
||||
txt_binary = fields.Binary(string="File Download")
|
||||
txt_message = fields.Char(string="File Preview")
|
||||
|
||||
start_date = fields.Date(
|
||||
string="From",
|
||||
required=True,
|
||||
)
|
||||
end_date = fields.Date(
|
||||
string="To",
|
||||
required=True,
|
||||
)
|
||||
|
||||
adr = fields.Float(string="Monthly ADR")
|
||||
revpar = fields.Float(string="Monthly RevPAR")
|
||||
|
||||
@api.model
|
||||
def ine_rooms(self, start_date, end_date, pms_property_id):
|
||||
"""
|
||||
Returns a dictionary:
|
||||
{
|
||||
date_1: {
|
||||
'double_rooms_single_use': number,
|
||||
'double_rooms_double_use': number,
|
||||
'other_rooms': number,
|
||||
'extra_beds': number
|
||||
},
|
||||
# ... more dates
|
||||
}
|
||||
"""
|
||||
# result object
|
||||
rooms = dict()
|
||||
|
||||
# iterate days between start_date and end_date
|
||||
for p_date in [
|
||||
start_date + datetime.timedelta(days=x)
|
||||
for x in range(0, (end_date - start_date).days + 1)
|
||||
]:
|
||||
|
||||
# rooms with capacity 2 but only 1 adult using them
|
||||
double_rooms_single_use = (
|
||||
self.env["pms.reservation.line"]
|
||||
.search(
|
||||
[
|
||||
("pms_property_id", "=", pms_property_id),
|
||||
("occupies_availability", "=", True),
|
||||
("reservation_id.reservation_type", "=", "normal"),
|
||||
("room_id.in_ine", "=", True),
|
||||
("date", "=", p_date),
|
||||
("room_id.capacity", "=", 2),
|
||||
("reservation_id.adults", "=", 1),
|
||||
]
|
||||
)
|
||||
.mapped("room_id")
|
||||
)
|
||||
|
||||
# rooms with capacity 2 with 2 adult using them
|
||||
double_rooms_double_use = (
|
||||
self.env["pms.reservation.line"]
|
||||
.search(
|
||||
[
|
||||
("pms_property_id", "=", pms_property_id),
|
||||
("occupies_availability", "=", True),
|
||||
("reservation_id.reservation_type", "=", "normal"),
|
||||
("room_id.in_ine", "=", True),
|
||||
("date", "=", p_date),
|
||||
("room_id.capacity", "=", 2),
|
||||
("reservation_id.adults", "=", 2),
|
||||
]
|
||||
)
|
||||
.mapped("room_id")
|
||||
)
|
||||
|
||||
# service lines with extra beds
|
||||
extra_bed_service_lines = self.env["pms.service.line"].search(
|
||||
[
|
||||
("pms_property_id", "=", pms_property_id),
|
||||
("product_id.is_extra_bed", "=", True),
|
||||
("reservation_id.reservation_type", "=", "normal"),
|
||||
("date", "=", p_date),
|
||||
]
|
||||
)
|
||||
|
||||
extra_beds = 0
|
||||
|
||||
# get num. extra beds
|
||||
for ebsl in extra_bed_service_lines:
|
||||
reservation_lines = ebsl.reservation_id.reservation_line_ids.filtered(
|
||||
lambda x: x.date == ebsl.date
|
||||
and x.room_id.in_ine
|
||||
and x.occupies_availability
|
||||
)
|
||||
if reservation_lines:
|
||||
extra_beds += (
|
||||
ebsl.day_qty
|
||||
- reservation_lines.reservation_id.children_occupying
|
||||
)
|
||||
# children occuppying do not have checkin partner data
|
||||
|
||||
# search all rooms
|
||||
all_rooms = (
|
||||
self.env["pms.reservation.line"]
|
||||
.search(
|
||||
[
|
||||
("date", "=", p_date),
|
||||
("occupies_availability", "=", True),
|
||||
("reservation_id.reservation_type", "=", "normal"),
|
||||
("room_id.in_ine", "=", True),
|
||||
("pms_property_id", "=", pms_property_id),
|
||||
]
|
||||
)
|
||||
.mapped("room_id")
|
||||
)
|
||||
|
||||
# other rooms = all rooms - double rooms
|
||||
other_rooms = (
|
||||
all_rooms - double_rooms_double_use
|
||||
) - double_rooms_single_use
|
||||
|
||||
# no room movements -> no dict entrys
|
||||
if not (
|
||||
extra_beds == 0
|
||||
and len(other_rooms) == 0
|
||||
and len(double_rooms_double_use) == 0
|
||||
and len(double_rooms_single_use) == 0
|
||||
):
|
||||
# create result dict for each date
|
||||
rooms[p_date] = dict()
|
||||
rooms[p_date]["double_rooms_single_use"] = len(double_rooms_single_use)
|
||||
rooms[p_date]["double_rooms_double_use"] = len(double_rooms_double_use)
|
||||
rooms[p_date]["other_rooms"] = len(other_rooms)
|
||||
rooms[p_date]["extra_beds"] = extra_beds
|
||||
return rooms
|
||||
|
||||
@api.model
|
||||
def ine_nationalities(self, start_date, end_date, pms_property_id):
|
||||
"""
|
||||
Returns a dictionary:
|
||||
{
|
||||
CODE_SPAIN: {
|
||||
state.code_ine: {
|
||||
date: {
|
||||
'arrivals': number,
|
||||
'departures': number,
|
||||
'pernoctations': number,
|
||||
},
|
||||
# ... more dates
|
||||
},
|
||||
# ... more ine codes from spain
|
||||
},
|
||||
# ... more countries (except Spain)
|
||||
country.code_alpha3: {
|
||||
date: {
|
||||
'arrivals': num. of arrivals
|
||||
'departures': num. of departures
|
||||
'pernoctations': num. of pernoctations
|
||||
},
|
||||
# ... more dates
|
||||
},
|
||||
# ... more countries (except Spain)
|
||||
}
|
||||
"""
|
||||
|
||||
def ine_add_arrivals_departures_pernoctations(
|
||||
date, type_of_entry, read_group_result
|
||||
):
|
||||
"""
|
||||
date = date to add the entry to dic
|
||||
type_of_entry = 'arrivals' | 'departures' | 'pernoctations'
|
||||
read_group_result = result of read_group by type_of_entry
|
||||
|
||||
"""
|
||||
|
||||
for entry in read_group_result:
|
||||
# get country_id from group set read_group results
|
||||
country_id_key = entry["country_id"][0]
|
||||
|
||||
# all countries except Spain
|
||||
if country_id_key != CODE_SPAIN:
|
||||
|
||||
# get count of each result
|
||||
num = entry["__count"]
|
||||
|
||||
# update/create dicts for countries & dates and set num. arrivals
|
||||
if not nationalities.get(country_id_key):
|
||||
nationalities[country_id_key] = dict()
|
||||
if not nationalities[country_id_key].get(date):
|
||||
nationalities[country_id_key][date] = dict()
|
||||
nationalities[country_id_key][date][type_of_entry] = num
|
||||
else:
|
||||
# arrivals grouped by state_id (Spain "provincias")
|
||||
read_by_arrivals_spain = self.env["res.partner"].read_group(
|
||||
entry["__domain"],
|
||||
["state_id"],
|
||||
["state_id"],
|
||||
lazy=False,
|
||||
)
|
||||
# iterate read_group results from Spain
|
||||
for entry_from_spain in read_by_arrivals_spain:
|
||||
state_id = self.env["res.country.state"].browse(
|
||||
entry_from_spain["state_id"][0]
|
||||
) # .ine_code
|
||||
ine_code = state_id.ine_code
|
||||
|
||||
# get count of each result
|
||||
num_spain = entry_from_spain["__count"]
|
||||
|
||||
# update/create dicts for states & dates and set num. arrivals
|
||||
if not nationalities.get(CODE_SPAIN):
|
||||
nationalities[CODE_SPAIN] = dict()
|
||||
|
||||
if not nationalities[CODE_SPAIN].get(ine_code):
|
||||
nationalities[CODE_SPAIN][ine_code] = dict()
|
||||
|
||||
if not nationalities[CODE_SPAIN][ine_code].get(date):
|
||||
nationalities[CODE_SPAIN][ine_code][date] = dict()
|
||||
|
||||
nationalities[CODE_SPAIN][ine_code][date][
|
||||
type_of_entry
|
||||
] = num_spain
|
||||
|
||||
# result object
|
||||
nationalities = dict()
|
||||
|
||||
# iterate days between start_date and end_date
|
||||
for p_date in [
|
||||
start_date + datetime.timedelta(days=x)
|
||||
for x in range(0, (end_date - start_date).days + 1)
|
||||
]:
|
||||
# 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),
|
||||
]
|
||||
)
|
||||
|
||||
# only checkin partners housed in "in_ine" rooms
|
||||
hosts = hosts.filtered(
|
||||
lambda x: x.reservation_id.reservation_line_ids.mapped("room_id").in_ine
|
||||
)
|
||||
|
||||
# arrivals
|
||||
arrivals = hosts.filtered(lambda x: x.checkin == p_date)
|
||||
|
||||
# arrivals grouped by country_id
|
||||
read_by_arrivals = self.env["res.partner"].read_group(
|
||||
[("id", "in", arrivals.mapped("partner_id").ids)],
|
||||
["country_id"],
|
||||
["country_id"],
|
||||
lazy=False,
|
||||
)
|
||||
|
||||
# departures
|
||||
departures = hosts.filtered(lambda x: x.checkout == p_date)
|
||||
|
||||
# departures grouped by country_id
|
||||
read_by_departures = self.env["res.partner"].read_group(
|
||||
[("id", "in", departures.mapped("partner_id").ids)],
|
||||
["country_id"],
|
||||
["country_id"],
|
||||
lazy=False,
|
||||
)
|
||||
|
||||
# pernoctations
|
||||
pernoctations = hosts - departures
|
||||
|
||||
# pernoctations grouped by country_id
|
||||
read_by_pernoctations = self.env["res.partner"].read_group(
|
||||
[("id", "in", pernoctations.mapped("partner_id").ids)],
|
||||
["country_id"],
|
||||
["country_id"],
|
||||
lazy=False,
|
||||
)
|
||||
|
||||
ine_add_arrivals_departures_pernoctations(
|
||||
p_date, "arrivals", read_by_arrivals
|
||||
)
|
||||
ine_add_arrivals_departures_pernoctations(
|
||||
p_date, "departures", read_by_departures
|
||||
)
|
||||
ine_add_arrivals_departures_pernoctations(
|
||||
p_date, "pernoctations", read_by_pernoctations
|
||||
)
|
||||
|
||||
return nationalities
|
||||
|
||||
@api.model
|
||||
def ine_calculate_monthly_adr(self, start_date, pms_property_id):
|
||||
month = start_date.month
|
||||
year = start_date.year
|
||||
month_range = calendar.monthrange(start_date.year, start_date.month)
|
||||
first_day = datetime.date(year, month, 1)
|
||||
last_day = datetime.date(year, month, month_range[1])
|
||||
group_adr = self.env["pms.reservation.line"].read_group(
|
||||
[
|
||||
("pms_property_id", "=", pms_property_id),
|
||||
("occupies_availability", "=", True),
|
||||
("reservation_id.reservation_type", "=", "normal"),
|
||||
("room_id.in_ine", "=", True),
|
||||
("date", ">=", first_day),
|
||||
("date", "<=", last_day),
|
||||
],
|
||||
["price:avg"],
|
||||
["date:day"],
|
||||
)
|
||||
adr = 0
|
||||
for day_adr in group_adr:
|
||||
adr += day_adr["price"]
|
||||
|
||||
adr = round(adr / len(group_adr), 2)
|
||||
self.adr = adr
|
||||
return adr
|
||||
|
||||
@api.model
|
||||
def ine_calculate_monthly_revpar(self, start_date, pms_property_id):
|
||||
month = start_date.month
|
||||
year = start_date.year
|
||||
month_range = calendar.monthrange(start_date.year, start_date.month)
|
||||
first_day = datetime.date(year, month, 1)
|
||||
last_day = datetime.date(year, month, month_range[1])
|
||||
sum_group_price = self.env["pms.reservation.line"].read_group(
|
||||
[
|
||||
("pms_property_id", "=", pms_property_id),
|
||||
("occupies_availability", "=", True),
|
||||
("reservation_id.reservation_type", "=", "normal"),
|
||||
("room_id.in_ine", "=", True),
|
||||
("date", ">=", first_day),
|
||||
("date", "<=", last_day),
|
||||
],
|
||||
["price"],
|
||||
[],
|
||||
)
|
||||
rooms_not_allowed = (
|
||||
self.env["pms.reservation.line"]
|
||||
.search(
|
||||
[
|
||||
("pms_property_id", "=", pms_property_id),
|
||||
("occupies_availability", "=", True),
|
||||
("reservation_id.reservation_type", "!=", "normal"),
|
||||
]
|
||||
)
|
||||
.mapped("room_id")
|
||||
.ids
|
||||
)
|
||||
available_rooms = self.env["pms.room"].search_count(
|
||||
[
|
||||
("in_ine", "=", True),
|
||||
("pms_property_id", "=", pms_property_id),
|
||||
("id", "not in", rooms_not_allowed),
|
||||
]
|
||||
)
|
||||
revpar = round(
|
||||
sum_group_price[0]["price"] / (available_rooms * last_day.day), 2
|
||||
)
|
||||
self.revpar = revpar
|
||||
return revpar
|
||||
|
||||
@api.model
|
||||
def ine_calculate_capacity(self):
|
||||
# TODO: Review if calculate like below or get the info from property.ine_seats
|
||||
return sum(
|
||||
self.env["pms.room"]
|
||||
.search(
|
||||
[
|
||||
("in_ine", "=", True),
|
||||
]
|
||||
)
|
||||
.mapped("capacity")
|
||||
)
|
||||
|
||||
def ine_generate_xml(self):
|
||||
if self.start_date.month != self.end_date.month:
|
||||
raise ValidationError(_("The date range must belong to the same month."))
|
||||
if not self.pms_property_id.company_id.vat:
|
||||
raise ValidationError(_("The VAT is not established."))
|
||||
|
||||
# INE XML
|
||||
survey_tag = ET.Element("ENCUESTA")
|
||||
|
||||
# INE XML -> PROPERTY
|
||||
header_tag = ET.SubElement(survey_tag, "CABECERA")
|
||||
date = ET.SubElement(header_tag, "FECHA_REFERENCIA")
|
||||
ET.SubElement(date, "MES").text = f"{self.start_date.month:02}"
|
||||
ET.SubElement(date, "ANYO").text = str(self.start_date.year)
|
||||
ET.SubElement(header_tag, "DIAS_ABIERTO_MES_REFERENCIA").text = str(
|
||||
calendar.monthrange(self.start_date.year, self.start_date.month)[1]
|
||||
)
|
||||
ET.SubElement(
|
||||
header_tag, "RAZON_SOCIAL"
|
||||
).text = self.pms_property_id.company_id.name
|
||||
ET.SubElement(
|
||||
header_tag, "NOMBRE_ESTABLECIMIENTO"
|
||||
).text = self.pms_property_id.name
|
||||
ET.SubElement(header_tag, "CIF_NIF").text = self.pms_property_id.company_id.vat[
|
||||
2:
|
||||
].strip()
|
||||
ET.SubElement(
|
||||
header_tag, "NUMERO_REGISTRO"
|
||||
).text = self.pms_property_id.ine_tourism
|
||||
ET.SubElement(header_tag, "DIRECCION").text = self.pms_property_id.street
|
||||
ET.SubElement(header_tag, "CODIGO_POSTAL").text = self.pms_property_id.zip
|
||||
ET.SubElement(header_tag, "LOCALIDAD").text = self.pms_property_id.city
|
||||
ET.SubElement(header_tag, "MUNICIPIO").text = self.pms_property_id.city
|
||||
ET.SubElement(
|
||||
header_tag, "PROVINCIA"
|
||||
).text = self.pms_property_id.partner_id.state_id.name
|
||||
ET.SubElement(
|
||||
header_tag, "TELEFONO_1"
|
||||
).text = self.pms_property_id.phone.replace(" ", "")[0:12]
|
||||
ET.SubElement(
|
||||
header_tag, "TIPO"
|
||||
).text = self.pms_property_id.ine_category_id.category_type
|
||||
ET.SubElement(
|
||||
header_tag, "CATEGORIA"
|
||||
).text = self.pms_property_id.ine_category_id.name
|
||||
ET.SubElement(header_tag, "HABITACIONES").text = str(
|
||||
self.env["pms.room"].search_count([("in_ine", "=", True)])
|
||||
)
|
||||
|
||||
ET.SubElement(header_tag, "PLAZAS_DISPONIBLES_SIN_SUPLETORIAS").text = str(
|
||||
self.ine_calculate_capacity()
|
||||
)
|
||||
ET.SubElement(header_tag, "URL").text = self.pms_property_id.website
|
||||
|
||||
# INE XML -> GUESTS
|
||||
accommodation_tag = ET.SubElement(survey_tag, "ALOJAMIENTO")
|
||||
|
||||
nationalities = self.ine_nationalities(
|
||||
self.start_date, self.end_date, self.pms_property_id.id
|
||||
)
|
||||
for key_country, value_country in nationalities.items():
|
||||
country = self.env["res.country"].browse(key_country)
|
||||
if key_country != CODE_SPAIN:
|
||||
residency_tag = ET.SubElement(accommodation_tag, "RESIDENCIA")
|
||||
ET.SubElement(residency_tag, "ID_PAIS").text = country.code_alpha3
|
||||
|
||||
for key_date, value_dates in value_country.items():
|
||||
movement = ET.SubElement(residency_tag, "MOVIMIENTO")
|
||||
ET.SubElement(movement, "N_DIA").text = f"{key_date.day:02}"
|
||||
num_arrivals = (
|
||||
value_dates["arrivals"] if value_dates.get("arrivals") else 0
|
||||
)
|
||||
num_departures = (
|
||||
value_dates["departures"]
|
||||
if value_dates.get("departures")
|
||||
else 0
|
||||
)
|
||||
num_pernoctations = (
|
||||
value_dates["pernoctations"]
|
||||
if value_dates.get("pernoctations")
|
||||
else 0
|
||||
)
|
||||
|
||||
ET.SubElement(movement, "ENTRADAS").text = str(num_arrivals)
|
||||
ET.SubElement(movement, "SALIDAS").text = str(num_departures)
|
||||
ET.SubElement(movement, "PERNOCTACIONES").text = str(
|
||||
num_pernoctations
|
||||
)
|
||||
else:
|
||||
for code_ine, value_state in value_country.items():
|
||||
residency_tag = ET.SubElement(accommodation_tag, "RESIDENCIA")
|
||||
ET.SubElement(residency_tag, "ID_PROVINCIA_ISLA").text = code_ine
|
||||
for key_date, value_dates in value_state.items():
|
||||
movement = ET.SubElement(residency_tag, "MOVIMIENTO")
|
||||
ET.SubElement(movement, "N_DIA").text = f"{key_date.day:02}"
|
||||
num_arrivals = (
|
||||
value_dates["arrivals"]
|
||||
if value_dates.get("arrivals")
|
||||
else 0
|
||||
)
|
||||
num_departures = (
|
||||
value_dates["departures"]
|
||||
if value_dates.get("departures")
|
||||
else 0
|
||||
)
|
||||
num_pernoctations = (
|
||||
value_dates["pernoctations"]
|
||||
if value_dates.get("pernoctations")
|
||||
else 0
|
||||
)
|
||||
ET.SubElement(movement, "ENTRADAS").text = str(num_arrivals)
|
||||
ET.SubElement(movement, "SALIDAS").text = str(num_departures)
|
||||
ET.SubElement(movement, "PERNOCTACIONES").text = str(
|
||||
num_pernoctations
|
||||
)
|
||||
|
||||
rooms_tag = ET.SubElement(survey_tag, "HABITACIONES")
|
||||
rooms = self.ine_rooms(self.start_date, self.end_date, self.pms_property_id.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(
|
||||
value_rooms["extra_beds"]
|
||||
)
|
||||
ET.SubElement(rooms_move, "HABITACIONES_DOBLES_USO_DOBLE").text = str(
|
||||
value_rooms["double_rooms_double_use"]
|
||||
)
|
||||
ET.SubElement(rooms_move, "HABITACIONES_DOBLES_USO_INDIVIDUAL").text = str(
|
||||
value_rooms["double_rooms_single_use"]
|
||||
)
|
||||
ET.SubElement(rooms_move, "HABITACIONES_OTRAS").text = str(
|
||||
value_rooms["other_rooms"]
|
||||
)
|
||||
prices_tag = ET.SubElement(survey_tag, "PRECIOS")
|
||||
|
||||
ET.SubElement(prices_tag, "ADR_MENSUAL").text = str(
|
||||
self.ine_calculate_monthly_adr(
|
||||
self.start_date,
|
||||
self.pms_property_id.id,
|
||||
)
|
||||
)
|
||||
|
||||
ET.SubElement(prices_tag, "REVPAR_MENSUAL").text = str(
|
||||
self.ine_calculate_monthly_revpar(
|
||||
self.start_date,
|
||||
self.pms_property_id.id,
|
||||
)
|
||||
)
|
||||
# TODO:
|
||||
# Evaluate how to get occupation & ADR for:
|
||||
# -traditional/online tour-operator
|
||||
# -traditional/online agency
|
||||
# -companys
|
||||
|
||||
ET.SubElement(prices_tag, "ADR_TOUROPERADOR_TRADICIONAL").text = "0"
|
||||
ET.SubElement(
|
||||
prices_tag, "PCTN_HABITACIONES_OCUPADAS_TOUROPERADOR_TRADICIONAL"
|
||||
).text = "0"
|
||||
ET.SubElement(prices_tag, "ADR_TOUROPERADOR_ONLINE").text = "0"
|
||||
ET.SubElement(
|
||||
prices_tag, "PCTN_HABITACIONES_OCUPADAS_TOUROPERADOR_ONLINE"
|
||||
).text = "0"
|
||||
ET.SubElement(prices_tag, "ADR_EMPRESAS").text = "0"
|
||||
ET.SubElement(prices_tag, "PCTN_HABITACIONES_OCUPADAS_EMPRESAS").text = "0"
|
||||
ET.SubElement(prices_tag, "ADR_AGENCIA_DE_VIAJE_TRADICIONAL").text = "0"
|
||||
ET.SubElement(
|
||||
prices_tag, "PCTN_HABITACIONES_OCUPADAS_AGENCIA_TRADICIONAL"
|
||||
).text = "0"
|
||||
ET.SubElement(prices_tag, "ADR_AGENCIA_DE_VIAJE_ONLINE").text = "0"
|
||||
ET.SubElement(
|
||||
prices_tag, "PCTN_HABITACIONES_OCUPADAS_AGENCIA_ONLINE"
|
||||
).text = "0"
|
||||
ET.SubElement(prices_tag, "ADR_PARTICULARES").text = "0"
|
||||
ET.SubElement(prices_tag, "PCTN_HABITACIONES_OCUPADAS_PARTICULARES").text = "0"
|
||||
ET.SubElement(prices_tag, "ADR_GRUPOS").text = "0"
|
||||
ET.SubElement(prices_tag, "PCTN_HABITACIONES_OCUPADAS_GRUPOS").text = "0"
|
||||
ET.SubElement(prices_tag, "ADR_INTERNET").text = "0"
|
||||
ET.SubElement(prices_tag, "PCTN_HABITACIONES_OCUPADAS_INTERNET").text = "0"
|
||||
ET.SubElement(prices_tag, "ADR_OTROS").text = "0"
|
||||
ET.SubElement(prices_tag, "PCTN_HABITACIONES_OCUPADAS_OTROS").text = "0"
|
||||
|
||||
staff_tag = ET.SubElement(survey_tag, "PERSONAL_OCUPADO")
|
||||
ET.SubElement(staff_tag, "PERSONAL_NO_REMUNERADO").text = "0"
|
||||
ET.SubElement(staff_tag, "PERSONAL_REMUNERADO_FIJO").text = str(
|
||||
self.pms_property_id.ine_permanent_staff
|
||||
)
|
||||
ET.SubElement(staff_tag, "PERSONAL_REMUNERADO_EVENTUAL").text = str(
|
||||
self.pms_property_id.ine_eventual_staff
|
||||
)
|
||||
|
||||
xmlstr = '<?xml version="1.0" encoding="ISO-8859-1"?>'
|
||||
xmlstr += ET.tostring(survey_tag).decode("utf-8")
|
||||
|
||||
self.txt_binary = base64.b64encode(str.encode(xmlstr))
|
||||
self.txt_filename = (
|
||||
"INE_"
|
||||
+ str(self.start_date.month)
|
||||
+ "_"
|
||||
+ str(self.start_date.year)
|
||||
+ ".xml"
|
||||
)
|
||||
|
||||
return {
|
||||
"context": self.env.context,
|
||||
"view_type": "form",
|
||||
"view_mode": "form",
|
||||
"res_model": "pms.ine.wizard",
|
||||
"res_id": self.id,
|
||||
"view_id": False,
|
||||
"type": "ir.actions.act_window",
|
||||
"target": "new",
|
||||
}
|
||||
@@ -6,6 +6,11 @@
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<group>
|
||||
<field name="pms_property_id" />
|
||||
</group>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<group>
|
||||
<field
|
||||
@@ -20,25 +25,40 @@
|
||||
/>
|
||||
</group>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<group>
|
||||
<field name="pms_property_id" />
|
||||
</group>
|
||||
</div>
|
||||
</div>
|
||||
<group>
|
||||
<field name="txt_filename" />
|
||||
<field name="txt_message" />
|
||||
<field name="txt_binary" filename="txt_filename" readonly="1" />
|
||||
</group>
|
||||
<div class="col-3">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<group>
|
||||
<field name="txt_filename" invisible="1" />
|
||||
<field
|
||||
name="txt_binary"
|
||||
filename="txt_filename"
|
||||
readonly="1"
|
||||
attrs="{'invisible': [('txt_filename','=', False)]}"
|
||||
/>
|
||||
</group>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<group>
|
||||
<field
|
||||
name="adr"
|
||||
attrs="{'invisible': [('txt_filename','=', False)]}"
|
||||
readonly="1"
|
||||
/>
|
||||
<field
|
||||
name="revpar"
|
||||
attrs="{'invisible': [('txt_filename','=', False)]}"
|
||||
readonly="1"
|
||||
/>
|
||||
</group>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
name="generate_ine_file"
|
||||
class="btn btn-primary btn-sm"
|
||||
type="object"
|
||||
string="Preview file"
|
||||
/>
|
||||
</div>
|
||||
name="ine_generate_xml"
|
||||
class="btn btn-primary btn-sm"
|
||||
type="object"
|
||||
string="Generate INE XML"
|
||||
/>
|
||||
<footer />
|
||||
</form>
|
||||
</field>
|
||||
|
||||
Reference in New Issue
Block a user