Need to update timesspan

This commit is contained in:
Jonas Linter
2025-09-24 17:14:13 +02:00
parent 5e4703a6b5
commit d41084cd1b
3 changed files with 199 additions and 6 deletions

View File

@@ -7,7 +7,11 @@ import re
from xsdata_pydantic.bindings import XmlSerializer from xsdata_pydantic.bindings import XmlSerializer
from simplified_access import ( from simplified_access import (
CommentData,
CommentsData,
CommentListItemData,
CustomerData, CustomerData,
HotelReservationIdData, HotelReservationIdData,
PhoneTechType, PhoneTechType,
AlpineBitsFactory, AlpineBitsFactory,
@@ -87,10 +91,35 @@ def main():
hotel_code="123", hotel_name="Frangart Inn" 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 # ResGlobalInfo
res_global_info = ( res_global_info = (
ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo( ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo(
hotel_reservation_ids=hotel_res_ids, basic_property_info=basic_property_info hotel_reservation_ids=hotel_res_ids, basic_property_info=basic_property_info, comments=comments
) )
) )

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<OTA_ResRetrieveRS xmlns="http://www.opentravel.org/OTA/2003/05" Version="7.000"> <OTA_ResRetrieveRS xmlns="http://www.opentravel.org/OTA/2003/05" Version="7.000">
<ReservationsList> <ReservationsList>
<HotelReservation CreateDateTime="2025-09-24T13:36:42.168402+00:00" ResStatus="Requested" RoomStayReservation="true"> <HotelReservation CreateDateTime="2025-09-24T15:07:57.451427+00:00" ResStatus="Requested" RoomStayReservation="true">
<UniqueID Type="14" ID="6b34fe24ac2ff811"/> <UniqueID Type="14" ID="6b34fe24ac2ff811"/>
<RoomStays> <RoomStays>
<RoomStay> <RoomStay>
@@ -37,6 +37,15 @@
</ResGuest> </ResGuest>
</ResGuests> </ResGuests>
<ResGlobalInfo> <ResGlobalInfo>
<Comments>
<Comment Name="customer comment">
<ListItem ListItem="1" Language="en">Landing page comment</ListItem>
<Text>This is a sample comment.</Text>
</Comment>
<Comment Name="additional info">
<Text>This is a special request comment.</Text>
</Comment>
</Comments>
<HotelReservationIDs> <HotelReservationIDs>
<HotelReservationID ResID_Type="13" ResID_SourceContext="99tales"/> <HotelReservationID ResID_Type="13" ResID_SourceContext="99tales"/>
</HotelReservationIDs> </HotelReservationIDs>

View File

@@ -4,7 +4,7 @@ from dataclasses import dataclass
from enum import Enum from enum import Enum
# Import the generated classes # Import the generated classes
from generated.alpinebits import OtaHotelResNotifRq, OtaResRetrieveRs from generated.alpinebits import OtaHotelResNotifRq, OtaResRetrieveRs, CommentName2
# Define type aliases for the two Customer types # Define type aliases for the two Customer types
NotifCustomer = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer NotifCustomer = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer
@@ -14,6 +14,12 @@ RetrieveCustomer = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.
NotifHotelReservationId = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGlobalInfo.HotelReservationIds.HotelReservationId NotifHotelReservationId = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGlobalInfo.HotelReservationIds.HotelReservationId
RetrieveHotelReservationId = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.HotelReservationIds.HotelReservationId RetrieveHotelReservationId = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.HotelReservationIds.HotelReservationId
# Define type aliases for Comments types
NotifComments = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGlobalInfo.Comments
RetrieveComments = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.Comments
NotifComment = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGlobalInfo.Comments.Comment
RetrieveComment = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.Comments.Comment
# phonetechtype enum 1,3,5 voice, fax, mobile # phonetechtype enum 1,3,5 voice, fax, mobile
class PhoneTechType(Enum): class PhoneTechType(Enum):
@@ -288,6 +294,113 @@ class HotelReservationIdFactory:
) )
@dataclass
class CommentListItemData:
"""Simple data class to hold comment list item information."""
value: str # The text content of the list item
list_item: str # Numeric identifier (pattern: [0-9]+)
language: str # Two-letter language code (pattern: [a-z][a-z])
@dataclass
class CommentData:
"""Simple data class to hold comment information without nested type constraints."""
name: CommentName2 # Required: "included services", "customer comment", "additional info"
text: Optional[str] = None # Optional text content
list_items: list[CommentListItemData] = None # Optional list items
def __post_init__(self):
if self.list_items is None:
self.list_items = []
@dataclass
class CommentsData:
"""Simple data class to hold multiple comments (1-3 max)."""
comments: list[CommentData] = None # 1-3 comments maximum
def __post_init__(self):
if self.comments is None:
self.comments = []
class CommentFactory:
"""Factory class to create Comment instances for both OtaHotelResNotifRq and OtaResRetrieveRs."""
@staticmethod
def create_notif_comments(data: CommentsData) -> NotifComments:
"""Create Comments for OtaHotelResNotifRq."""
return CommentFactory._create_comments(NotifComments, NotifComment, data)
@staticmethod
def create_retrieve_comments(data: CommentsData) -> RetrieveComments:
"""Create Comments for OtaResRetrieveRs."""
return CommentFactory._create_comments(RetrieveComments, RetrieveComment, data)
@staticmethod
def _create_comments(comments_class: type, comment_class: type, data: CommentsData) -> Any:
"""Internal method to create comments of the specified type."""
comments_list = []
for comment_data in data.comments:
# Create list items
list_items = []
for item_data in comment_data.list_items:
list_item = comment_class.ListItem(
value=item_data.value,
list_item=item_data.list_item,
language=item_data.language
)
list_items.append(list_item)
# Create comment
comment = comment_class(
name=comment_data.name,
text=comment_data.text,
list_item=list_items
)
comments_list.append(comment)
# Create comments container
return comments_class(comment=comments_list)
@staticmethod
def from_notif_comments(comments: NotifComments) -> CommentsData:
"""Convert NotifComments back to CommentsData."""
return CommentFactory._comments_to_data(comments)
@staticmethod
def from_retrieve_comments(comments: RetrieveComments) -> CommentsData:
"""Convert RetrieveComments back to CommentsData."""
return CommentFactory._comments_to_data(comments)
@staticmethod
def _comments_to_data(comments: Any) -> CommentsData:
"""Internal method to convert any comments type to CommentsData."""
comments_data_list = []
for comment in comments.comment:
# Extract list items
list_items_data = []
if comment.list_item:
for list_item in comment.list_item:
list_items_data.append(CommentListItemData(
value=list_item.value,
list_item=list_item.list_item,
language=list_item.language
))
# Extract comment data
comment_data = CommentData(
name=comment.name,
text=comment.text,
list_items=list_items_data
)
comments_data_list.append(comment_data)
return CommentsData(comments=comments_data_list)
# Define type aliases for ResGuests types # Define type aliases for ResGuests types
NotifResGuests = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGuests NotifResGuests = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGuests
RetrieveResGuests = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests RetrieveResGuests = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests
@@ -356,12 +469,12 @@ class AlpineBitsFactory:
"""Unified factory class for creating AlpineBits objects with a simple interface.""" """Unified factory class for creating AlpineBits objects with a simple interface."""
@staticmethod @staticmethod
def create(data: Union[CustomerData, HotelReservationIdData], message_type: OtaMessageType) -> Any: def create(data: Union[CustomerData, HotelReservationIdData, CommentsData], message_type: OtaMessageType) -> Any:
""" """
Create an AlpineBits object based on the data type and message type. Create an AlpineBits object based on the data type and message type.
Args: Args:
data: The data object (CustomerData, HotelReservationIdData, etc.) data: The data object (CustomerData, HotelReservationIdData, CommentsData, etc.)
message_type: Whether to create for NOTIF or RETRIEVE message types message_type: Whether to create for NOTIF or RETRIEVE message types
Returns: Returns:
@@ -379,6 +492,12 @@ class AlpineBitsFactory:
else: else:
return HotelReservationIdFactory.create_retrieve_hotel_reservation_id(data) return HotelReservationIdFactory.create_retrieve_hotel_reservation_id(data)
elif isinstance(data, CommentsData):
if message_type == OtaMessageType.NOTIF:
return CommentFactory.create_notif_comments(data)
else:
return CommentFactory.create_retrieve_comments(data)
else: else:
raise ValueError(f"Unsupported data type: {type(data)}") raise ValueError(f"Unsupported data type: {type(data)}")
@@ -400,7 +519,7 @@ class AlpineBitsFactory:
return ResGuestFactory.create_retrieve_res_guests(customer_data) return ResGuestFactory.create_retrieve_res_guests(customer_data)
@staticmethod @staticmethod
def extract_data(obj: Any) -> Union[CustomerData, HotelReservationIdData]: def extract_data(obj: Any) -> Union[CustomerData, HotelReservationIdData, CommentsData]:
""" """
Extract data from an AlpineBits object back to a simple data class. Extract data from an AlpineBits object back to a simple data class.
@@ -424,6 +543,13 @@ class AlpineBitsFactory:
elif isinstance(obj, RetrieveHotelReservationId): elif isinstance(obj, RetrieveHotelReservationId):
return HotelReservationIdFactory.from_retrieve_hotel_reservation_id(obj) return HotelReservationIdFactory.from_retrieve_hotel_reservation_id(obj)
# Check if it's a Comments object
elif hasattr(obj, 'comment'):
if isinstance(obj, NotifComments):
return CommentFactory.from_notif_comments(obj)
elif isinstance(obj, RetrieveComments):
return CommentFactory.from_retrieve_comments(obj)
# Check if it's a ResGuests object # Check if it's a ResGuests object
elif hasattr(obj, 'res_guest'): elif hasattr(obj, 'res_guest'):
return ResGuestFactory.extract_primary_customer(obj) return ResGuestFactory.extract_primary_customer(obj)
@@ -564,6 +690,33 @@ if __name__ == "__main__":
retrieve_res_id = AlpineBitsFactory.create(reservation_id_data, OtaMessageType.RETRIEVE) retrieve_res_id = AlpineBitsFactory.create(reservation_id_data, OtaMessageType.RETRIEVE)
print("Created reservation IDs using unified factory") print("Created reservation IDs using unified factory")
print("=== Comments Creation ===")
comments_data = CommentsData(comments=[
CommentData(
name=CommentName2.CUSTOMER_COMMENT,
text="This is a customer comment about the reservation",
list_items=[
CommentListItemData(
value="Special dietary requirements: vegetarian",
list_item="1",
language="en"
),
CommentListItemData(
value="Late arrival expected",
list_item="2",
language="en"
)
]
),
CommentData(
name=CommentName2.ADDITIONAL_INFO,
text="Additional information about the stay"
)
])
notif_comments = AlpineBitsFactory.create(comments_data, OtaMessageType.NOTIF)
retrieve_comments = AlpineBitsFactory.create(comments_data, OtaMessageType.RETRIEVE)
print("Created comments using unified factory")
print("=== ResGuests Creation ===") print("=== ResGuests Creation ===")
notif_res_guests = AlpineBitsFactory.create_res_guests(customer_data, OtaMessageType.NOTIF) notif_res_guests = AlpineBitsFactory.create_res_guests(customer_data, OtaMessageType.NOTIF)
retrieve_res_guests = AlpineBitsFactory.create_res_guests(customer_data, OtaMessageType.RETRIEVE) retrieve_res_guests = AlpineBitsFactory.create_res_guests(customer_data, OtaMessageType.RETRIEVE)
@@ -573,11 +726,13 @@ if __name__ == "__main__":
# Extract data back using unified interface # Extract data back using unified interface
extracted_customer_data = AlpineBitsFactory.extract_data(notif_customer) extracted_customer_data = AlpineBitsFactory.extract_data(notif_customer)
extracted_res_id_data = AlpineBitsFactory.extract_data(notif_res_id) extracted_res_id_data = AlpineBitsFactory.extract_data(notif_res_id)
extracted_comments_data = AlpineBitsFactory.extract_data(retrieve_comments)
extracted_from_res_guests = AlpineBitsFactory.extract_data(retrieve_res_guests) extracted_from_res_guests = AlpineBitsFactory.extract_data(retrieve_res_guests)
print("Data extraction successful:") print("Data extraction successful:")
print("- Customer roundtrip:", customer_data == extracted_customer_data) print("- Customer roundtrip:", customer_data == extracted_customer_data)
print("- ReservationId roundtrip:", reservation_id_data == extracted_res_id_data) print("- ReservationId roundtrip:", reservation_id_data == extracted_res_id_data)
print("- Comments roundtrip:", comments_data == extracted_comments_data)
print("- ResGuests roundtrip:", customer_data == extracted_from_res_guests) print("- ResGuests roundtrip:", customer_data == extracted_from_res_guests)
print("\n--- Comparison with old approach ---") print("\n--- Comparison with old approach ---")