Added guestCounts to output.xml

This commit is contained in:
Jonas Linter
2025-09-29 09:24:19 +02:00
parent ff00edf35d
commit 4416397a69
5 changed files with 165 additions and 44 deletions

View File

@@ -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

View File

@@ -1,11 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<OTA_ResRetrieveRS xmlns="http://www.opentravel.org/OTA/2003/05" Version="7.000">
<ReservationsList>
<HotelReservation CreateDateTime="2025-09-27T15:34:46.762660+00:00" ResStatus="Requested" RoomStayReservation="true">
<HotelReservation CreateDateTime="2025-09-29T07:21:12.768928+00:00" ResStatus="Requested" RoomStayReservation="true">
<UniqueID Type="14" ID="6b34fe24ac2ff811"/>
<RoomStays>
<RoomStay>
<TimeSpan Start="2025-10-03" End="2025-10-05"/>
<GuestCounts>
<GuestCount Count="2"/>
<GuestCount Count="1" Age="3"/>
<GuestCount Count="1" Age="0"/>
<GuestCount Count="1" Age="1"/>
</GuestCounts>
<TimeSpan Start="2025-10-31" End="2025-11-02"/>
</RoomStay>
</RoomStays>
<ResGuests>
@@ -15,15 +21,12 @@
<Profile>
<Customer Language="it">
<PersonName>
<NamePrefix>Familie</NamePrefix>
<GivenName>Miriana</GivenName>
<Surname>Darman</Surname>
<NamePrefix>Frau</NamePrefix>
<GivenName>Elena</GivenName>
<Surname>Battiloro</Surname>
</PersonName>
<Telephone PhoneTechType="5" PhoneNumber="+39 348 443 0969"/>
<Email Remark="newsletter:no">miriana.m9@gmail.com</Email>
<Address Remark="catalog:no">
<CountryName Code="IT"/>
</Address>
<Telephone PhoneTechType="5" PhoneNumber="+393337673262"/>
<Email Remark="newsletter:no">e.battiloro1@gmail.com</Email>
</Customer>
</Profile>
</ProfileInfo>
@@ -32,13 +35,13 @@
</ResGuests>
<ResGlobalInfo>
<Comments>
<Comment Name="customer comment">
<ListItem ListItem="1" Language="it">Landing page comment</ListItem>
<Text>Wix form submission</Text>
<Comment Name="additional info">
<ListItem ListItem="1" Language="it">Herbstferien - Familienzeit mit Dolomitenblick</ListItem>
<Text>Angebot/Offerta</Text>
</Comment>
</Comments>
<HotelReservationIDs>
<HotelReservationID ResID_Type="13" ResID_Value="PAZXh0bgNhZW0BMABhZGlkAasmYBTNE3QBp1jWuJ9zIpfEGRJMP63fMAMI405yvG5EtH-OT0PxSkAbBJaudFHR6cMtkdHu_aem_fopaFtECyVPNW9fmWfEkyA" ResID_SourceContext="99tales"/>
<HotelReservationID ResID_Type="13" ResID_Value="PAZXh0bgNhZW0BMABhZGlkAasmYBhk4DQBp02L46Rl1jAuccxsOaeFSv7WSFnP-MQCsOrz9yDnKRH4hwZ7GEgxF9gy0_OF_aem_qSvrs6xsBkvTaI_Y9_hfnQ" ResID_SourceContext="99tales"/>
</HotelReservationIDs>
<BasicPropertyInfo HotelCode="123" HotelName="Frangart Inn"/>
</ResGlobalInfo>

View File

@@ -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

View File

@@ -0,0 +1,7 @@
def parse_form(form: dict):
pass

View File

@@ -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."""