diff --git a/src/alpine_bits_python/alpine_bits_helpers.py b/src/alpine_bits_python/alpine_bits_helpers.py index 5975106..810f75c 100644 --- a/src/alpine_bits_python/alpine_bits_helpers.py +++ b/src/alpine_bits_python/alpine_bits_helpers.py @@ -389,8 +389,11 @@ class CommentFactory: # Create list items list_items = [] for item_data in comment_data.list_items: - _LOGGER.info( - f"Creating list item: value={item_data.value}, list_item={item_data.list_item}, language={item_data.language}" + _LOGGER.debug( + "Creating list item: value=%s, list_item=%s, language=%s", + item_data.value, + item_data.list_item, + item_data.language, ) list_item = comment_class.ListItem( @@ -755,8 +758,11 @@ def _process_single_reservation( comments_xml = None if comments: for c in comments: - _LOGGER.info( - f"Creating comment: name={c.name}, text={c.text}, list_items={len(c.list_items)}" + _LOGGER.debug( + "Creating comment: name=%s, text=%s, list_items=%s", + c.name, + c.text, + len(c.list_items), ) comments_data = CommentsData(comments=comments) @@ -774,7 +780,7 @@ def _process_single_reservation( profile_info = HotelReservation.ResGlobalInfo.Profiles.ProfileInfo(profile=profile) - _LOGGER.info(f"Type of profile_info: {type(profile_info)}") + _LOGGER.info("Type of profile_info: %s", type(profile_info)) profiles = HotelReservation.ResGlobalInfo.Profiles(profile_info=profile_info) @@ -785,7 +791,7 @@ def _process_single_reservation( profiles=profiles, ) - hotel_reservation = HotelReservation( + return HotelReservation( create_date_time=reservation.created_at.replace(tzinfo=UTC).isoformat(), res_status=HotelReservationResStatus.REQUESTED, room_stay_reservation="true", @@ -795,8 +801,6 @@ def _process_single_reservation( res_global_info=res_global_info, ) - return hotel_reservation - def _create_xml_from_db( entries: list[tuple[Reservation, Customer]] | tuple[Reservation, Customer], @@ -815,7 +819,9 @@ def _create_xml_from_db( for reservation, customer in entries: _LOGGER.info( - f"Creating XML for reservation {reservation.unique_id} and customer {customer.given_name}" + "Creating XML for reservation %s and customer %s", + reservation.id, + customer.id, ) try: @@ -823,9 +829,11 @@ def _create_xml_from_db( reservations_list.append(hotel_reservation) - except Exception as e: - _LOGGER.error( - f"Error creating XML for reservation {reservation.unique_id} and customer {customer.given_name}: {e}" + except Exception: + _LOGGER.exception( + "Error creating XML for reservation %s and customer %s", + reservation.unique_id, + customer.given_name, ) _LOGGER.debug(traceback.format_exc()) @@ -840,8 +848,8 @@ def _create_xml_from_db( try: ota_hotel_res_notif_rq.model_validate(ota_hotel_res_notif_rq.model_dump()) - except Exception as e: - _LOGGER.error(f"Validation error: {e}") + except Exception: + _LOGGER.exception("Validation error: ") raise return ota_hotel_res_notif_rq @@ -863,189 +871,3 @@ def _create_xml_from_db( return ota_res_retrieve_rs raise ValueError(f"Unsupported message type: {type}") - - -# Usage examples -if __name__ == "__main__": - # Create customer data using simple data class - 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", - ) - - # Create customer for OtaHotelResNotifRq - notif_customer = CustomerFactory.create_notif_customer(customer_data) - print( - "Created NotifCustomer:", - notif_customer.person_name.given_name, - notif_customer.person_name.surname, - ) - - # Create customer for OtaResRetrieveRs - retrieve_customer = CustomerFactory.create_retrieve_customer(customer_data) - print( - "Created RetrieveCustomer:", - retrieve_customer.person_name.given_name, - retrieve_customer.person_name.surname, - ) - - # Convert back to data class - converted_data = CustomerFactory.from_notif_customer(notif_customer) - print("Converted back to data:", converted_data.given_name, converted_data.surname) - - # Verify they contain the same information - 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 ---") - - # Create complete ResGuests structure for OtaHotelResNotifRq - much simpler! - notif_res_guests = ResGuestFactory.create_notif_res_guests(customer_data) - print( - "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! - retrieve_res_guests = ResGuestFactory.create_retrieve_res_guests(customer_data) - print( - "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 - extracted_data = ResGuestFactory.extract_primary_customer(retrieve_res_guests) - print("Extracted customer data:", extracted_data.given_name, extracted_data.surname) - - # Verify roundtrip conversion - print("Roundtrip conversion successful:", customer_data == extracted_data) - - print("\n--- Unified AlpineBitsFactory Examples ---") - - # Much simpler approach - single factory with enum parameter! - print("=== Customer Creation ===") - notif_customer = AlpineBitsFactory.create(customer_data, OtaMessageType.NOTIF) - retrieve_customer = AlpineBitsFactory.create(customer_data, OtaMessageType.RETRIEVE) - print("Created customers using unified factory") - - print("=== HotelReservationId Creation ===") - reservation_id_data = HotelReservationIdData( - res_id_type="123", res_id_value="RESERVATION-456", res_id_source="HOTEL_SYSTEM" - ) - notif_res_id = AlpineBitsFactory.create(reservation_id_data, OtaMessageType.NOTIF) - retrieve_res_id = AlpineBitsFactory.create( - reservation_id_data, OtaMessageType.RETRIEVE - ) - 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 ===") - notif_res_guests = AlpineBitsFactory.create_res_guests( - customer_data, OtaMessageType.NOTIF - ) - retrieve_res_guests = AlpineBitsFactory.create_res_guests( - customer_data, OtaMessageType.RETRIEVE - ) - print("Created ResGuests using unified factory") - - print("=== Data Extraction ===") - # Extract data back using unified interface - extracted_customer_data = AlpineBitsFactory.extract_data(notif_customer) - 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) - - print("Data extraction successful:") - print("- Customer roundtrip:", customer_data == extracted_customer_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("\n--- Comparison with old approach ---") - print("Old way required multiple imports and knowing specific factory methods") - print("New way: single import, single factory, enum parameter to specify type!") diff --git a/src/alpine_bits_python/api.py b/src/alpine_bits_python/api.py index 15a0c2e..6a50647 100644 --- a/src/alpine_bits_python/api.py +++ b/src/alpine_bits_python/api.py @@ -189,12 +189,14 @@ async def lifespan(app: FastAPI): "form_processed", hotel_id, partial(push_listener, hotel=hotel) ) _LOGGER.info( - f"Registered push listener for hotel {hotel_id} with endpoint {push_endpoint.get('url')}" + "Registered push listener for hotel %s with endpoint %s", + hotel_id, + push_endpoint.get("url"), ) elif push_endpoint and not hotel_id: - _LOGGER.warning(f"Hotel has push_endpoint but no hotel_id: {hotel}") + _LOGGER.warning("Hotel has push_endpoint but no hotel_id: %s", hotel) elif hotel_id and not push_endpoint: - _LOGGER.info(f"Hotel {hotel_id} has no push_endpoint configured") + _LOGGER.info("Hotel %s has no push_endpoint configured", hotel_id) # Create tables async with engine.begin() as conn: