From 4416397a695bda35e5b36e7d7e51ab17430c4458 Mon Sep 17 00:00:00 2001 From: Jonas Linter Date: Mon, 29 Sep 2025 09:24:19 +0200 Subject: [PATCH] Added guestCounts to output.xml --- README.md | 18 ++++ output.xml | 31 +++--- src/alpine_bits_python/main.py | 100 ++++++++++++++------ src/alpine_bits_python/reservations.py | 7 ++ src/alpine_bits_python/simplified_access.py | 53 +++++++++++ 5 files changed, 165 insertions(+), 44 deletions(-) create mode 100644 src/alpine_bits_python/reservations.py diff --git a/README.md b/README.md index 0048394..231c9ea 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,21 @@ When ASA wants to know our GuestRequests from the Landing page then they are the Just for GuestRequests this should be fine however. + + +# Wix formular parsing Notizen + + +### Kontaktinformationen + + + +#### Werbeparameter + + + + +field:angebot_auswaehlen -> Kommentar mit Angebot + + + diff --git a/output.xml b/output.xml index 4c6400f..58471d0 100644 --- a/output.xml +++ b/output.xml @@ -1,11 +1,17 @@ - + - + + + + + + + @@ -15,15 +21,12 @@ - Familie - Miriana - Darman + Frau + Elena + Battiloro - - miriana.m9@gmail.com -
- -
+ + e.battiloro1@gmail.com
@@ -32,13 +35,13 @@
- - Landing page comment - Wix form submission + + Herbstferien - Familienzeit mit Dolomitenblick + Angebot/Offerta - + diff --git a/src/alpine_bits_python/main.py b/src/alpine_bits_python/main.py index 2555b85..a6d852d 100644 --- a/src/alpine_bits_python/main.py +++ b/src/alpine_bits_python/main.py @@ -11,6 +11,7 @@ from .simplified_access import ( CommentsData, CommentListItemData, CustomerData, + GuestCountsFactory, HotelReservationIdData, PhoneTechType, AlpineBitsFactory, @@ -53,23 +54,29 @@ def main(): db = SessionLocal() # Load data from JSON file - json_path = os.path.join(os.path.dirname(__file__), '../../test_data/wix_test_data_20250927_070500.json') + json_path = os.path.join(os.path.dirname(__file__), '../../test_data/wix_test_data_20250928_132611.json') with open(json_path, 'r', encoding='utf-8') as f: wix_data = json.load(f) data = wix_data["data"]["data"] - # Extract relevant fields - given_name = data.get("field:first_name_abae") or data.get("contact", {}).get("name", {}).get("first") - surname = data.get("field:last_name_d97c") or data.get("contact", {}).get("name", {}).get("last") + + + contact_info = data.get("contact", {}) + + first_name = contact_info.get("name", {}).get("first") + last_name = contact_info.get("name", {}).get("last") + email = contact_info.get("email") + phone_number = contact_info.get("phones", [{}])[0].get("e164Phone") # phone without formatting + locale = contact_info.get("locale", "de-de") + + name_prefix = data.get("field:anrede") - email_address = data.get("field:email_5139") or data.get("contact", {}).get("email") - phone = data.get("field:phone_4c77") or (data.get("contact", {}).get("phones", [{}])[0].get("formattedPhone")) email_newsletter = data.get("field:form_field_5a7b", "") != "Non selezionato" address_line = None city_name = None postal_code = None - country_code = data.get("contact", {}).get("phones", [{}])[0].get("countryCode", "") or "IT" + country_code = None gender = None birth_date = None language = data.get("contact", {}).get("locale", "en")[:2] @@ -82,13 +89,22 @@ def main(): num_adults = int(data.get("field:number_7cf5") or 2) num_children = int(data.get("field:anzahl_kinder") or 0) children_ages = [] - for k in data.keys(): - if k.startswith("field:alter_kind_"): - try: - age = int(data[k]) - children_ages.append(age) - except Exception: - pass + + if num_children > 0: + for k in data.keys(): + if k.startswith("field:alter_kind_"): + try: + age = int(data[k]) + children_ages.append(age) + except Exception: + pass + + guest_counts = GuestCountsFactory().create_retrieve_guest_counts(num_adults, children_ages) + + + + # print guests and kids info for debugging + print(f"Guests: {num_adults} adults, {num_children} children, ages: {children_ages}") # UTM and offer utm_fields = [ @@ -108,11 +124,11 @@ def main(): # Save customer and reservation to DB db_customer = DBCustomer( - given_name=given_name, - surname=surname, + given_name=first_name, + surname=last_name, name_prefix=name_prefix, - email_address=email_address, - phone=phone, + email_address=email, + phone=phone_number, email_newsletter=email_newsletter, address_line=address_line, city_name=city_name, @@ -155,21 +171,24 @@ def main(): # RoomStay with TimeSpan room_stay = ( ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay( - time_span=time_span + time_span=time_span, + guest_counts=guest_counts, + ) ) room_stays = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays( - room_stay=[room_stay] + room_stay=[room_stay], + ) # CustomerData - phone_numbers = [(phone, PhoneTechType.MOBILE)] if phone else [] + phone_numbers = [(phone_number, PhoneTechType.MOBILE)] if phone_number else [] customer_data = CustomerData( - given_name=given_name, - surname=surname, + given_name=first_name, + surname=last_name, name_prefix=name_prefix, phone_numbers=phone_numbers, - email_address=email_address, + email_address=email, email_newsletter=email_newsletter, address_line=address_line, city_name=city_name, @@ -203,18 +222,39 @@ def main(): hotel_code="123", hotel_name="Frangart Inn" ) - # Comments from UTM fields and other info - comment = CommentData( - name= ab.CommentName2.CUSTOMER_COMMENT, - text="Wix form submission", + + user_comment_text = data.get("field:long_answer_3524", "") + + + comment = None + + if user_comment_text: + + # Comments from UTM fields and other info + comment = CommentData( + name= ab.CommentName2.CUSTOMER_COMMENT, + text=user_comment_text, + list_items=[CommentListItemData( + value="Landing page comment", + language=language, + list_item="1", + )], + ) + + + offer_comment = CommentData( + name= ab.CommentName2.ADDITIONAL_INFO, + text="Angebot/Offerta", list_items=[CommentListItemData( - value="Landing page comment", + value=offer, language=language, list_item="1", )], ) - comments_data = CommentsData(comments=[comment]) + comments = [offer_comment, comment] if comment else [offer_comment] + + comments_data = CommentsData(comments=comments) comments = alpine_bits_factory.create(comments_data, OtaMessageType.RETRIEVE) # ResGlobalInfo diff --git a/src/alpine_bits_python/reservations.py b/src/alpine_bits_python/reservations.py new file mode 100644 index 0000000..70d483a --- /dev/null +++ b/src/alpine_bits_python/reservations.py @@ -0,0 +1,7 @@ + + + +def parse_form(form: dict): + + pass + \ No newline at end of file diff --git a/src/alpine_bits_python/simplified_access.py b/src/alpine_bits_python/simplified_access.py index f20694a..b52d381 100644 --- a/src/alpine_bits_python/simplified_access.py +++ b/src/alpine_bits_python/simplified_access.py @@ -20,6 +20,11 @@ RetrieveComments = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalI NotifComment = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGlobalInfo.Comments.Comment RetrieveComment = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.Comments.Comment +# type aliases for GuestCounts +NotifGuestCounts = OtaHotelResNotifRq.HotelReservations.HotelReservation.RoomStays.RoomStay.GuestCounts +RetrieveGuestCounts = OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay.GuestCounts + + # phonetechtype enum 1,3,5 voice, fax, mobile class PhoneTechType(Enum): @@ -34,6 +39,12 @@ class OtaMessageType(Enum): RETRIEVE = "retrieve" # For OtaResRetrieveRs +@dataclass +class KidsAgeData: + """Data class to hold information about children's ages.""" + ages: list[int] + + @dataclass class CustomerData: """Simple data class to hold customer information without nested type constraints.""" @@ -65,6 +76,48 @@ class CustomerData: self.phone_numbers = [] +class GuestCountsFactory: + + @staticmethod + def create_notif_guest_counts(adults: int, kids: Optional[list[int]] = None) -> NotifGuestCounts: + """ + Create a GuestCounts object for OtaHotelResNotifRq. + :param adults: Number of adults + :param kids: List of ages for each kid (optional) + :return: GuestCounts instance + """ + return GuestCountsFactory._create_guest_counts(adults, kids, NotifGuestCounts) + + @staticmethod + def create_retrieve_guest_counts(adults: int, kids: Optional[list[int]] = None) -> RetrieveGuestCounts: + """ + Create a GuestCounts object for OtaResRetrieveRs. + :param adults: Number of adults + :param kids: List of ages for each kid (optional) + :return: GuestCounts instance + """ + return GuestCountsFactory._create_guest_counts(adults, kids, RetrieveGuestCounts) + + + @staticmethod + def _create_guest_counts(adults: int, kids: Optional[list[int]], guest_counts_class: type) -> Any: + """ + Internal method to create a GuestCounts object of the specified type. + :param adults: Number of adults + :param kids: List of ages for each kid (optional) + :param guest_counts_class: The GuestCounts class to instantiate + :return: GuestCounts instance + """ + GuestCount = guest_counts_class.GuestCount + guest_count_list = [] + if adults > 0: + guest_count_list.append(GuestCount(count=str(adults))) + if kids: + for age in kids: + guest_count_list.append(GuestCount(count="1", age=str(age))) + return guest_counts_class(guest_count=guest_count_list) + + class CustomerFactory: """Factory class to create Customer instances for both OtaHotelResNotifRq and OtaResRetrieveRs."""