diff --git a/pms_l10n_es/models/pms_reservation.py b/pms_l10n_es/models/pms_reservation.py
index eb6492f55..e97ce9029 100644
--- a/pms_l10n_es/models/pms_reservation.py
+++ b/pms_l10n_es/models/pms_reservation.py
@@ -30,7 +30,6 @@ class PmsReservation(models.Model):
("processed", "Processed"),
],
compute="_compute_ses_status_reservation",
- store=True,
)
ses_status_traveller_report = fields.Selection(
string="SES Status traveller",
@@ -46,15 +45,20 @@ class PmsReservation(models.Model):
("processed", "Processed"),
],
compute="_compute_ses_status_traveller_report",
- store=True,
)
- @api.depends("pms_property_id")
+ @api.depends("pms_property_id", "preferred_room_id")
def _compute_is_ses(self):
for record in self:
- record.is_ses = record.pms_property_id.institution == "ses"
+ if (
+ record.preferred_room_id
+ and record.preferred_room_id.institution_independent_account
+ and record.preferred_room_id.institution == "ses"
+ ):
+ record.is_ses = True
+ else:
+ record.is_ses = record.pms_property_id.institution == "ses"
- @api.depends("ses_communication_ids", "ses_communication_ids.state")
def _compute_ses_status_reservation(self):
for record in self:
if record.pms_property_id.institution != "ses":
@@ -70,7 +74,6 @@ class PmsReservation(models.Model):
communication.state if communication else "error_create"
)
- @api.depends("ses_communication_ids", "ses_communication_ids.state")
def _compute_ses_status_traveller_report(self):
for record in self:
if record.pms_property_id.institution != "ses":
@@ -88,11 +91,13 @@ class PmsReservation(models.Model):
@api.model
def create_communication(self, reservation_id, operation, entity):
+ reservation = self.env["pms.reservation"].browse(reservation_id)
self.env["pms.ses.communication"].create(
{
"reservation_id": reservation_id,
"operation": operation,
"entity": entity,
+ "room_id": reservation.preferred_room_id.id,
}
)
@@ -164,9 +169,6 @@ class PmsReservation(models.Model):
def write(self, vals):
for record in self:
- if (
- record.pms_property_id.institution == "ses"
- and record.reservation_type != "out"
- ):
+ if record.is_ses and record.reservation_type != "out":
self.create_communication_after_update_reservation(record, vals)
return super(PmsReservation, self).write(vals)
diff --git a/pms_l10n_es/models/pms_room.py b/pms_l10n_es/models/pms_room.py
index 76dbc5efd..5efc348b6 100644
--- a/pms_l10n_es/models/pms_room.py
+++ b/pms_l10n_es/models/pms_room.py
@@ -3,8 +3,43 @@ from odoo import fields, models
class PmsRoom(models.Model):
_inherit = "pms.room"
+
in_ine = fields.Boolean(
string="In INE",
help="Take it into account to generate INE statistics",
default=True,
)
+ institution_independent_account = fields.Boolean(
+ string="Independent account for institution (travel reports)",
+ help="This room has an independent account",
+ default=False,
+ )
+ institution = fields.Selection(
+ [
+ ("ses", "SES"),
+ ("ertxaintxa", "Ertxaintxa (soon)"),
+ ("mossos", "Mossos_d'esquadra (soon)"),
+ ],
+ string="Institution",
+ help="Institution to send daily guest data.",
+ required=False,
+ )
+ institution_property_id = fields.Char(
+ string="Institution property id",
+ help="Id provided by institution to send data from property.",
+ )
+ ses_url = fields.Char(
+ string="SES URL",
+ help="URL to send the data to SES",
+ )
+ institution_user = fields.Char(
+ string="Institution user", help="User provided by institution to send the data."
+ )
+ institution_password = fields.Char(
+ string="Institution password",
+ help="Password provided by institution to send the data.",
+ )
+ institution_lessor_id = fields.Char(
+ string="Institution lessor id",
+ help="Id provided by institution to send data from lessor.",
+ )
diff --git a/pms_l10n_es/models/pms_ses_communication.py b/pms_l10n_es/models/pms_ses_communication.py
index 41056c62b..1931b1893 100644
--- a/pms_l10n_es/models/pms_ses_communication.py
+++ b/pms_l10n_es/models/pms_ses_communication.py
@@ -22,6 +22,14 @@ class PmsSesCommunication(models.Model):
index=True,
store=True,
)
+ room_id = fields.Many2one(
+ comodel_name="pms.room",
+ string="Room",
+ help="Room related to this communication",
+ related="reservation_id.preferred_room_id",
+ index=True,
+ store=True,
+ )
batch_id = fields.Char(
string="Batch ID",
default=False,
diff --git a/pms_l10n_es/views/pms_room_views.xml b/pms_l10n_es/views/pms_room_views.xml
index 820fceaa9..9c2a60e90 100644
--- a/pms_l10n_es/views/pms_room_views.xml
+++ b/pms_l10n_es/views/pms_room_views.xml
@@ -7,6 +7,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pms_l10n_es/wizards/traveller_report.py b/pms_l10n_es/wizards/traveller_report.py
index b90bf1029..de3c6138d 100644
--- a/pms_l10n_es/wizards/traveller_report.py
+++ b/pms_l10n_es/wizards/traveller_report.py
@@ -310,8 +310,15 @@ def _ses_xml_person_elements(comunicacion, checkin_partner):
def _get_auth_headers(communication):
- user = communication.reservation_id.pms_property_id.institution_user
- password = communication.reservation_id.pms_property_id.institution_password
+ if (
+ communication.reservation_id.preferred_room_id
+ and communication.reservation_id.preferred_room_id.institution_independent_account
+ ):
+ user = communication.reservation_id.preferred_room_id.institution_user
+ password = communication.reservation_id.preferred_room_id.institution_password
+ else:
+ user = communication.reservation_id.pms_property_id.institution_user
+ password = communication.reservation_id.pms_property_id.institution_password
user_and_password_base64 = "Basic " + base64.b64encode(
bytes(user + ":" + password, "utf-8")
@@ -412,13 +419,22 @@ class TravellerReport(models.TransientModel):
required=True,
default=lambda self: self.env.user.get_active_property_ids()[0],
)
-
+ room_id = fields.Many2one(
+ comodel_name="pms.room",
+ string="Room",
+ domain="""
+ [
+ ('pms_property_id', '=', pms_property_id),
+ ('institution_independent_account, '=', True),
+ ('institution', '=', 'ses')
+ ]
+ """,
+ )
is_ses = fields.Boolean(
string="Is SES",
readonly=True,
compute="_compute_is_ses",
)
-
report_type = fields.Selection(
string="Report Type",
required=True,
@@ -431,31 +447,50 @@ class TravellerReport(models.TransientModel):
)
@api.depends(
- "pms_property_id", "date_target", "date_from", "date_to", "report_type"
+ "pms_property_id",
+ "date_target",
+ "date_from",
+ "date_to",
+ "report_type",
+ "room_id",
)
def _compute_txt_message(self):
for record in self:
record.txt_message = False
- @api.depends("pms_property_id.institution")
+ @api.depends("pms_property_id.institution", "room_id.institution")
def _compute_is_ses(self):
for record in self:
- record.is_ses = record.pms_property_id.institution == "ses"
+ if record.room_id:
+ record.is_ses = record.room_id.institution == "ses"
+ else:
+ record.is_ses = record.pms_property_id.institution == "ses"
def generate_file_from_user_action(self):
pms_property = self.env["pms.property"].search(
[("id", "=", self.pms_property_id.id)]
)
- # check if there's institution settings properly established
- if (
- not pms_property
- or not pms_property.institution_property_id
- or not pms_property.institution_user
- or not pms_property.institution_password
- ):
- raise ValidationError(
- _("The guest information sending settings is not property set up.")
- )
+ room = self.room_id
+ if not room:
+ # check if there's institution settings properly established
+ if (
+ not pms_property
+ or not pms_property.institution_property_id
+ or not pms_property.institution_user
+ or not pms_property.institution_password
+ ):
+ raise ValidationError(
+ _("The guest information sending settings is not property set up.")
+ )
+ else:
+ if (
+ not room.institution_property_id
+ or not room.institution_user
+ or not room.institution_password
+ ):
+ raise ValidationError(
+ _("The guest information sending settings is not property set up.")
+ )
content = False
# build content
@@ -464,12 +499,14 @@ class TravellerReport(models.TransientModel):
content = self.generate_ses_travellers_list(
pms_property_id=pms_property.id,
date_target=self.date_target,
+ room_id=room.id if room else False,
)
elif self.report_type == "reservations":
content = self.generate_ses_reservation_list(
pms_property_id=pms_property.id,
date_from=self.date_from,
date_to=self.date_to,
+ room_id=room.id if room else False,
)
else:
content = self.generate_checkin_list(
@@ -479,22 +516,26 @@ class TravellerReport(models.TransientModel):
if content:
if self.is_ses:
+ institution_property_id = (
+ room.institution_property_id
+ if room
+ else pms_property.institution_property_id
+ )
if self.report_type == "travellers":
self.txt_filename = (
- pms_property.institution_property_id
+ institution_property_id
+ "-"
+ self.date_target.strftime("%Y%m%d")
)
else:
self.txt_filename = (
- pms_property.institution_property_id
+ institution_property_id
+ "-"
+ self.date_from.strftime("%Y%m%d")
+ "-"
+ self.date_to.strftime("%Y%m%d")
)
self.txt_filename = self.txt_filename + ".xml"
-
else:
self.txt_filename = (
pms_property.institution_property_id
@@ -521,6 +562,7 @@ class TravellerReport(models.TransientModel):
}
def generate_checkin_list(self, pms_property_id, date_target=False):
+ # DEPRECATED
regex = re.compile("[^a-zA-Z0-9]")
# check if there's guests info pending to send
@@ -541,11 +583,13 @@ class TravellerReport(models.TransientModel):
lines = self.env["pms.checkin.partner"].search(domain)
# build the property info record
# 1 | property id | property name | date | nÂș of checkin partners
+ institution_property_id = pms_property.institution_property_id
+ name = pms_property.name
content = (
"1|"
- + pms_property.institution_property_id.upper()
+ + institution_property_id.upper()
+ "|"
- + regex.sub(" ", pms_property.name.upper())
+ + regex.sub(" ", name.upper())
+ "|"
+ datetime.datetime.now().strftime("%Y%m%d|%H%M")
+ "|"
@@ -580,6 +624,7 @@ class TravellerReport(models.TransientModel):
return content
def send_file_gc(self, file_content, called_from_user, pms_property):
+ # DEPRECATED
try:
_logger.info(
"Sending file to Guardia Civil, Property %s, date: %s"
@@ -680,6 +725,7 @@ class TravellerReport(models.TransientModel):
)
def send_file_pn(self, file_content, called_from_user, pms_property):
+ # DEPRECATED
try:
base_url = "https://webpol.policia.es"
headers = {
@@ -805,6 +851,7 @@ class TravellerReport(models.TransientModel):
)
def send_file_institution(self, pms_property=False, offset=0, date_target=False):
+ # DEPRECATED
called_from_user = False
log = False
try:
@@ -898,33 +945,44 @@ class TravellerReport(models.TransientModel):
@api.model
def send_file_institution_async(self, offset=0):
+ # DEPRECATED
for prop in self.env["pms.property"].search([]):
if prop.institution:
self.send_file_institution(pms_property=prop, offset=offset)
time.sleep(0.5)
# SES RESERVATIONS
- def generate_ses_reservation_list(self, pms_property_id, date_from, date_to):
- reservation_ids = (
- self.env["pms.reservation"]
- .search(
- [
- ("pms_property_id", "=", pms_property_id),
- ("state", "!=", "cancel"),
- ("reservation_type", "!=", "out"),
- "|",
- ("date_order", ">=", date_from),
- ("date_order", "<=", date_to),
- ]
- )
- .mapped("id")
- )
+ def generate_ses_reservation_list(
+ self, pms_property_id, date_from, date_to, room_id=False
+ ):
+ domain = [
+ ("pms_property_id", "=", pms_property_id),
+ ("state", "!=", "cancel"),
+ ("reservation_type", "!=", "out"),
+ "|",
+ ("date_order", ">=", date_from),
+ ("date_order", "<=", date_to),
+ ]
+ if room_id:
+ domain.append(("preferred_room_id.room_id", "=", room_id))
+ reservation_ids = self.env["pms.reservation"].search(domain).mapped("id")
return self.generate_xml_reservations(reservation_ids)
def generate_xml_reservation(self, solicitud, reservation_id):
reservation = self.env["pms.reservation"].browse(reservation_id)
-
- if not reservation.pms_property_id.institution_property_id:
+ institution_property_id = False
+ if (
+ reservation.preferred_room_id
+ and reservation.preferred_room_id.institution_independent_account
+ ):
+ institution_property_id = (
+ reservation.preferred_room_id.institution_property_id
+ )
+ else:
+ institution_property_id = (
+ reservation.pms_property_id.institution_property_id
+ )
+ if not institution_property_id:
raise ValidationError(
_("The property does not have an institution property id.")
)
@@ -936,9 +994,7 @@ class TravellerReport(models.TransientModel):
establecimiento = ET.SubElement(comunicacion, "establecimiento")
# SOLICITUD > COMUNICACION > ESTABLECIMIENTO > CODIGO
- ET.SubElement(
- establecimiento, "codigo"
- ).text = reservation.pms_property_id.institution_property_id
+ ET.SubElement(establecimiento, "codigo").text = institution_property_id
# SOLICITUD > COMUNICACION > CONTRATO
_ses_xml_contract_elements(comunicacion, reservation)
@@ -974,17 +1030,14 @@ class TravellerReport(models.TransientModel):
return xml_str
# SES RESERVATIONS TRAVELLER REPORT
- def generate_ses_travellers_list(self, pms_property_id, date_target):
- reservation_ids = (
- self.env["pms.reservation"]
- .search(
- [
- ("pms_property_id", "=", pms_property_id),
- ("checkin", "=", date_target),
- ]
- )
- .mapped("id")
- )
+ def generate_ses_travellers_list(self, pms_property_id, date_target, room_id=False):
+ domain = [
+ ("pms_property_id", "=", pms_property_id),
+ ("checkin", "=", date_target),
+ ]
+ if room_id:
+ domain.append(("preferred_room_id.room_id", "=", room_id))
+ reservation_ids = self.env["pms.reservation"].search(domain).mapped("id")
return self.generate_xml_reservations_travellers_report(reservation_ids)
def generate_xml_reservation_travellers_report(
@@ -1029,19 +1082,34 @@ class TravellerReport(models.TransientModel):
):
raise ValidationError(_("There are some guests not onboard."))
else:
+ reservations = self.env["pms.reservation"].browse(reservation_ids)
+ independent_accounts = reservations.filtered(
+ lambda r: r.preferred_room_id.institution_independent_account
+ )
+ if independent_accounts:
+ institution_property_ids = independent_accounts.mapped(
+ "preferred_room_id.institution_property_id"
+ )
+ if len(institution_property_ids) != 1:
+ raise ValidationError(
+ _(
+ "All reservation rooms must have the same institution property id."
+ )
+ )
+ institution_property_id = institution_property_ids[0]
+ else:
+ pms_property = reservations[0].pms_property_id
+ institution_property_id = pms_property.institution_property_id
+ if not institution_property_id:
+ raise ValidationError(
+ _("The property does not have an institution property id.")
+ )
# SOLICITUD
solicitud = ET.Element("solicitud")
- pms_property = (
- self.env["pms.reservation"].browse(reservation_ids[0]).pms_property_id
- )
- if not pms_property.institution_property_id:
- raise ValidationError(
- _("The property does not have an institution property id.")
- )
# SOLICITUD -> CODIGO ESTABLECIMIENTO
ET.SubElement(
solicitud, "codigoEstablecimiento"
- ).text = pms_property.institution_property_id
+ ).text = institution_property_id
for reservation_id in reservation_ids:
if ignore_some_not_onboard:
num_people_on_board = len(
@@ -1084,6 +1152,17 @@ class TravellerReport(models.TransientModel):
for communication in self.env["pms.ses.communication"].search(domain):
data = False
try:
+ if (
+ communication.room_id
+ and communication.room_id.institution_independent_account
+ ):
+ institution_lessor_id = communication.room_id.institution_lessor_id
+ ses_url = communication.room_id.ses_url
+ else:
+ institution_lessor_id = (
+ communication.reservation_id.pms_property_id.institution_lessor_id
+ )
+ ses_url = communication.reservation_id.pms_property_id.ses_url
if communication.operation == DELETE_OPERATION_CODE:
communication_to_cancel = self.env["pms.ses.communication"].search(
[
@@ -1115,7 +1194,7 @@ class TravellerReport(models.TransientModel):
communication.communication_xml = data
data = _string_to_zip_to_base64(data)
payload = _generate_payload(
- communication.reservation_id.pms_property_id.institution_lessor_id,
+ institution_lessor_id,
communication.operation,
communication.entity,
data,
@@ -1125,7 +1204,7 @@ class TravellerReport(models.TransientModel):
soap_response = requests.request(
"POST",
- communication.reservation_id.pms_property_id.ses_url,
+ ses_url,
headers=_get_auth_headers(communication),
data=payload,
verify=get_module_resource("pms_l10n_es", "static", "cert.pem"),
@@ -1162,6 +1241,17 @@ class TravellerReport(models.TransientModel):
]
):
try:
+ if (
+ communication.room_id
+ and communication.room_id.institution_independent_account
+ ):
+ institution_lessor_id = communication.room_id.institution_lessor_id
+ ses_url = communication.room_id.ses_url
+ else:
+ institution_lessor_id = (
+ communication.reservation_id.pms_property_id.institution_lessor_id
+ )
+ ses_url = communication.reservation_id.pms_property_id.ses_url
time_difference = fields.Datetime.now() - communication.create_date
hours_difference = (
time_difference.days * 24 + time_difference.seconds // 3600
@@ -1181,7 +1271,7 @@ class TravellerReport(models.TransientModel):
communication.communication_xml = data
data = _string_to_zip_to_base64(data)
payload = _generate_payload(
- communication.reservation_id.pms_property_id.institution_lessor_id,
+ institution_lessor_id,
communication.operation,
communication.entity,
data,
@@ -1191,7 +1281,7 @@ class TravellerReport(models.TransientModel):
soap_response = requests.request(
"POST",
- communication.reservation_id.pms_property_id.ses_url,
+ ses_url,
headers=_get_auth_headers(communication),
data=payload,
verify=get_module_resource("pms_l10n_es", "static", "cert.pem"),
@@ -1224,6 +1314,17 @@ class TravellerReport(models.TransientModel):
]
):
try:
+ if (
+ communication.room_id
+ and communication.room_id.institution_independent_account
+ ):
+ institution_lessor_id = communication.room_id.institution_lessor_id
+ ses_url = communication.room_id.ses_url
+ else:
+ institution_lessor_id = (
+ communication.reservation_id.pms_property_id.institution_lessor_id
+ )
+ ses_url = communication.reservation_id.pms_property_id.ses_url
var_xml_get_batch = f"""
@@ -1233,7 +1334,7 @@ class TravellerReport(models.TransientModel):
communication.query_status_xml = var_xml_get_batch
data = _string_to_zip_to_base64(var_xml_get_batch)
payload = _generate_payload(
- communication.reservation_id.pms_property_id.institution_lessor_id,
+ institution_lessor_id,
"C",
False,
data,
@@ -1243,7 +1344,7 @@ class TravellerReport(models.TransientModel):
soap_response = requests.request(
"POST",
- communication.reservation_id.pms_property_id.ses_url,
+ ses_url,
headers=_get_auth_headers(communication),
data=payload,
verify=get_module_resource("pms_l10n_es", "static", "cert.pem"),