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.
|
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"?>
|
<?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-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"/>
|
<UniqueID Type="14" ID="6b34fe24ac2ff811"/>
|
||||||
<RoomStays>
|
<RoomStays>
|
||||||
<RoomStay>
|
<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>
|
</RoomStay>
|
||||||
</RoomStays>
|
</RoomStays>
|
||||||
<ResGuests>
|
<ResGuests>
|
||||||
@@ -15,15 +21,12 @@
|
|||||||
<Profile>
|
<Profile>
|
||||||
<Customer Language="it">
|
<Customer Language="it">
|
||||||
<PersonName>
|
<PersonName>
|
||||||
<NamePrefix>Familie</NamePrefix>
|
<NamePrefix>Frau</NamePrefix>
|
||||||
<GivenName>Miriana</GivenName>
|
<GivenName>Elena</GivenName>
|
||||||
<Surname>Darman</Surname>
|
<Surname>Battiloro</Surname>
|
||||||
</PersonName>
|
</PersonName>
|
||||||
<Telephone PhoneTechType="5" PhoneNumber="+39 348 443 0969"/>
|
<Telephone PhoneTechType="5" PhoneNumber="+393337673262"/>
|
||||||
<Email Remark="newsletter:no">miriana.m9@gmail.com</Email>
|
<Email Remark="newsletter:no">e.battiloro1@gmail.com</Email>
|
||||||
<Address Remark="catalog:no">
|
|
||||||
<CountryName Code="IT"/>
|
|
||||||
</Address>
|
|
||||||
</Customer>
|
</Customer>
|
||||||
</Profile>
|
</Profile>
|
||||||
</ProfileInfo>
|
</ProfileInfo>
|
||||||
@@ -32,13 +35,13 @@
|
|||||||
</ResGuests>
|
</ResGuests>
|
||||||
<ResGlobalInfo>
|
<ResGlobalInfo>
|
||||||
<Comments>
|
<Comments>
|
||||||
<Comment Name="customer comment">
|
<Comment Name="additional info">
|
||||||
<ListItem ListItem="1" Language="it">Landing page comment</ListItem>
|
<ListItem ListItem="1" Language="it">Herbstferien - Familienzeit mit Dolomitenblick</ListItem>
|
||||||
<Text>Wix form submission</Text>
|
<Text>Angebot/Offerta</Text>
|
||||||
</Comment>
|
</Comment>
|
||||||
</Comments>
|
</Comments>
|
||||||
<HotelReservationIDs>
|
<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>
|
</HotelReservationIDs>
|
||||||
<BasicPropertyInfo HotelCode="123" HotelName="Frangart Inn"/>
|
<BasicPropertyInfo HotelCode="123" HotelName="Frangart Inn"/>
|
||||||
</ResGlobalInfo>
|
</ResGlobalInfo>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from .simplified_access import (
|
|||||||
CommentsData,
|
CommentsData,
|
||||||
CommentListItemData,
|
CommentListItemData,
|
||||||
CustomerData,
|
CustomerData,
|
||||||
|
GuestCountsFactory,
|
||||||
HotelReservationIdData,
|
HotelReservationIdData,
|
||||||
PhoneTechType,
|
PhoneTechType,
|
||||||
AlpineBitsFactory,
|
AlpineBitsFactory,
|
||||||
@@ -53,23 +54,29 @@ def main():
|
|||||||
db = SessionLocal()
|
db = SessionLocal()
|
||||||
|
|
||||||
# Load data from JSON file
|
# 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:
|
with open(json_path, 'r', encoding='utf-8') as f:
|
||||||
wix_data = json.load(f)
|
wix_data = json.load(f)
|
||||||
|
|
||||||
data = wix_data["data"]["data"]
|
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")
|
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"
|
email_newsletter = data.get("field:form_field_5a7b", "") != "Non selezionato"
|
||||||
address_line = None
|
address_line = None
|
||||||
city_name = None
|
city_name = None
|
||||||
postal_code = None
|
postal_code = None
|
||||||
country_code = data.get("contact", {}).get("phones", [{}])[0].get("countryCode", "") or "IT"
|
country_code = None
|
||||||
gender = None
|
gender = None
|
||||||
birth_date = None
|
birth_date = None
|
||||||
language = data.get("contact", {}).get("locale", "en")[:2]
|
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_adults = int(data.get("field:number_7cf5") or 2)
|
||||||
num_children = int(data.get("field:anzahl_kinder") or 0)
|
num_children = int(data.get("field:anzahl_kinder") or 0)
|
||||||
children_ages = []
|
children_ages = []
|
||||||
for k in data.keys():
|
|
||||||
if k.startswith("field:alter_kind_"):
|
if num_children > 0:
|
||||||
try:
|
for k in data.keys():
|
||||||
age = int(data[k])
|
if k.startswith("field:alter_kind_"):
|
||||||
children_ages.append(age)
|
try:
|
||||||
except Exception:
|
age = int(data[k])
|
||||||
pass
|
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 and offer
|
||||||
utm_fields = [
|
utm_fields = [
|
||||||
@@ -108,11 +124,11 @@ def main():
|
|||||||
|
|
||||||
# Save customer and reservation to DB
|
# Save customer and reservation to DB
|
||||||
db_customer = DBCustomer(
|
db_customer = DBCustomer(
|
||||||
given_name=given_name,
|
given_name=first_name,
|
||||||
surname=surname,
|
surname=last_name,
|
||||||
name_prefix=name_prefix,
|
name_prefix=name_prefix,
|
||||||
email_address=email_address,
|
email_address=email,
|
||||||
phone=phone,
|
phone=phone_number,
|
||||||
email_newsletter=email_newsletter,
|
email_newsletter=email_newsletter,
|
||||||
address_line=address_line,
|
address_line=address_line,
|
||||||
city_name=city_name,
|
city_name=city_name,
|
||||||
@@ -155,21 +171,24 @@ def main():
|
|||||||
# RoomStay with TimeSpan
|
# RoomStay with TimeSpan
|
||||||
room_stay = (
|
room_stay = (
|
||||||
ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay(
|
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_stays = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays(
|
||||||
room_stay=[room_stay]
|
room_stay=[room_stay],
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# CustomerData
|
# CustomerData
|
||||||
phone_numbers = [(phone, PhoneTechType.MOBILE)] if phone else []
|
phone_numbers = [(phone_number, PhoneTechType.MOBILE)] if phone_number else []
|
||||||
customer_data = CustomerData(
|
customer_data = CustomerData(
|
||||||
given_name=given_name,
|
given_name=first_name,
|
||||||
surname=surname,
|
surname=last_name,
|
||||||
name_prefix=name_prefix,
|
name_prefix=name_prefix,
|
||||||
phone_numbers=phone_numbers,
|
phone_numbers=phone_numbers,
|
||||||
email_address=email_address,
|
email_address=email,
|
||||||
email_newsletter=email_newsletter,
|
email_newsletter=email_newsletter,
|
||||||
address_line=address_line,
|
address_line=address_line,
|
||||||
city_name=city_name,
|
city_name=city_name,
|
||||||
@@ -203,18 +222,39 @@ def main():
|
|||||||
hotel_code="123", hotel_name="Frangart Inn"
|
hotel_code="123", hotel_name="Frangart Inn"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Comments from UTM fields and other info
|
|
||||||
comment = CommentData(
|
user_comment_text = data.get("field:long_answer_3524", "")
|
||||||
name= ab.CommentName2.CUSTOMER_COMMENT,
|
|
||||||
text="Wix form submission",
|
|
||||||
|
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(
|
list_items=[CommentListItemData(
|
||||||
value="Landing page comment",
|
value=offer,
|
||||||
language=language,
|
language=language,
|
||||||
list_item="1",
|
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)
|
comments = alpine_bits_factory.create(comments_data, OtaMessageType.RETRIEVE)
|
||||||
|
|
||||||
# ResGlobalInfo
|
# 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
|
NotifComment = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGlobalInfo.Comments.Comment
|
||||||
RetrieveComment = OtaResRetrieveRs.ReservationsList.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
|
# phonetechtype enum 1,3,5 voice, fax, mobile
|
||||||
class PhoneTechType(Enum):
|
class PhoneTechType(Enum):
|
||||||
@@ -34,6 +39,12 @@ class OtaMessageType(Enum):
|
|||||||
RETRIEVE = "retrieve" # For OtaResRetrieveRs
|
RETRIEVE = "retrieve" # For OtaResRetrieveRs
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class KidsAgeData:
|
||||||
|
"""Data class to hold information about children's ages."""
|
||||||
|
ages: list[int]
|
||||||
|
|
||||||
|
|
||||||
@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."""
|
||||||
@@ -65,6 +76,48 @@ class CustomerData:
|
|||||||
self.phone_numbers = []
|
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:
|
class CustomerFactory:
|
||||||
"""Factory class to create Customer instances for both OtaHotelResNotifRq and OtaResRetrieveRs."""
|
"""Factory class to create Customer instances for both OtaHotelResNotifRq and OtaResRetrieveRs."""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user