mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
@@ -19,24 +19,24 @@
|
|||||||
<field name="code">model.send_file_institution_async()</field>
|
<field name="code">model.send_file_institution_async()</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.cron" id="autocreate_traveller_report_com">
|
<record model="ir.cron" id="autosend_incomplete_traveller_report_com">
|
||||||
<field name="name">
|
<field name="name">
|
||||||
SES Automatic Creation Traveller Communications
|
SES Automatic Sending Incomplete Traveller Reports
|
||||||
</field>
|
</field>
|
||||||
<field name="active" eval="False" />
|
<field name="active" eval="False" />
|
||||||
<field name="interval_number">1</field>
|
<field name="interval_number">1</field>
|
||||||
<field name="user_id" ref="base.user_root" />
|
<field name="user_id" ref="base.user_root" />
|
||||||
<field name="interval_type">days</field>
|
<field name="interval_type">hours</field>
|
||||||
<field name="numbercall">-1</field>
|
<field name="numbercall">-1</field>
|
||||||
<field name="doall" eval="False" />
|
<field name="doall" eval="False" />
|
||||||
<field name="state">code</field>
|
<field name="state">code</field>
|
||||||
<field name="model_id" ref="model_traveller_report_wizard" />
|
<field name="model_id" ref="model_traveller_report_wizard" />
|
||||||
<field
|
<field
|
||||||
name="nextcall"
|
name="nextcall"
|
||||||
eval="datetime.now(pytz.timezone('UTC')).strftime('%Y-%m-%d 23:30:00')"
|
eval="datetime.now(pytz.timezone('UTC')).strftime('%Y-%m-%d %H:%M:%S')"
|
||||||
/>
|
/>
|
||||||
<field name="code">
|
<field name="code">
|
||||||
model.create_pending_notifications_traveller_report()
|
model.ses_send_incomplete_traveller_reports(20)
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import logging
|
|||||||
|
|
||||||
from odoo import api, fields, models
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
from ..wizards.traveller_report import CREATE_OPERATION_CODE
|
||||||
|
|
||||||
CODE_SPAIN = "ES"
|
CODE_SPAIN = "ES"
|
||||||
CODE_NIF = "D"
|
CODE_NIF = "D"
|
||||||
CODE_NIE = "N"
|
CODE_NIE = "N"
|
||||||
@@ -80,3 +82,47 @@ class PmsCheckinPartner(models.Model):
|
|||||||
manual_fields = super(PmsCheckinPartner, self)._checkin_manual_fields()
|
manual_fields = super(PmsCheckinPartner, self)._checkin_manual_fields()
|
||||||
manual_fields.extend(["support_number"])
|
manual_fields.extend(["support_number"])
|
||||||
return manual_fields
|
return manual_fields
|
||||||
|
|
||||||
|
def write(self, vals):
|
||||||
|
result = super(PmsCheckinPartner, self).write(vals)
|
||||||
|
for record in self:
|
||||||
|
if (
|
||||||
|
"state" in vals
|
||||||
|
and record.reservation_id.pms_property_id.institution == "ses"
|
||||||
|
and record.state == "onboard"
|
||||||
|
):
|
||||||
|
previous_incomplete_traveller_communication = self.env[
|
||||||
|
"pms.ses.communication"
|
||||||
|
].search(
|
||||||
|
[
|
||||||
|
("reservation_id", "=", record.reservation_id.id),
|
||||||
|
("entity", "=", "PV"),
|
||||||
|
("operation", "=", CREATE_OPERATION_CODE),
|
||||||
|
("state", "=", "incomplete"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if not previous_incomplete_traveller_communication:
|
||||||
|
previous_incomplete_traveller_communication = self.env[
|
||||||
|
"pms.ses.communication"
|
||||||
|
].create(
|
||||||
|
{
|
||||||
|
"reservation_id": record.reservation_id.id,
|
||||||
|
"operation": CREATE_OPERATION_CODE,
|
||||||
|
"entity": "PV",
|
||||||
|
"state": "incomplete",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
# check if all checkin partners in the reservation are onboard
|
||||||
|
if (
|
||||||
|
all(
|
||||||
|
[
|
||||||
|
checkin.state == "onboard"
|
||||||
|
for checkin in record.reservation_id.checkin_partner_ids
|
||||||
|
]
|
||||||
|
)
|
||||||
|
and len(record.reservation_id.checkin_partner_ids)
|
||||||
|
== record.reservation_id.adults
|
||||||
|
):
|
||||||
|
previous_incomplete_traveller_communication.state = "to_send"
|
||||||
|
|
||||||
|
return result
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ class PmsReservation(models.Model):
|
|||||||
self.create_communication(
|
self.create_communication(
|
||||||
reservation.id, DELETE_OPERATION_CODE, "RH"
|
reservation.id, DELETE_OPERATION_CODE, "RH"
|
||||||
)
|
)
|
||||||
elif (
|
elif vals["state"] != "cancel" and (
|
||||||
vals["state"] != "cancel"
|
last_communication.operation == DELETE_OPERATION_CODE
|
||||||
and last_communication.operation == DELETE_OPERATION_CODE
|
or not last_communication
|
||||||
):
|
):
|
||||||
self.create_communication(
|
self.create_communication(
|
||||||
reservation.id, CREATE_OPERATION_CODE, "RH"
|
reservation.id, CREATE_OPERATION_CODE, "RH"
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class PmsSesCommunication(models.Model):
|
|||||||
default="to_send",
|
default="to_send",
|
||||||
required=True,
|
required=True,
|
||||||
selection=[
|
selection=[
|
||||||
|
("incomplete", "Incomplete checkin data"),
|
||||||
("to_send", "Pending Notification"),
|
("to_send", "Pending Notification"),
|
||||||
("to_process", "Pending Processing"),
|
("to_process", "Pending Processing"),
|
||||||
("error_sending", "Error Sending"),
|
("error_sending", "Error Sending"),
|
||||||
@@ -51,6 +52,7 @@ class PmsSesCommunication(models.Model):
|
|||||||
("processed", "Processed"),
|
("processed", "Processed"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
sending_result = fields.Text(
|
sending_result = fields.Text(
|
||||||
string="Sending Result",
|
string="Sending Result",
|
||||||
help="Notification sending result",
|
help="Notification sending result",
|
||||||
|
|||||||
@@ -32,10 +32,19 @@ XML_PENDING = "5"
|
|||||||
CREATE_OPERATION_CODE = "A"
|
CREATE_OPERATION_CODE = "A"
|
||||||
DELETE_OPERATION_CODE = "B"
|
DELETE_OPERATION_CODE = "B"
|
||||||
|
|
||||||
|
|
||||||
# Disable insecure request warnings
|
# Disable insecure request warnings
|
||||||
# requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
# requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||||
|
|
||||||
|
|
||||||
|
def clean_string_ses(string):
|
||||||
|
clean_string = re.sub(r"[^a-zA-Z0-9\s]", "", string).upper()
|
||||||
|
|
||||||
|
clean_string = " ".join(clean_string.split())
|
||||||
|
|
||||||
|
return clean_string
|
||||||
|
|
||||||
|
|
||||||
def _string_to_zip_to_base64(string_data):
|
def _string_to_zip_to_base64(string_data):
|
||||||
zip_buffer = io.BytesIO()
|
zip_buffer = io.BytesIO()
|
||||||
with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
|
with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
|
||||||
@@ -56,7 +65,7 @@ def _ses_xml_payment_elements(contrato, reservation):
|
|||||||
ET.SubElement(pago, "tipoPago").text = tipo_pago
|
ET.SubElement(pago, "tipoPago").text = tipo_pago
|
||||||
|
|
||||||
|
|
||||||
def _ses_xml_contract_elements(comunicacion, reservation):
|
def _ses_xml_contract_elements(comunicacion, reservation, people=False):
|
||||||
contrato = ET.SubElement(comunicacion, "contrato")
|
contrato = ET.SubElement(comunicacion, "contrato")
|
||||||
ET.SubElement(contrato, "referencia").text = reservation.name
|
ET.SubElement(contrato, "referencia").text = reservation.name
|
||||||
ET.SubElement(contrato, "fechaContrato").text = str(reservation.date_order)[:10]
|
ET.SubElement(contrato, "fechaContrato").text = str(reservation.date_order)[:10]
|
||||||
@@ -66,7 +75,10 @@ def _ses_xml_contract_elements(comunicacion, reservation):
|
|||||||
ET.SubElement(
|
ET.SubElement(
|
||||||
contrato, "fechaSalida"
|
contrato, "fechaSalida"
|
||||||
).text = f"{str(reservation.checkout)[:10]}T00:00:00"
|
).text = f"{str(reservation.checkout)[:10]}T00:00:00"
|
||||||
ET.SubElement(contrato, "numPersonas").text = str(reservation.adults)
|
if people:
|
||||||
|
ET.SubElement(contrato, "numPersonas").text = str(people)
|
||||||
|
else:
|
||||||
|
ET.SubElement(contrato, "numPersonas").text = str(reservation.adults)
|
||||||
_ses_xml_payment_elements(contrato, reservation)
|
_ses_xml_payment_elements(contrato, reservation)
|
||||||
|
|
||||||
|
|
||||||
@@ -90,37 +102,37 @@ def _ses_xml_map_document_type(code):
|
|||||||
|
|
||||||
def _ses_xml_person_names_elements(persona, reservation, checkin_partner):
|
def _ses_xml_person_names_elements(persona, reservation, checkin_partner):
|
||||||
if reservation:
|
if reservation:
|
||||||
name = False
|
ses_firstname = False
|
||||||
if reservation.partner_id.firstname:
|
if reservation.partner_id.firstname:
|
||||||
name = reservation.partner_id.firstname
|
ses_firstname = clean_string_ses(reservation.partner_id.firstname)
|
||||||
elif reservation.partner_name:
|
elif reservation.partner_name:
|
||||||
name = reservation.partner_name.split(" ")[0]
|
ses_firstname = clean_string_ses(reservation.partner_name).split(" ")[0]
|
||||||
_ses_xml_text_element_and_validate(
|
_ses_xml_text_element_and_validate(
|
||||||
persona,
|
persona,
|
||||||
"nombre",
|
"nombre",
|
||||||
name,
|
ses_firstname,
|
||||||
_("The reservation does not have a name."),
|
_("The reservation does not have a name."),
|
||||||
)
|
)
|
||||||
|
|
||||||
if reservation.partner_id.lastname:
|
if reservation.partner_id.lastname:
|
||||||
firstname = reservation.partner_id.lastname
|
ses_lastname = clean_string_ses(reservation.partner_id.lastname)
|
||||||
elif reservation.partner_name and len(reservation.partner_name.split(" ")) > 1:
|
elif reservation.partner_name and len(reservation.partner_name.split(" ")) > 1:
|
||||||
firstname = reservation.partner_name.split(" ")[1]
|
ses_lastname = clean_string_ses(reservation.partner_name).split(" ")[1]
|
||||||
else:
|
else:
|
||||||
firstname = "No aplica"
|
ses_lastname = "No aplica"
|
||||||
ET.SubElement(persona, "apellido1").text = firstname
|
ET.SubElement(persona, "apellido1").text = ses_lastname
|
||||||
|
|
||||||
elif checkin_partner:
|
elif checkin_partner:
|
||||||
_ses_xml_text_element_and_validate(
|
_ses_xml_text_element_and_validate(
|
||||||
persona,
|
persona,
|
||||||
"nombre",
|
"nombre",
|
||||||
checkin_partner.firstname,
|
clean_string_ses(checkin_partner.firstname),
|
||||||
_("The guest does not have a name."),
|
_("The guest does not have a name."),
|
||||||
)
|
)
|
||||||
_ses_xml_text_element_and_validate(
|
_ses_xml_text_element_and_validate(
|
||||||
persona,
|
persona,
|
||||||
"apellido1",
|
"apellido1",
|
||||||
checkin_partner.lastname,
|
clean_string_ses(checkin_partner.lastname),
|
||||||
_("The guest does not have a lastname."),
|
_("The guest does not have a lastname."),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -128,7 +140,7 @@ def _ses_xml_person_names_elements(persona, reservation, checkin_partner):
|
|||||||
_ses_xml_text_element_and_validate(
|
_ses_xml_text_element_and_validate(
|
||||||
persona,
|
persona,
|
||||||
"apellido2",
|
"apellido2",
|
||||||
checkin_partner.partner_id.lastname2,
|
clean_string_ses(checkin_partner.partner_id.lastname2),
|
||||||
_("The guest does not have a second lastname."),
|
_("The guest does not have a second lastname."),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -242,7 +254,12 @@ def _ses_xml_person_contact_elements(persona, reservation, checkin_partner=False
|
|||||||
|
|
||||||
for contact in contact_methods:
|
for contact in contact_methods:
|
||||||
if contact:
|
if contact:
|
||||||
tag = "telefono" if "@" not in contact else "correo"
|
if "@" in contact:
|
||||||
|
tag = "correo"
|
||||||
|
contact = contact[0:50]
|
||||||
|
else:
|
||||||
|
tag = "telefono"
|
||||||
|
contact = contact[0:20]
|
||||||
ET.SubElement(persona, tag).text = contact
|
ET.SubElement(persona, tag).text = contact
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -324,6 +341,8 @@ def _handle_request_exception(communication, e):
|
|||||||
communication.sending_result = f"Request error: {e}"
|
communication.sending_result = f"Request error: {e}"
|
||||||
else:
|
else:
|
||||||
communication.processing_result = f"Request error: {e}"
|
communication.processing_result = f"Request error: {e}"
|
||||||
|
else:
|
||||||
|
communication.sending_result = f"Unexpected error: {e}"
|
||||||
|
|
||||||
|
|
||||||
class TravellerReport(models.TransientModel):
|
class TravellerReport(models.TransientModel):
|
||||||
@@ -751,8 +770,9 @@ class TravellerReport(models.TransientModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def send_file_institution(self, pms_property=False, offset=0, date_target=False):
|
def send_file_institution(self, pms_property=False, offset=0, date_target=False):
|
||||||
|
called_from_user = False
|
||||||
|
log = False
|
||||||
try:
|
try:
|
||||||
called_from_user = False
|
|
||||||
if not pms_property:
|
if not pms_property:
|
||||||
called_from_user = True
|
called_from_user = True
|
||||||
pms_property = self.env["pms.property"].search(
|
pms_property = self.env["pms.property"].search(
|
||||||
@@ -932,21 +952,23 @@ class TravellerReport(models.TransientModel):
|
|||||||
)
|
)
|
||||||
return self.generate_xml_reservations_travellers_report(reservation_ids)
|
return self.generate_xml_reservations_travellers_report(reservation_ids)
|
||||||
|
|
||||||
def generate_xml_reservation_travellers_report(self, solicitud, reservation_id):
|
def generate_xml_reservation_travellers_report(
|
||||||
|
self, solicitud, reservation_id, people=False
|
||||||
|
):
|
||||||
reservation = self.env["pms.reservation"].browse(reservation_id)
|
reservation = self.env["pms.reservation"].browse(reservation_id)
|
||||||
comunicacion = ET.SubElement(solicitud, "comunicacion")
|
comunicacion = ET.SubElement(solicitud, "comunicacion")
|
||||||
_ses_xml_contract_elements(comunicacion, reservation)
|
_ses_xml_contract_elements(comunicacion, reservation, people)
|
||||||
|
|
||||||
for checkin_partner in reservation.checkin_partner_ids.filtered(
|
for checkin_partner in reservation.checkin_partner_ids.filtered(
|
||||||
lambda x: x.state == "onboard"
|
lambda x: x.state == "onboard"
|
||||||
):
|
):
|
||||||
_ses_xml_person_elements(comunicacion, checkin_partner)
|
_ses_xml_person_elements(comunicacion, checkin_partner)
|
||||||
|
|
||||||
def generate_xml_reservations_travellers_report(self, reservation_ids):
|
def generate_xml_reservations_travellers_report(
|
||||||
|
self, reservation_ids, ignore_some_not_onboard=False
|
||||||
|
):
|
||||||
if not reservation_ids:
|
if not reservation_ids:
|
||||||
raise ValidationError(_("Theres's no reservation to generate the XML"))
|
raise ValidationError(_("Theres's no reservation to generate the XML"))
|
||||||
|
elif (
|
||||||
if (
|
|
||||||
len(
|
len(
|
||||||
self.env["pms.reservation"]
|
self.env["pms.reservation"]
|
||||||
.browse(reservation_ids)
|
.browse(reservation_ids)
|
||||||
@@ -955,49 +977,64 @@ class TravellerReport(models.TransientModel):
|
|||||||
> 1
|
> 1
|
||||||
):
|
):
|
||||||
raise ValidationError(_("The reservations must be from the same property."))
|
raise ValidationError(_("The reservations must be from the same property."))
|
||||||
if not any(
|
elif all(
|
||||||
state == "onboard"
|
state != "onboard"
|
||||||
for state in self.env["pms.reservation"]
|
for state in self.env["pms.reservation"]
|
||||||
.browse(reservation_ids)
|
.browse(reservation_ids)
|
||||||
.mapped("checkin_partner_ids")
|
.mapped("checkin_partner_ids")
|
||||||
.mapped("state")
|
.mapped("state")
|
||||||
):
|
):
|
||||||
raise ValidationError(
|
raise ValidationError(_("There are no guests onboard."))
|
||||||
_("There are no guests to generate the travellers report.")
|
elif not ignore_some_not_onboard and any(
|
||||||
|
state != "onboard"
|
||||||
|
for state in self.env["pms.reservation"]
|
||||||
|
.browse(reservation_ids)
|
||||||
|
.mapped("checkin_partner_ids")
|
||||||
|
.mapped("state")
|
||||||
|
):
|
||||||
|
raise ValidationError(_("There are some guests not onboard."))
|
||||||
|
else:
|
||||||
|
# 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:
|
||||||
# SOLICITUD
|
raise ValidationError(
|
||||||
solicitud = ET.Element("solicitud")
|
_("The property does not have an institution property id.")
|
||||||
|
)
|
||||||
pms_property = (
|
# SOLICITUD -> CODIGO ESTABLECIMIENTO
|
||||||
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
|
|
||||||
|
|
||||||
for reservation_id in reservation_ids:
|
|
||||||
ET.SubElement(
|
ET.SubElement(
|
||||||
solicitud,
|
solicitud, "codigoEstablecimiento"
|
||||||
self.generate_xml_reservation_travellers_report(
|
).text = pms_property.institution_property_id
|
||||||
solicitud, reservation_id
|
for reservation_id in reservation_ids:
|
||||||
),
|
if ignore_some_not_onboard:
|
||||||
|
num_people_on_board = len(
|
||||||
|
self.env["pms.reservation"]
|
||||||
|
.browse(reservation_id)
|
||||||
|
.checkin_partner_ids.filtered(lambda x: x.state == "onboard")
|
||||||
|
)
|
||||||
|
ET.SubElement(
|
||||||
|
solicitud,
|
||||||
|
self.generate_xml_reservation_travellers_report(
|
||||||
|
solicitud, reservation_id, people=num_people_on_board
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
ET.SubElement(
|
||||||
|
solicitud,
|
||||||
|
self.generate_xml_reservation_travellers_report(
|
||||||
|
solicitud,
|
||||||
|
reservation_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
xml_str = ET.tostring(solicitud, encoding="unicode")
|
||||||
|
xml_str = (
|
||||||
|
'<ns2:peticion xmlns:ns2="http://www.neg.hospedajes.mir.es/altaParteHospedaje">'
|
||||||
|
+ xml_str
|
||||||
|
+ "</ns2:peticion>"
|
||||||
)
|
)
|
||||||
xml_str = ET.tostring(solicitud, encoding="unicode")
|
return xml_str
|
||||||
|
|
||||||
xml_str = (
|
|
||||||
'<ns2:peticion xmlns:ns2="http://www.neg.hospedajes.mir.es/altaParteHospedaje">'
|
|
||||||
+ xml_str
|
|
||||||
+ "</ns2:peticion>"
|
|
||||||
)
|
|
||||||
return xml_str
|
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def ses_send_communications(self, entity):
|
def ses_send_communications(self, entity):
|
||||||
@@ -1008,31 +1045,51 @@ class TravellerReport(models.TransientModel):
|
|||||||
("entity", "=", entity),
|
("entity", "=", entity),
|
||||||
]
|
]
|
||||||
):
|
):
|
||||||
|
|
||||||
data = False
|
data = False
|
||||||
if communication.entity == "RH":
|
|
||||||
data = self.generate_xml_reservations([communication.reservation_id.id])
|
|
||||||
elif communication.entity == "PV":
|
|
||||||
data = self.generate_xml_reservations_travellers_report(
|
|
||||||
[communication.reservation_id.id]
|
|
||||||
)
|
|
||||||
communication.communication_xml = data
|
|
||||||
data = _string_to_zip_to_base64(data)
|
|
||||||
payload = _generate_payload(
|
|
||||||
communication.reservation_id.pms_property_id.institution_lessor_id,
|
|
||||||
communication.operation,
|
|
||||||
communication.entity,
|
|
||||||
data,
|
|
||||||
)
|
|
||||||
communication.communication_soap = payload
|
|
||||||
communication.communication_time = fields.Datetime.now()
|
|
||||||
try:
|
try:
|
||||||
|
if communication.operation == DELETE_OPERATION_CODE:
|
||||||
|
communication_to_cancel = self.env["pms.ses.communication"].search(
|
||||||
|
[
|
||||||
|
("reservation_id", "=", communication.reservation_id.id),
|
||||||
|
("state", "!=", "to_send"),
|
||||||
|
("entity", "=", communication.entity),
|
||||||
|
("operation", "=", CREATE_OPERATION_CODE),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
data = (
|
||||||
|
"<anul:comunicaciones "
|
||||||
|
'xmlns:anul="http://www.neg.hospedajes.mir.es/anularComunicacion">'
|
||||||
|
+ "<anul:codigoComunicacion>"
|
||||||
|
+ communication_to_cancel.communication_id
|
||||||
|
+ "</anul:codigoComunicacion>"
|
||||||
|
+ "</anul:comunicaciones>"
|
||||||
|
)
|
||||||
|
elif communication.operation == CREATE_OPERATION_CODE:
|
||||||
|
if communication.entity == "RH":
|
||||||
|
data = self.generate_xml_reservations(
|
||||||
|
[communication.reservation_id.id]
|
||||||
|
)
|
||||||
|
elif communication.entity == "PV":
|
||||||
|
data = self.generate_xml_reservations_travellers_report(
|
||||||
|
[communication.reservation_id.id]
|
||||||
|
)
|
||||||
|
communication.communication_xml = data
|
||||||
|
data = _string_to_zip_to_base64(data)
|
||||||
|
payload = _generate_payload(
|
||||||
|
communication.reservation_id.pms_property_id.institution_lessor_id,
|
||||||
|
communication.operation,
|
||||||
|
communication.entity,
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
communication.communication_soap = payload
|
||||||
|
communication.communication_time = fields.Datetime.now()
|
||||||
|
|
||||||
soap_response = requests.request(
|
soap_response = requests.request(
|
||||||
"POST",
|
"POST",
|
||||||
communication.reservation_id.pms_property_id.ses_url,
|
communication.reservation_id.pms_property_id.ses_url,
|
||||||
headers=_get_auth_headers(communication),
|
headers=_get_auth_headers(communication),
|
||||||
data=payload,
|
data=payload,
|
||||||
verify=get_module_resource("pms_l10n_es", "static", "ses_cert.pem"),
|
verify=get_module_resource("pms_l10n_es", "static", "cert.pem"),
|
||||||
)
|
)
|
||||||
root = ET.fromstring(soap_response.text)
|
root = ET.fromstring(soap_response.text)
|
||||||
communication.sending_result = root.find(".//descripcion").text
|
communication.sending_result = root.find(".//descripcion").text
|
||||||
@@ -1049,6 +1106,72 @@ class TravellerReport(models.TransientModel):
|
|||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
_handle_request_exception(communication, e)
|
_handle_request_exception(communication, e)
|
||||||
|
except Exception as e:
|
||||||
|
_handle_request_exception(communication, e)
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def ses_send_incomplete_traveller_reports(
|
||||||
|
self, hours_after_first_checkin_to_inform
|
||||||
|
):
|
||||||
|
# iterate through incomplete communications
|
||||||
|
for communication in self.env["pms.ses.communication"].search(
|
||||||
|
[
|
||||||
|
("state", "=", "incomplete"),
|
||||||
|
("entity", "=", "PV"),
|
||||||
|
]
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
if (
|
||||||
|
fields.Datetime.now() - communication.create_date
|
||||||
|
).hours > hours_after_first_checkin_to_inform:
|
||||||
|
# add a note to the reservation
|
||||||
|
communication.reservation_id.sudo().message_post(
|
||||||
|
body=_(
|
||||||
|
"There was't enough guests in the reservation when data "
|
||||||
|
"was sent to SES. Sent to SES with onboard guests"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
data = self.generate_xml_reservations_travellers_report(
|
||||||
|
[communication.reservation_id.id],
|
||||||
|
ignore_some_not_onboard=True,
|
||||||
|
)
|
||||||
|
communication.communication_xml = data
|
||||||
|
data = _string_to_zip_to_base64(data)
|
||||||
|
payload = _generate_payload(
|
||||||
|
communication.reservation_id.pms_property_id.institution_lessor_id,
|
||||||
|
communication.operation,
|
||||||
|
communication.entity,
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
communication.communication_soap = payload
|
||||||
|
communication.communication_time = fields.Datetime.now()
|
||||||
|
|
||||||
|
soap_response = requests.request(
|
||||||
|
"POST",
|
||||||
|
communication.reservation_id.pms_property_id.ses_url,
|
||||||
|
headers=_get_auth_headers(communication),
|
||||||
|
data=payload,
|
||||||
|
verify=get_module_resource(
|
||||||
|
"pms_l10n_es", "static", "ses_cert.pem"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
root = ET.fromstring(soap_response.text)
|
||||||
|
communication.sending_result = root.find(".//descripcion").text
|
||||||
|
communication.response_communication_soap = soap_response.text
|
||||||
|
result_code = root.find(".//codigo").text
|
||||||
|
if result_code == REQUEST_CODE_OK:
|
||||||
|
communication.communication_id = root.find(".//lote").text
|
||||||
|
if communication.operation == CREATE_OPERATION_CODE:
|
||||||
|
communication.state = "to_process"
|
||||||
|
else:
|
||||||
|
communication.state = "processed"
|
||||||
|
else:
|
||||||
|
communication.state = "error_sending"
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
_handle_request_exception(communication, e)
|
||||||
|
except Exception as e:
|
||||||
|
_handle_request_exception(communication, e)
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def ses_process_communications(self):
|
def ses_process_communications(self):
|
||||||
@@ -1058,23 +1181,24 @@ class TravellerReport(models.TransientModel):
|
|||||||
("operation", "!=", DELETE_OPERATION_CODE),
|
("operation", "!=", DELETE_OPERATION_CODE),
|
||||||
]
|
]
|
||||||
):
|
):
|
||||||
var_xml_get_batch = f"""
|
|
||||||
<con:lotes
|
|
||||||
xmlns:con="http://www.neg.hospedajes.mir.es/consultarComunicacion">
|
|
||||||
<con:lote>{communication.communication_id}</con:lote>
|
|
||||||
</con:lotes>
|
|
||||||
"""
|
|
||||||
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,
|
|
||||||
"C",
|
|
||||||
"",
|
|
||||||
data,
|
|
||||||
)
|
|
||||||
communication.query_status_soap = payload
|
|
||||||
communication.query_status_time = fields.Datetime.now()
|
|
||||||
try:
|
try:
|
||||||
|
var_xml_get_batch = f"""
|
||||||
|
<con:lotes
|
||||||
|
xmlns:con="http://www.neg.hospedajes.mir.es/consultarComunicacion">
|
||||||
|
<con:lote>{communication.communication_id}</con:lote>
|
||||||
|
</con:lotes>
|
||||||
|
"""
|
||||||
|
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,
|
||||||
|
"C",
|
||||||
|
"",
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
communication.query_status_soap = payload
|
||||||
|
communication.query_status_time = fields.Datetime.now()
|
||||||
|
|
||||||
soap_response = requests.request(
|
soap_response = requests.request(
|
||||||
"POST",
|
"POST",
|
||||||
communication.reservation_id.pms_property_id.ses_url,
|
communication.reservation_id.pms_property_id.ses_url,
|
||||||
@@ -1105,6 +1229,8 @@ class TravellerReport(models.TransientModel):
|
|||||||
communication.processing_result = root.find(".//descripcion").text
|
communication.processing_result = root.find(".//descripcion").text
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
_handle_request_exception(communication, e)
|
_handle_request_exception(communication, e)
|
||||||
|
except Exception as e:
|
||||||
|
_handle_request_exception(communication, e)
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def create_pending_notifications_traveller_report(self):
|
def create_pending_notifications_traveller_report(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user