Added guestCounts to output.xml
This commit is contained in:
18
README.md
18
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
|
||||
|
||||
|
||||
|
||||
|
||||
31
output.xml
31
output.xml
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
7
src/alpine_bits_python/reservations.py
Normal file
7
src/alpine_bits_python/reservations.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
|
||||
|
||||
def parse_form(form: dict):
|
||||
|
||||
pass
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user