notif_report #3

Merged
jonas merged 18 commits from notif_report into main 2025-10-06 12:50:41 +00:00
Showing only changes of commit dbfbd53ad9 - Show all commits

View File

@@ -1,169 +0,0 @@
import xml.etree.ElementTree as ET
from datetime import datetime, timezone
from typing import List, Optional
# TimeSpan class according to XSD: <TimeSpan Start="..." End="..." Duration="..." StartWindow="..." EndWindow="..."/>
class TimeSpan:
def __init__(
self,
start: str,
end: str = None,
duration: str = None,
start_window: str = None,
end_window: str = None,
):
self.start = start
self.end = end
self.duration = duration
self.start_window = start_window
self.end_window = end_window
def to_xml(self):
attrib = {"Start": self.start}
if self.end:
attrib["End"] = self.end
if self.duration:
attrib["Duration"] = self.duration
if self.start_window:
attrib["StartWindow"] = self.start_window
if self.end_window:
attrib["EndWindow"] = self.end_window
return ET.Element(_ns("TimeSpan"), attrib)
NAMESPACE = "http://www.opentravel.org/OTA/2003/05"
ET.register_namespace("", NAMESPACE)
def _ns(tag):
return f"{{{NAMESPACE}}}{tag}"
class ResGuest:
def __init__(
self,
given_name: str,
surname: str,
gender: Optional[str] = None,
birth_date: Optional[str] = None,
language: Optional[str] = None,
name_prefix: Optional[str] = None,
name_title: Optional[str] = None,
email: Optional[str] = None,
address: Optional[dict] = None,
telephones: Optional[list] = None,
):
self.given_name = given_name
self.surname = surname
self.gender = gender
self.birth_date = birth_date
self.language = language
self.name_prefix = name_prefix
self.name_title = name_title
self.email = email
self.address = address or {}
self.telephones = telephones or []
def to_xml(self):
resguest_elem = ET.Element(_ns("ResGuest"))
profiles_elem = ET.SubElement(resguest_elem, _ns("Profiles"))
profileinfo_elem = ET.SubElement(profiles_elem, _ns("ProfileInfo"))
profile_elem = ET.SubElement(profileinfo_elem, _ns("Profile"))
customer_elem = ET.SubElement(profile_elem, _ns("Customer"))
if self.gender:
customer_elem.set("Gender", self.gender)
if self.birth_date:
customer_elem.set("BirthDate", self.birth_date)
if self.language:
customer_elem.set("Language", self.language)
personname_elem = ET.SubElement(customer_elem, _ns("PersonName"))
if self.name_prefix:
ET.SubElement(personname_elem, _ns("NamePrefix")).text = self.name_prefix
ET.SubElement(personname_elem, _ns("GivenName")).text = self.given_name
ET.SubElement(personname_elem, _ns("Surname")).text = self.surname
if self.name_title:
ET.SubElement(personname_elem, _ns("NameTitle")).text = self.name_title
for tel in self.telephones:
tel_elem = ET.SubElement(customer_elem, _ns("Telephone"))
for k, v in tel.items():
tel_elem.set(k, v)
if self.email:
ET.SubElement(customer_elem, _ns("Email")).text = self.email
if self.address:
address_elem = ET.SubElement(customer_elem, _ns("Address"))
for k, v in self.address.items():
if k == "CountryName":
country_elem = ET.SubElement(address_elem, _ns("CountryName"))
if isinstance(v, dict):
for ck, cv in v.items():
country_elem.set(ck, cv)
else:
country_elem.text = v
else:
ET.SubElement(address_elem, _ns(k)).text = v
return resguest_elem
def __str__(self):
from lxml import etree
elem = self.to_xml()
xml_bytes = ET.tostring(elem, encoding="utf-8")
parser = etree.XMLParser(remove_blank_text=True)
lxml_elem = etree.fromstring(xml_bytes, parser)
return etree.tostring(lxml_elem, pretty_print=True, encoding="unicode")
class RoomStay:
def __init__(self, room_type: str, timespan: TimeSpan, guests: List[ResGuest]):
self.room_type = room_type
self.timespan = timespan
self.guests = guests
def to_xml(self):
roomstay_elem = ET.Element(_ns("RoomStay"))
ET.SubElement(roomstay_elem, _ns("RoomType")).set(
"RoomTypeCode", self.room_type
)
roomstay_elem.append(self.timespan.to_xml())
guests_elem = ET.SubElement(roomstay_elem, _ns("Guests"))
for guest in self.guests:
guests_elem.append(guest.to_xml())
return roomstay_elem
class Reservation:
def __init__(
self,
reservation_id: str,
hotel_code: str,
roomstays: List[RoomStay],
create_time: Optional[str] = None,
):
self.reservation_id = reservation_id
self.hotel_code = hotel_code
self.roomstays = roomstays
self.create_time = create_time or datetime.now(timezone.utc).isoformat()
def to_xml(self):
res_elem = ET.Element(_ns("HotelReservation"))
uniqueid_elem = ET.SubElement(res_elem, _ns("UniqueID"))
uniqueid_elem.set("Type", "14")
uniqueid_elem.set("ID", self.reservation_id)
hotel_elem = ET.SubElement(res_elem, _ns("Hotel"))
hotel_elem.set("HotelCode", self.hotel_code)
roomstays_elem = ET.SubElement(res_elem, _ns("RoomStays"))
for rs in self.roomstays:
roomstays_elem.append(rs.to_xml())
res_elem.set("CreateDateTime", self.create_time)
return res_elem
def to_xml_string(self):
root = ET.Element(
_ns("OTA_ResRetrieveRS"),
{"Version": "2024-10", "TimeStamp": datetime.now(timezone.utc).isoformat()},
)
success_elem = ET.SubElement(root, _ns("Success"))
reservations_list = ET.SubElement(root, _ns("ReservationsList"))
reservations_list.append(self.to_xml())
return ET.tostring(root, encoding="utf-8", xml_declaration=True).decode("utf-8")