196 lines
5.9 KiB
Python
196 lines
5.9 KiB
Python
from alpinebits_guestrequests import ResGuest, RoomStay
|
|
import generated.alpinebits as ab
|
|
from io import BytesIO
|
|
import sys
|
|
from datetime import datetime, timezone
|
|
import re
|
|
from xsdata_pydantic.bindings import XmlSerializer
|
|
|
|
from simplified_access import (
|
|
CommentData,
|
|
CommentsData,
|
|
CommentListItemData,
|
|
CustomerData,
|
|
|
|
HotelReservationIdData,
|
|
PhoneTechType,
|
|
AlpineBitsFactory,
|
|
OtaMessageType
|
|
)
|
|
|
|
|
|
def main():
|
|
# Success - use None instead of object() for cleaner XML output
|
|
success = None
|
|
|
|
# UniqueID
|
|
unique_id = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.UniqueId(
|
|
type_value=ab.UniqueIdType2.VALUE_14, id="6b34fe24ac2ff811"
|
|
)
|
|
|
|
# TimeSpan - use the actual nested class
|
|
|
|
start_date_window = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay.TimeSpan.StartDateWindow(
|
|
earliest_date="2024-10-01", latest_date="2024-10-02"
|
|
)
|
|
|
|
time_span = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay.TimeSpan(
|
|
start_date_window=start_date_window
|
|
)
|
|
|
|
# RoomStay with TimeSpan
|
|
room_stay = (
|
|
ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay(
|
|
time_span=time_span
|
|
)
|
|
)
|
|
room_stays = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays(
|
|
room_stay=[room_stay]
|
|
)
|
|
|
|
customer_data = CustomerData(
|
|
given_name="John",
|
|
surname="Doe",
|
|
name_prefix="Mr.",
|
|
phone_numbers=[
|
|
("+1234567890", PhoneTechType.MOBILE), # Phone number with type
|
|
("+0987654321", None), # Phone number without type
|
|
],
|
|
email_address="john.doe@example.com",
|
|
email_newsletter=True,
|
|
address_line="123 Main Street",
|
|
city_name="Anytown",
|
|
postal_code="12345",
|
|
country_code="US",
|
|
address_catalog=False,
|
|
gender="Male",
|
|
birth_date="1980-01-01",
|
|
language="en",
|
|
)
|
|
|
|
alpine_bits_factory = AlpineBitsFactory()
|
|
|
|
res_guests = alpine_bits_factory.create_res_guests(customer_data, OtaMessageType.RETRIEVE)
|
|
|
|
hotel_res_id_data = HotelReservationIdData(
|
|
res_id_type="13",
|
|
res_id_value=None,
|
|
res_id_source=None,
|
|
res_id_source_context="99tales",
|
|
)
|
|
# Create HotelReservationId using the factory
|
|
hotel_res_id = alpine_bits_factory.create(hotel_res_id_data, OtaMessageType.RETRIEVE)
|
|
|
|
# Use the actual nested HotelReservationIds class
|
|
hotel_res_ids = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.HotelReservationIds(
|
|
hotel_reservation_id=[hotel_res_id]
|
|
)
|
|
|
|
# Basic property info
|
|
basic_property_info = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.BasicPropertyInfo(
|
|
hotel_code="123", hotel_name="Frangart Inn"
|
|
)
|
|
|
|
comment = CommentData(
|
|
name= ab.CommentName2.CUSTOMER_COMMENT,
|
|
text="This is a sample comment.",
|
|
list_items=[CommentListItemData(
|
|
value="Landing page comment",
|
|
language="en",
|
|
list_item="1",
|
|
)],
|
|
|
|
|
|
)
|
|
|
|
comment2 = CommentData(
|
|
name= ab.CommentName2.ADDITIONAL_INFO,
|
|
text="This is a special request comment.",
|
|
|
|
)
|
|
|
|
comments_data = CommentsData(comments=[comment, comment2])
|
|
|
|
|
|
comments = alpine_bits_factory.create(comments_data, OtaMessageType.RETRIEVE)
|
|
|
|
|
|
|
|
# ResGlobalInfo
|
|
res_global_info = (
|
|
ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo(
|
|
hotel_reservation_ids=hotel_res_ids, basic_property_info=basic_property_info, comments=comments
|
|
)
|
|
)
|
|
|
|
# Hotel Reservation
|
|
hotel_reservation = ab.OtaResRetrieveRs.ReservationsList.HotelReservation(
|
|
create_date_time=datetime.now(timezone.utc).isoformat(),
|
|
res_status=ab.HotelReservationResStatus.REQUESTED,
|
|
room_stay_reservation="true",
|
|
unique_id=unique_id,
|
|
room_stays=room_stays,
|
|
res_guests=res_guests,
|
|
res_global_info=res_global_info,
|
|
)
|
|
|
|
reservations_list = ab.OtaResRetrieveRs.ReservationsList(
|
|
hotel_reservation=[hotel_reservation]
|
|
)
|
|
|
|
# Root element
|
|
ota_res_retrieve_rs = ab.OtaResRetrieveRs(
|
|
version="7.000", success=success, reservations_list=reservations_list
|
|
)
|
|
|
|
# Serialize using Pydantic's model_dump and convert to XML
|
|
try:
|
|
# First validate the model
|
|
ota_res_retrieve_rs.model_validate(ota_res_retrieve_rs.model_dump())
|
|
print("✅ Pydantic validation successful!")
|
|
|
|
# For XML serialization with Pydantic models, we need to use xsdata-pydantic serializer
|
|
from xsdata.formats.dataclass.serializers.config import SerializerConfig
|
|
|
|
config = SerializerConfig(
|
|
pretty_print=True, xml_declaration=True, encoding="UTF-8"
|
|
)
|
|
|
|
serializer = XmlSerializer(config=config)
|
|
|
|
# Use ns_map to control namespace prefixes - set default namespace
|
|
ns_map = {None: "http://www.opentravel.org/OTA/2003/05"}
|
|
xml_string = serializer.render(ota_res_retrieve_rs, ns_map=ns_map)
|
|
|
|
with open("output.xml", "w", encoding="utf-8") as outfile:
|
|
outfile.write(xml_string)
|
|
|
|
print("✅ XML serialization successful!")
|
|
print(f"Generated XML written to output.xml")
|
|
|
|
# Also print the pretty formatted XML to console
|
|
print("\n📄 Generated XML:")
|
|
print(xml_string)
|
|
|
|
# Test parsing back
|
|
from xsdata_pydantic.bindings import XmlParser
|
|
|
|
parser = XmlParser()
|
|
|
|
with open("output.xml", "r", encoding="utf-8") as infile:
|
|
xml_content = infile.read()
|
|
|
|
parsed_result = parser.from_string(xml_content, ab.OtaResRetrieveRs)
|
|
|
|
print("✅ Round-trip validation successful!")
|
|
print(
|
|
f"Parsed reservation status: {parsed_result.reservations_list.hotel_reservation[0].res_status}"
|
|
)
|
|
|
|
except Exception as e:
|
|
print(f"❌ Validation/Serialization failed: {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|