Before simplifying the factory
This commit is contained in:
35
src/main.py
35
src/main.py
@@ -6,8 +6,14 @@ from datetime import datetime, timezone
|
|||||||
import re
|
import re
|
||||||
from xsdata_pydantic.bindings import XmlSerializer
|
from xsdata_pydantic.bindings import XmlSerializer
|
||||||
|
|
||||||
from simplified_access import CustomerData, CustomerFactory, PhoneTechType, ResGuestFactory
|
from simplified_access import (
|
||||||
|
CustomerData,
|
||||||
|
CustomerFactory,
|
||||||
|
HotelReservationIdData,
|
||||||
|
HotelReservationIdFactory,
|
||||||
|
PhoneTechType,
|
||||||
|
ResGuestFactory,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -45,7 +51,7 @@ def main():
|
|||||||
name_prefix="Mr.",
|
name_prefix="Mr.",
|
||||||
phone_numbers=[
|
phone_numbers=[
|
||||||
("+1234567890", PhoneTechType.MOBILE), # Phone number with type
|
("+1234567890", PhoneTechType.MOBILE), # Phone number with type
|
||||||
("+0987654321", None) # Phone number without type
|
("+0987654321", None), # Phone number without type
|
||||||
],
|
],
|
||||||
email_address="john.doe@example.com",
|
email_address="john.doe@example.com",
|
||||||
email_newsletter=True,
|
email_newsletter=True,
|
||||||
@@ -56,23 +62,25 @@ def main():
|
|||||||
address_catalog=False,
|
address_catalog=False,
|
||||||
gender="Male",
|
gender="Male",
|
||||||
birth_date="1980-01-01",
|
birth_date="1980-01-01",
|
||||||
language="en"
|
language="en",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
res_guests = ResGuestFactory.create_retrieve_res_guests(customer_data)
|
res_guests = ResGuestFactory.create_retrieve_res_guests(customer_data)
|
||||||
|
|
||||||
|
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 = HotelReservationIdFactory.create_retrieve_hotel_reservation_id(
|
||||||
|
hotel_res_id_data
|
||||||
|
)
|
||||||
|
|
||||||
# Use the actual nested HotelReservationIds class
|
# Use the actual nested HotelReservationIds class
|
||||||
hotel_res_ids = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.HotelReservationIds(
|
hotel_res_ids = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.HotelReservationIds(
|
||||||
hotel_reservation_id = [
|
hotel_reservation_id=[hotel_res_id]
|
||||||
ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.HotelReservationIds.HotelReservationId(
|
|
||||||
res_id_type="13", res_id_source_context="99tales"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Basic property info
|
# Basic property info
|
||||||
@@ -146,7 +154,6 @@ def main():
|
|||||||
|
|
||||||
parsed_result = parser.from_string(xml_content, ab.OtaResRetrieveRs)
|
parsed_result = parser.from_string(xml_content, ab.OtaResRetrieveRs)
|
||||||
|
|
||||||
|
|
||||||
print("✅ Round-trip validation successful!")
|
print("✅ Round-trip validation successful!")
|
||||||
print(
|
print(
|
||||||
f"Parsed reservation status: {parsed_result.reservations_list.hotel_reservation[0].res_status}"
|
f"Parsed reservation status: {parsed_result.reservations_list.hotel_reservation[0].res_status}"
|
||||||
|
|||||||
@@ -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:06:48.996519+00:00" ResStatus="Requested" RoomStayReservation="true">
|
<HotelReservation CreateDateTime="2025-09-24T13:22:30.892827+00:00" ResStatus="Requested" RoomStayReservation="true">
|
||||||
<UniqueID Type="14" ID="6b34fe24ac2ff811"/>
|
<UniqueID Type="14" ID="6b34fe24ac2ff811"/>
|
||||||
<RoomStays>
|
<RoomStays>
|
||||||
<RoomStay>
|
<RoomStay>
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ from generated.alpinebits import OtaHotelResNotifRq, OtaResRetrieveRs
|
|||||||
NotifCustomer = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer
|
NotifCustomer = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer
|
||||||
RetrieveCustomer = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer
|
RetrieveCustomer = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer
|
||||||
|
|
||||||
|
# Define type aliases for HotelReservationId types
|
||||||
|
NotifHotelReservationId = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGlobalInfo.HotelReservationIds.HotelReservationId
|
||||||
|
RetrieveHotelReservationId = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.HotelReservationIds.HotelReservationId
|
||||||
|
|
||||||
|
|
||||||
# phonetechtype enum 1,3,5 voice, fax, mobile
|
# phonetechtype enum 1,3,5 voice, fax, mobile
|
||||||
class PhoneTechType(Enum):
|
class PhoneTechType(Enum):
|
||||||
@@ -18,23 +22,28 @@ class PhoneTechType(Enum):
|
|||||||
MOBILE = "5"
|
MOBILE = "5"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class CustomerData:
|
class CustomerData:
|
||||||
"""Simple data class to hold customer information without nested type constraints."""
|
"""Simple data class to hold customer information without nested type constraints."""
|
||||||
|
|
||||||
given_name: str
|
given_name: str
|
||||||
surname: str
|
surname: str
|
||||||
name_prefix: None | str = None
|
name_prefix: None | str = None
|
||||||
name_title: None | str = None
|
name_title: None | str = None
|
||||||
phone_numbers: list[tuple[str, None | PhoneTechType]] = None # (phone_number, phone_tech_type)
|
phone_numbers: list[tuple[str, None | PhoneTechType]] = (
|
||||||
|
None # (phone_number, phone_tech_type)
|
||||||
|
)
|
||||||
email_address: None | str = None
|
email_address: None | str = None
|
||||||
email_newsletter: None | bool = None # True for "yes", False for "no", None for not specified
|
email_newsletter: None | bool = (
|
||||||
|
None # True for "yes", False for "no", None for not specified
|
||||||
|
)
|
||||||
address_line: None | str = None
|
address_line: None | str = None
|
||||||
city_name: None | str = None
|
city_name: None | str = None
|
||||||
postal_code: None | str = None
|
postal_code: None | str = None
|
||||||
country_code: None | str = None # Two-letter country code
|
country_code: None | str = None # Two-letter country code
|
||||||
address_catalog: None | bool = None # True for "yes", False for "no", None for not specified
|
address_catalog: None | bool = (
|
||||||
|
None # True for "yes", False for "no", None for not specified
|
||||||
|
)
|
||||||
gender: None | str = None # "Unknown", "Male", "Female"
|
gender: None | str = None # "Unknown", "Male", "Female"
|
||||||
birth_date: None | str = None
|
birth_date: None | str = None
|
||||||
language: None | str = None # Two-letter language code
|
language: None | str = None # Two-letter language code
|
||||||
@@ -46,69 +55,70 @@ class CustomerData:
|
|||||||
|
|
||||||
class CustomerFactory:
|
class CustomerFactory:
|
||||||
"""Factory class to create Customer instances for both OtaHotelResNotifRq and OtaResRetrieveRs."""
|
"""Factory class to create Customer instances for both OtaHotelResNotifRq and OtaResRetrieveRs."""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_notif_customer(data: CustomerData) -> NotifCustomer:
|
def create_notif_customer(data: CustomerData) -> NotifCustomer:
|
||||||
"""Create a Customer for OtaHotelResNotifRq."""
|
"""Create a Customer for OtaHotelResNotifRq."""
|
||||||
return CustomerFactory._create_customer(NotifCustomer, data)
|
return CustomerFactory._create_customer(NotifCustomer, data)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_retrieve_customer(data: CustomerData) -> RetrieveCustomer:
|
def create_retrieve_customer(data: CustomerData) -> RetrieveCustomer:
|
||||||
"""Create a Customer for OtaResRetrieveRs."""
|
"""Create a Customer for OtaResRetrieveRs."""
|
||||||
return CustomerFactory._create_customer(RetrieveCustomer, data)
|
return CustomerFactory._create_customer(RetrieveCustomer, data)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_customer(customer_class: type, data: CustomerData) -> Any:
|
def _create_customer(customer_class: type, data: CustomerData) -> Any:
|
||||||
"""Internal method to create a customer of the specified type."""
|
"""Internal method to create a customer of the specified type."""
|
||||||
|
|
||||||
# Create PersonName
|
# Create PersonName
|
||||||
person_name = customer_class.PersonName(
|
person_name = customer_class.PersonName(
|
||||||
given_name=data.given_name,
|
given_name=data.given_name,
|
||||||
surname=data.surname,
|
surname=data.surname,
|
||||||
name_prefix=data.name_prefix,
|
name_prefix=data.name_prefix,
|
||||||
name_title=data.name_title
|
name_title=data.name_title,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create telephone list
|
# Create telephone list
|
||||||
telephones = []
|
telephones = []
|
||||||
for phone_number, phone_tech_type in data.phone_numbers:
|
for phone_number, phone_tech_type in data.phone_numbers:
|
||||||
telephone = customer_class.Telephone(
|
telephone = customer_class.Telephone(
|
||||||
phone_number=phone_number,
|
phone_number=phone_number,
|
||||||
phone_tech_type=phone_tech_type.value if phone_tech_type else None
|
phone_tech_type=phone_tech_type.value if phone_tech_type else None,
|
||||||
)
|
)
|
||||||
telephones.append(telephone)
|
telephones.append(telephone)
|
||||||
|
|
||||||
# Create email if provided
|
# Create email if provided
|
||||||
email = None
|
email = None
|
||||||
if data.email_address:
|
if data.email_address:
|
||||||
remark = None
|
remark = None
|
||||||
if data.email_newsletter is not None:
|
if data.email_newsletter is not None:
|
||||||
remark = f"newsletter:{'yes' if data.email_newsletter else 'no'}"
|
remark = f"newsletter:{'yes' if data.email_newsletter else 'no'}"
|
||||||
|
|
||||||
email = customer_class.Email(
|
email = customer_class.Email(value=data.email_address, remark=remark)
|
||||||
value=data.email_address,
|
|
||||||
remark=remark
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create address if any address fields are provided
|
# Create address if any address fields are provided
|
||||||
address = None
|
address = None
|
||||||
if any([data.address_line, data.city_name, data.postal_code, data.country_code]):
|
if any(
|
||||||
|
[data.address_line, data.city_name, data.postal_code, data.country_code]
|
||||||
|
):
|
||||||
country_name = None
|
country_name = None
|
||||||
if data.country_code:
|
if data.country_code:
|
||||||
country_name = customer_class.Address.CountryName(code=data.country_code)
|
country_name = customer_class.Address.CountryName(
|
||||||
|
code=data.country_code
|
||||||
|
)
|
||||||
|
|
||||||
address_remark = None
|
address_remark = None
|
||||||
if data.address_catalog is not None:
|
if data.address_catalog is not None:
|
||||||
address_remark = f"catalog:{'yes' if data.address_catalog else 'no'}"
|
address_remark = f"catalog:{'yes' if data.address_catalog else 'no'}"
|
||||||
|
|
||||||
address = customer_class.Address(
|
address = customer_class.Address(
|
||||||
address_line=data.address_line,
|
address_line=data.address_line,
|
||||||
city_name=data.city_name,
|
city_name=data.city_name,
|
||||||
postal_code=data.postal_code,
|
postal_code=data.postal_code,
|
||||||
country_name=country_name,
|
country_name=country_name,
|
||||||
remark=address_remark
|
remark=address_remark,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create the customer
|
# Create the customer
|
||||||
return customer_class(
|
return customer_class(
|
||||||
person_name=person_name,
|
person_name=person_name,
|
||||||
@@ -117,29 +127,36 @@ class CustomerFactory:
|
|||||||
address=address,
|
address=address,
|
||||||
gender=data.gender,
|
gender=data.gender,
|
||||||
birth_date=data.birth_date,
|
birth_date=data.birth_date,
|
||||||
language=data.language
|
language=data.language,
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_notif_customer(customer: NotifCustomer) -> CustomerData:
|
def from_notif_customer(customer: NotifCustomer) -> CustomerData:
|
||||||
"""Convert a NotifCustomer back to CustomerData."""
|
"""Convert a NotifCustomer back to CustomerData."""
|
||||||
return CustomerFactory._customer_to_data(customer)
|
return CustomerFactory._customer_to_data(customer)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_retrieve_customer(customer: RetrieveCustomer) -> CustomerData:
|
def from_retrieve_customer(customer: RetrieveCustomer) -> CustomerData:
|
||||||
"""Convert a RetrieveCustomer back to CustomerData."""
|
"""Convert a RetrieveCustomer back to CustomerData."""
|
||||||
return CustomerFactory._customer_to_data(customer)
|
return CustomerFactory._customer_to_data(customer)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _customer_to_data(customer: Any) -> CustomerData:
|
def _customer_to_data(customer: Any) -> CustomerData:
|
||||||
"""Internal method to convert any customer type to CustomerData."""
|
"""Internal method to convert any customer type to CustomerData."""
|
||||||
|
|
||||||
# Extract phone numbers
|
# Extract phone numbers
|
||||||
phone_numbers = []
|
phone_numbers = []
|
||||||
if customer.telephone:
|
if customer.telephone:
|
||||||
for tel in customer.telephone:
|
for tel in customer.telephone:
|
||||||
phone_numbers.append((tel.phone_number, PhoneTechType(tel.phone_tech_type) if tel.phone_tech_type else None))
|
phone_numbers.append(
|
||||||
|
(
|
||||||
|
tel.phone_number,
|
||||||
|
PhoneTechType(tel.phone_tech_type)
|
||||||
|
if tel.phone_tech_type
|
||||||
|
else None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Extract email info
|
# Extract email info
|
||||||
email_address = None
|
email_address = None
|
||||||
email_newsletter = None
|
email_newsletter = None
|
||||||
@@ -150,28 +167,28 @@ class CustomerFactory:
|
|||||||
email_newsletter = True
|
email_newsletter = True
|
||||||
elif "newsletter:no" in customer.email.remark:
|
elif "newsletter:no" in customer.email.remark:
|
||||||
email_newsletter = False
|
email_newsletter = False
|
||||||
|
|
||||||
# Extract address info
|
# Extract address info
|
||||||
address_line = None
|
address_line = None
|
||||||
city_name = None
|
city_name = None
|
||||||
postal_code = None
|
postal_code = None
|
||||||
country_code = None
|
country_code = None
|
||||||
address_catalog = None
|
address_catalog = None
|
||||||
|
|
||||||
if customer.address:
|
if customer.address:
|
||||||
address_line = customer.address.address_line
|
address_line = customer.address.address_line
|
||||||
city_name = customer.address.city_name
|
city_name = customer.address.city_name
|
||||||
postal_code = customer.address.postal_code
|
postal_code = customer.address.postal_code
|
||||||
|
|
||||||
if customer.address.country_name:
|
if customer.address.country_name:
|
||||||
country_code = customer.address.country_name.code
|
country_code = customer.address.country_name.code
|
||||||
|
|
||||||
if customer.address.remark:
|
if customer.address.remark:
|
||||||
if "catalog:yes" in customer.address.remark:
|
if "catalog:yes" in customer.address.remark:
|
||||||
address_catalog = True
|
address_catalog = True
|
||||||
elif "catalog:no" in customer.address.remark:
|
elif "catalog:no" in customer.address.remark:
|
||||||
address_catalog = False
|
address_catalog = False
|
||||||
|
|
||||||
return CustomerData(
|
return CustomerData(
|
||||||
given_name=customer.person_name.given_name,
|
given_name=customer.person_name.given_name,
|
||||||
surname=customer.person_name.surname,
|
surname=customer.person_name.surname,
|
||||||
@@ -187,7 +204,81 @@ class CustomerFactory:
|
|||||||
address_catalog=address_catalog,
|
address_catalog=address_catalog,
|
||||||
gender=customer.gender,
|
gender=customer.gender,
|
||||||
birth_date=customer.birth_date,
|
birth_date=customer.birth_date,
|
||||||
language=customer.language
|
language=customer.language,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class HotelReservationIdData:
|
||||||
|
"""Simple data class to hold hotel reservation ID information without nested type constraints."""
|
||||||
|
|
||||||
|
res_id_type: str # Required field - pattern: [0-9]+
|
||||||
|
res_id_value: None | str = None # Max 64 characters
|
||||||
|
res_id_source: None | str = None # Max 64 characters
|
||||||
|
res_id_source_context: None | str = None # Max 64 characters
|
||||||
|
|
||||||
|
|
||||||
|
class HotelReservationIdFactory:
|
||||||
|
"""Factory class to create HotelReservationId instances for both OtaHotelResNotifRq and OtaResRetrieveRs."""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_notif_hotel_reservation_id(
|
||||||
|
data: HotelReservationIdData,
|
||||||
|
) -> NotifHotelReservationId:
|
||||||
|
"""Create a HotelReservationId for OtaHotelResNotifRq."""
|
||||||
|
return HotelReservationIdFactory._create_hotel_reservation_id(
|
||||||
|
NotifHotelReservationId, data
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_retrieve_hotel_reservation_id(
|
||||||
|
data: HotelReservationIdData,
|
||||||
|
) -> RetrieveHotelReservationId:
|
||||||
|
"""Create a HotelReservationId for OtaResRetrieveRs."""
|
||||||
|
return HotelReservationIdFactory._create_hotel_reservation_id(
|
||||||
|
RetrieveHotelReservationId, data
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_hotel_reservation_id(
|
||||||
|
hotel_reservation_id_class: type, data: HotelReservationIdData
|
||||||
|
) -> Any:
|
||||||
|
"""Internal method to create a hotel reservation id of the specified type."""
|
||||||
|
return hotel_reservation_id_class(
|
||||||
|
res_id_type=data.res_id_type,
|
||||||
|
res_id_value=data.res_id_value,
|
||||||
|
res_id_source=data.res_id_source,
|
||||||
|
res_id_source_context=data.res_id_source_context,
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_notif_hotel_reservation_id(
|
||||||
|
hotel_reservation_id: NotifHotelReservationId,
|
||||||
|
) -> HotelReservationIdData:
|
||||||
|
"""Convert a NotifHotelReservationId back to HotelReservationIdData."""
|
||||||
|
return HotelReservationIdFactory._hotel_reservation_id_to_data(
|
||||||
|
hotel_reservation_id
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_retrieve_hotel_reservation_id(
|
||||||
|
hotel_reservation_id: RetrieveHotelReservationId,
|
||||||
|
) -> HotelReservationIdData:
|
||||||
|
"""Convert a RetrieveHotelReservationId back to HotelReservationIdData."""
|
||||||
|
return HotelReservationIdFactory._hotel_reservation_id_to_data(
|
||||||
|
hotel_reservation_id
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _hotel_reservation_id_to_data(
|
||||||
|
hotel_reservation_id: Any,
|
||||||
|
) -> HotelReservationIdData:
|
||||||
|
"""Internal method to convert any hotel reservation id type to HotelReservationIdData."""
|
||||||
|
return HotelReservationIdData(
|
||||||
|
res_id_type=hotel_reservation_id.res_id_type,
|
||||||
|
res_id_value=hotel_reservation_id.res_id_value,
|
||||||
|
res_id_source=hotel_reservation_id.res_id_source,
|
||||||
|
res_id_source_context=hotel_reservation_id.res_id_source_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -198,64 +289,56 @@ RetrieveResGuests = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests
|
|||||||
|
|
||||||
class ResGuestFactory:
|
class ResGuestFactory:
|
||||||
"""Factory class to create complete ResGuests structures with a primary customer."""
|
"""Factory class to create complete ResGuests structures with a primary customer."""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_notif_res_guests(customer_data: CustomerData) -> NotifResGuests:
|
def create_notif_res_guests(customer_data: CustomerData) -> NotifResGuests:
|
||||||
"""Create a complete ResGuests structure for OtaHotelResNotifRq with primary customer."""
|
"""Create a complete ResGuests structure for OtaHotelResNotifRq with primary customer."""
|
||||||
return ResGuestFactory._create_res_guests(
|
return ResGuestFactory._create_res_guests(
|
||||||
NotifResGuests,
|
NotifResGuests, NotifCustomer, customer_data
|
||||||
NotifCustomer,
|
|
||||||
customer_data
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_retrieve_res_guests(customer_data: CustomerData) -> RetrieveResGuests:
|
def create_retrieve_res_guests(customer_data: CustomerData) -> RetrieveResGuests:
|
||||||
"""Create a complete ResGuests structure for OtaResRetrieveRs with primary customer."""
|
"""Create a complete ResGuests structure for OtaResRetrieveRs with primary customer."""
|
||||||
return ResGuestFactory._create_res_guests(
|
return ResGuestFactory._create_res_guests(
|
||||||
RetrieveResGuests,
|
RetrieveResGuests, RetrieveCustomer, customer_data
|
||||||
RetrieveCustomer,
|
|
||||||
customer_data
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_res_guests(res_guests_class: type, customer_class: type, customer_data: CustomerData) -> Any:
|
def _create_res_guests(
|
||||||
|
res_guests_class: type, customer_class: type, customer_data: CustomerData
|
||||||
|
) -> Any:
|
||||||
"""Internal method to create complete ResGuests structure."""
|
"""Internal method to create complete ResGuests structure."""
|
||||||
|
|
||||||
# Create the customer using the existing CustomerFactory
|
# Create the customer using the existing CustomerFactory
|
||||||
customer = CustomerFactory._create_customer(customer_class, customer_data)
|
customer = CustomerFactory._create_customer(customer_class, customer_data)
|
||||||
|
|
||||||
# Create Profile with the customer
|
# Create Profile with the customer
|
||||||
profile = res_guests_class.ResGuest.Profiles.ProfileInfo.Profile(
|
profile = res_guests_class.ResGuest.Profiles.ProfileInfo.Profile(
|
||||||
customer=customer
|
customer=customer
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create ProfileInfo with the profile
|
# Create ProfileInfo with the profile
|
||||||
profile_info = res_guests_class.ResGuest.Profiles.ProfileInfo(
|
profile_info = res_guests_class.ResGuest.Profiles.ProfileInfo(profile=profile)
|
||||||
profile=profile
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create Profiles with the profile_info
|
# Create Profiles with the profile_info
|
||||||
profiles = res_guests_class.ResGuest.Profiles(
|
profiles = res_guests_class.ResGuest.Profiles(profile_info=profile_info)
|
||||||
profile_info=profile_info
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create ResGuest with the profiles
|
# Create ResGuest with the profiles
|
||||||
res_guest = res_guests_class.ResGuest(
|
res_guest = res_guests_class.ResGuest(profiles=profiles)
|
||||||
profiles=profiles
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create ResGuests with the res_guest
|
# Create ResGuests with the res_guest
|
||||||
return res_guests_class(
|
return res_guests_class(res_guest=res_guest)
|
||||||
res_guest=res_guest
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def extract_primary_customer(res_guests: Union[NotifResGuests, RetrieveResGuests]) -> CustomerData:
|
def extract_primary_customer(
|
||||||
|
res_guests: Union[NotifResGuests, RetrieveResGuests],
|
||||||
|
) -> CustomerData:
|
||||||
"""Extract the primary customer data from a ResGuests structure."""
|
"""Extract the primary customer data from a ResGuests structure."""
|
||||||
|
|
||||||
# Navigate down the nested structure to get the customer
|
# Navigate down the nested structure to get the customer
|
||||||
customer = res_guests.res_guest.profiles.profile_info.profile.customer
|
customer = res_guests.res_guest.profiles.profile_info.profile.customer
|
||||||
|
|
||||||
# Use the existing CustomerFactory conversion method
|
# Use the existing CustomerFactory conversion method
|
||||||
if isinstance(res_guests, NotifResGuests):
|
if isinstance(res_guests, NotifResGuests):
|
||||||
return CustomerFactory.from_notif_customer(customer)
|
return CustomerFactory.from_notif_customer(customer)
|
||||||
@@ -272,7 +355,7 @@ if __name__ == "__main__":
|
|||||||
name_prefix="Mr.",
|
name_prefix="Mr.",
|
||||||
phone_numbers=[
|
phone_numbers=[
|
||||||
("+1234567890", PhoneTechType.MOBILE), # Phone number with type
|
("+1234567890", PhoneTechType.MOBILE), # Phone number with type
|
||||||
("+0987654321", None) # Phone number without type
|
("+0987654321", None), # Phone number without type
|
||||||
],
|
],
|
||||||
email_address="john.doe@example.com",
|
email_address="john.doe@example.com",
|
||||||
email_newsletter=True,
|
email_newsletter=True,
|
||||||
@@ -283,39 +366,96 @@ if __name__ == "__main__":
|
|||||||
address_catalog=False,
|
address_catalog=False,
|
||||||
gender="Male",
|
gender="Male",
|
||||||
birth_date="1980-01-01",
|
birth_date="1980-01-01",
|
||||||
language="en"
|
language="en",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create customer for OtaHotelResNotifRq
|
# Create customer for OtaHotelResNotifRq
|
||||||
notif_customer = CustomerFactory.create_notif_customer(customer_data)
|
notif_customer = CustomerFactory.create_notif_customer(customer_data)
|
||||||
print("Created NotifCustomer:", notif_customer.person_name.given_name, notif_customer.person_name.surname)
|
print(
|
||||||
|
"Created NotifCustomer:",
|
||||||
|
notif_customer.person_name.given_name,
|
||||||
|
notif_customer.person_name.surname,
|
||||||
|
)
|
||||||
|
|
||||||
# Create customer for OtaResRetrieveRs
|
# Create customer for OtaResRetrieveRs
|
||||||
retrieve_customer = CustomerFactory.create_retrieve_customer(customer_data)
|
retrieve_customer = CustomerFactory.create_retrieve_customer(customer_data)
|
||||||
print("Created RetrieveCustomer:", retrieve_customer.person_name.given_name, retrieve_customer.person_name.surname)
|
print(
|
||||||
|
"Created RetrieveCustomer:",
|
||||||
|
retrieve_customer.person_name.given_name,
|
||||||
|
retrieve_customer.person_name.surname,
|
||||||
|
)
|
||||||
|
|
||||||
# Convert back to data class
|
# Convert back to data class
|
||||||
converted_data = CustomerFactory.from_notif_customer(notif_customer)
|
converted_data = CustomerFactory.from_notif_customer(notif_customer)
|
||||||
print("Converted back to data:", converted_data.given_name, converted_data.surname)
|
print("Converted back to data:", converted_data.given_name, converted_data.surname)
|
||||||
|
|
||||||
# Verify they contain the same information
|
# Verify they contain the same information
|
||||||
print("Original and converted data match:", customer_data == converted_data)
|
print("Original and converted data match:", customer_data == converted_data)
|
||||||
|
|
||||||
|
print("\n--- HotelReservationIdFactory Examples ---")
|
||||||
|
|
||||||
|
# Create hotel reservation ID data
|
||||||
|
reservation_id_data = HotelReservationIdData(
|
||||||
|
res_id_type="123",
|
||||||
|
res_id_value="RESERVATION-456",
|
||||||
|
res_id_source="HOTEL_SYSTEM",
|
||||||
|
res_id_source_context="BOOKING_ENGINE",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create HotelReservationId for both types
|
||||||
|
notif_res_id = HotelReservationIdFactory.create_notif_hotel_reservation_id(
|
||||||
|
reservation_id_data
|
||||||
|
)
|
||||||
|
retrieve_res_id = HotelReservationIdFactory.create_retrieve_hotel_reservation_id(
|
||||||
|
reservation_id_data
|
||||||
|
)
|
||||||
|
|
||||||
|
print(
|
||||||
|
"Created NotifHotelReservationId:",
|
||||||
|
notif_res_id.res_id_type,
|
||||||
|
notif_res_id.res_id_value,
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
"Created RetrieveHotelReservationId:",
|
||||||
|
retrieve_res_id.res_id_type,
|
||||||
|
retrieve_res_id.res_id_value,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert back to data class
|
||||||
|
converted_res_id_data = HotelReservationIdFactory.from_notif_hotel_reservation_id(
|
||||||
|
notif_res_id
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
"Converted back to reservation ID data:",
|
||||||
|
converted_res_id_data.res_id_type,
|
||||||
|
converted_res_id_data.res_id_value,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify they contain the same information
|
||||||
|
print(
|
||||||
|
"Original and converted reservation ID data match:",
|
||||||
|
reservation_id_data == converted_res_id_data,
|
||||||
|
)
|
||||||
|
|
||||||
print("\n--- ResGuestFactory Examples ---")
|
print("\n--- ResGuestFactory Examples ---")
|
||||||
|
|
||||||
# Create complete ResGuests structure for OtaHotelResNotifRq - much simpler!
|
# Create complete ResGuests structure for OtaHotelResNotifRq - much simpler!
|
||||||
notif_res_guests = ResGuestFactory.create_notif_res_guests(customer_data)
|
notif_res_guests = ResGuestFactory.create_notif_res_guests(customer_data)
|
||||||
print("Created NotifResGuests with customer:",
|
print(
|
||||||
notif_res_guests.res_guest.profiles.profile_info.profile.customer.person_name.given_name)
|
"Created NotifResGuests with customer:",
|
||||||
|
notif_res_guests.res_guest.profiles.profile_info.profile.customer.person_name.given_name,
|
||||||
|
)
|
||||||
|
|
||||||
# Create complete ResGuests structure for OtaResRetrieveRs - much simpler!
|
# Create complete ResGuests structure for OtaResRetrieveRs - much simpler!
|
||||||
retrieve_res_guests = ResGuestFactory.create_retrieve_res_guests(customer_data)
|
retrieve_res_guests = ResGuestFactory.create_retrieve_res_guests(customer_data)
|
||||||
print("Created RetrieveResGuests with customer:",
|
print(
|
||||||
retrieve_res_guests.res_guest.profiles.profile_info.profile.customer.person_name.given_name)
|
"Created RetrieveResGuests with customer:",
|
||||||
|
retrieve_res_guests.res_guest.profiles.profile_info.profile.customer.person_name.given_name,
|
||||||
|
)
|
||||||
|
|
||||||
# Extract primary customer data back from ResGuests structure
|
# Extract primary customer data back from ResGuests structure
|
||||||
extracted_data = ResGuestFactory.extract_primary_customer(retrieve_res_guests)
|
extracted_data = ResGuestFactory.extract_primary_customer(retrieve_res_guests)
|
||||||
print("Extracted customer data:", extracted_data.given_name, extracted_data.surname)
|
print("Extracted customer data:", extracted_data.given_name, extracted_data.surname)
|
||||||
|
|
||||||
# Verify roundtrip conversion
|
# Verify roundtrip conversion
|
||||||
print("Roundtrip conversion successful:", customer_data == extracted_data)
|
print("Roundtrip conversion successful:", customer_data == extracted_data)
|
||||||
|
|||||||
@@ -10,11 +10,15 @@ from simplified_access import (
|
|||||||
CustomerData,
|
CustomerData,
|
||||||
CustomerFactory,
|
CustomerFactory,
|
||||||
ResGuestFactory,
|
ResGuestFactory,
|
||||||
|
HotelReservationIdData,
|
||||||
|
HotelReservationIdFactory,
|
||||||
PhoneTechType,
|
PhoneTechType,
|
||||||
NotifCustomer,
|
NotifCustomer,
|
||||||
RetrieveCustomer,
|
RetrieveCustomer,
|
||||||
NotifResGuests,
|
NotifResGuests,
|
||||||
RetrieveResGuests
|
RetrieveResGuests,
|
||||||
|
NotifHotelReservationId,
|
||||||
|
RetrieveHotelReservationId
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -53,6 +57,25 @@ def minimal_customer_data():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def sample_hotel_reservation_id_data():
|
||||||
|
"""Fixture providing sample hotel reservation ID data for testing."""
|
||||||
|
return HotelReservationIdData(
|
||||||
|
res_id_type="123",
|
||||||
|
res_id_value="RESERVATION-456",
|
||||||
|
res_id_source="HOTEL_SYSTEM",
|
||||||
|
res_id_source_context="BOOKING_ENGINE"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def minimal_hotel_reservation_id_data():
|
||||||
|
"""Fixture providing minimal hotel reservation ID data (only required fields)."""
|
||||||
|
return HotelReservationIdData(
|
||||||
|
res_id_type="999"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestCustomerData:
|
class TestCustomerData:
|
||||||
"""Test the CustomerData dataclass."""
|
"""Test the CustomerData dataclass."""
|
||||||
|
|
||||||
@@ -213,6 +236,73 @@ class TestCustomerFactory:
|
|||||||
assert customer.telephone[2].phone_tech_type == "5" # MOBILE
|
assert customer.telephone[2].phone_tech_type == "5" # MOBILE
|
||||||
|
|
||||||
|
|
||||||
|
class TestHotelReservationIdData:
|
||||||
|
"""Test the HotelReservationIdData dataclass."""
|
||||||
|
|
||||||
|
def test_hotel_reservation_id_data_creation_full(self, sample_hotel_reservation_id_data):
|
||||||
|
"""Test creating HotelReservationIdData with all fields."""
|
||||||
|
assert sample_hotel_reservation_id_data.res_id_type == "123"
|
||||||
|
assert sample_hotel_reservation_id_data.res_id_value == "RESERVATION-456"
|
||||||
|
assert sample_hotel_reservation_id_data.res_id_source == "HOTEL_SYSTEM"
|
||||||
|
assert sample_hotel_reservation_id_data.res_id_source_context == "BOOKING_ENGINE"
|
||||||
|
|
||||||
|
def test_hotel_reservation_id_data_creation_minimal(self, minimal_hotel_reservation_id_data):
|
||||||
|
"""Test creating HotelReservationIdData with only required fields."""
|
||||||
|
assert minimal_hotel_reservation_id_data.res_id_type == "999"
|
||||||
|
assert minimal_hotel_reservation_id_data.res_id_value is None
|
||||||
|
assert minimal_hotel_reservation_id_data.res_id_source is None
|
||||||
|
assert minimal_hotel_reservation_id_data.res_id_source_context is None
|
||||||
|
|
||||||
|
|
||||||
|
class TestHotelReservationIdFactory:
|
||||||
|
"""Test the HotelReservationIdFactory class."""
|
||||||
|
|
||||||
|
def test_create_notif_hotel_reservation_id_full(self, sample_hotel_reservation_id_data):
|
||||||
|
"""Test creating a NotifHotelReservationId with full data."""
|
||||||
|
reservation_id = HotelReservationIdFactory.create_notif_hotel_reservation_id(sample_hotel_reservation_id_data)
|
||||||
|
|
||||||
|
assert isinstance(reservation_id, NotifHotelReservationId)
|
||||||
|
assert reservation_id.res_id_type == "123"
|
||||||
|
assert reservation_id.res_id_value == "RESERVATION-456"
|
||||||
|
assert reservation_id.res_id_source == "HOTEL_SYSTEM"
|
||||||
|
assert reservation_id.res_id_source_context == "BOOKING_ENGINE"
|
||||||
|
|
||||||
|
def test_create_retrieve_hotel_reservation_id_full(self, sample_hotel_reservation_id_data):
|
||||||
|
"""Test creating a RetrieveHotelReservationId with full data."""
|
||||||
|
reservation_id = HotelReservationIdFactory.create_retrieve_hotel_reservation_id(sample_hotel_reservation_id_data)
|
||||||
|
|
||||||
|
assert isinstance(reservation_id, RetrieveHotelReservationId)
|
||||||
|
assert reservation_id.res_id_type == "123"
|
||||||
|
assert reservation_id.res_id_value == "RESERVATION-456"
|
||||||
|
assert reservation_id.res_id_source == "HOTEL_SYSTEM"
|
||||||
|
assert reservation_id.res_id_source_context == "BOOKING_ENGINE"
|
||||||
|
|
||||||
|
def test_create_hotel_reservation_id_minimal(self, minimal_hotel_reservation_id_data):
|
||||||
|
"""Test creating hotel reservation IDs with minimal data."""
|
||||||
|
notif_reservation_id = HotelReservationIdFactory.create_notif_hotel_reservation_id(minimal_hotel_reservation_id_data)
|
||||||
|
retrieve_reservation_id = HotelReservationIdFactory.create_retrieve_hotel_reservation_id(minimal_hotel_reservation_id_data)
|
||||||
|
|
||||||
|
for reservation_id in [notif_reservation_id, retrieve_reservation_id]:
|
||||||
|
assert reservation_id.res_id_type == "999"
|
||||||
|
assert reservation_id.res_id_value is None
|
||||||
|
assert reservation_id.res_id_source is None
|
||||||
|
assert reservation_id.res_id_source_context is None
|
||||||
|
|
||||||
|
def test_from_notif_hotel_reservation_id_roundtrip(self, sample_hotel_reservation_id_data):
|
||||||
|
"""Test converting NotifHotelReservationId back to HotelReservationIdData."""
|
||||||
|
reservation_id = HotelReservationIdFactory.create_notif_hotel_reservation_id(sample_hotel_reservation_id_data)
|
||||||
|
converted_data = HotelReservationIdFactory.from_notif_hotel_reservation_id(reservation_id)
|
||||||
|
|
||||||
|
assert converted_data == sample_hotel_reservation_id_data
|
||||||
|
|
||||||
|
def test_from_retrieve_hotel_reservation_id_roundtrip(self, sample_hotel_reservation_id_data):
|
||||||
|
"""Test converting RetrieveHotelReservationId back to HotelReservationIdData."""
|
||||||
|
reservation_id = HotelReservationIdFactory.create_retrieve_hotel_reservation_id(sample_hotel_reservation_id_data)
|
||||||
|
converted_data = HotelReservationIdFactory.from_retrieve_hotel_reservation_id(reservation_id)
|
||||||
|
|
||||||
|
assert converted_data == sample_hotel_reservation_id_data
|
||||||
|
|
||||||
|
|
||||||
class TestResGuestFactory:
|
class TestResGuestFactory:
|
||||||
"""Test the ResGuestFactory class."""
|
"""Test the ResGuestFactory class."""
|
||||||
|
|
||||||
@@ -313,6 +403,17 @@ class TestIntegration:
|
|||||||
assert retrieve_customer.person_name.given_name == retrieve_from_res_guests.person_name.given_name
|
assert retrieve_customer.person_name.given_name == retrieve_from_res_guests.person_name.given_name
|
||||||
assert retrieve_customer.person_name.surname == retrieve_from_res_guests.person_name.surname
|
assert retrieve_customer.person_name.surname == retrieve_from_res_guests.person_name.surname
|
||||||
|
|
||||||
|
def test_hotel_reservation_id_factories_produce_same_data(self, sample_hotel_reservation_id_data):
|
||||||
|
"""Test that both HotelReservationId factories produce equivalent results."""
|
||||||
|
notif_reservation_id = HotelReservationIdFactory.create_notif_hotel_reservation_id(sample_hotel_reservation_id_data)
|
||||||
|
retrieve_reservation_id = HotelReservationIdFactory.create_retrieve_hotel_reservation_id(sample_hotel_reservation_id_data)
|
||||||
|
|
||||||
|
# Both should have the same field values
|
||||||
|
assert notif_reservation_id.res_id_type == retrieve_reservation_id.res_id_type
|
||||||
|
assert notif_reservation_id.res_id_value == retrieve_reservation_id.res_id_value
|
||||||
|
assert notif_reservation_id.res_id_source == retrieve_reservation_id.res_id_source
|
||||||
|
assert notif_reservation_id.res_id_source_context == retrieve_reservation_id.res_id_source_context
|
||||||
|
|
||||||
def test_complex_customer_workflow(self):
|
def test_complex_customer_workflow(self):
|
||||||
"""Test a complex workflow with multiple operations."""
|
"""Test a complex workflow with multiple operations."""
|
||||||
# Create original data
|
# Create original data
|
||||||
@@ -342,6 +443,29 @@ class TestIntegration:
|
|||||||
notif_extracted = ResGuestFactory.extract_primary_customer(notif_res_guests)
|
notif_extracted = ResGuestFactory.extract_primary_customer(notif_res_guests)
|
||||||
retrieve_extracted = ResGuestFactory.extract_primary_customer(retrieve_res_guests)
|
retrieve_extracted = ResGuestFactory.extract_primary_customer(retrieve_res_guests)
|
||||||
|
|
||||||
|
# All should be equal
|
||||||
|
assert original_data == notif_extracted
|
||||||
|
assert original_data == retrieve_extracted
|
||||||
|
assert notif_extracted == retrieve_extracted
|
||||||
|
|
||||||
|
def test_complex_hotel_reservation_id_workflow(self):
|
||||||
|
"""Test a complex workflow with HotelReservationId operations."""
|
||||||
|
# Create original reservation ID data
|
||||||
|
original_data = HotelReservationIdData(
|
||||||
|
res_id_type="456",
|
||||||
|
res_id_value="COMPLEX-RESERVATION-789",
|
||||||
|
res_id_source="INTEGRATION_SYSTEM",
|
||||||
|
res_id_source_context="API_CALL"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create HotelReservationId for both types
|
||||||
|
notif_reservation_id = HotelReservationIdFactory.create_notif_hotel_reservation_id(original_data)
|
||||||
|
retrieve_reservation_id = HotelReservationIdFactory.create_retrieve_hotel_reservation_id(original_data)
|
||||||
|
|
||||||
|
# Extract data back from both
|
||||||
|
notif_extracted = HotelReservationIdFactory.from_notif_hotel_reservation_id(notif_reservation_id)
|
||||||
|
retrieve_extracted = HotelReservationIdFactory.from_retrieve_hotel_reservation_id(retrieve_reservation_id)
|
||||||
|
|
||||||
# All should be equal
|
# All should be equal
|
||||||
assert original_data == notif_extracted
|
assert original_data == notif_extracted
|
||||||
assert original_data == retrieve_extracted
|
assert original_data == retrieve_extracted
|
||||||
|
|||||||
Reference in New Issue
Block a user