Merging to main
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
import traceback
|
||||||
from typing import Union, Optional, Any, TypeVar
|
from typing import Union, Optional, Any, TypeVar
|
||||||
from pydantic import BaseModel, ConfigDict, Field
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
@@ -14,6 +15,7 @@ from .generated.alpinebits import (
|
|||||||
OtaHotelResNotifRq,
|
OtaHotelResNotifRq,
|
||||||
OtaResRetrieveRs,
|
OtaResRetrieveRs,
|
||||||
CommentName2,
|
CommentName2,
|
||||||
|
ProfileProfileType,
|
||||||
UniqueIdType2,
|
UniqueIdType2,
|
||||||
)
|
)
|
||||||
import logging
|
import logging
|
||||||
@@ -735,10 +737,12 @@ def _process_single_reservation(reservation: Reservation, customer: Customer, me
|
|||||||
UniqueId = NotifUniqueId
|
UniqueId = NotifUniqueId
|
||||||
RoomStays = NotifRoomStays
|
RoomStays = NotifRoomStays
|
||||||
HotelReservation = NotifHotelReservation
|
HotelReservation = NotifHotelReservation
|
||||||
|
Profile = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGlobalInfo.Profiles.ProfileInfo.Profile
|
||||||
elif message_type == OtaMessageType.RETRIEVE:
|
elif message_type == OtaMessageType.RETRIEVE:
|
||||||
UniqueId = RetrieveUniqueId
|
UniqueId = RetrieveUniqueId
|
||||||
RoomStays = RetrieveRoomStays
|
RoomStays = RetrieveRoomStays
|
||||||
HotelReservation = RetrieveHotelReservation
|
HotelReservation = RetrieveHotelReservation
|
||||||
|
Profile = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.Profiles.ProfileInfo.Profile
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported message type: {message_type}")
|
raise ValueError(f"Unsupported message type: {message_type}")
|
||||||
|
|
||||||
@@ -795,10 +799,24 @@ def _process_single_reservation(reservation: Reservation, customer: Customer, me
|
|||||||
else: # extract string from Column object
|
else: # extract string from Column object
|
||||||
klick_id = str(klick_id)
|
klick_id = str(klick_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
utm_medium = (
|
||||||
|
str(reservation.utm_medium)
|
||||||
|
if reservation.utm_medium is not None and str(reservation.utm_medium) != ""
|
||||||
|
else "website"
|
||||||
|
)
|
||||||
|
|
||||||
|
#shorten klick_id if longer than 64 characters
|
||||||
|
if klick_id is not None and len(klick_id) > 64:
|
||||||
|
klick_id = klick_id[:64]
|
||||||
|
|
||||||
hotel_res_id_data = HotelReservationIdData(
|
hotel_res_id_data = HotelReservationIdData(
|
||||||
res_id_type="13",
|
res_id_type="13",
|
||||||
res_id_value=klick_id,
|
res_id_value=klick_id,
|
||||||
res_id_source=None,
|
res_id_source=utm_medium,
|
||||||
res_id_source_context="99tales",
|
res_id_source_context="99tales",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -866,12 +884,26 @@ def _process_single_reservation(reservation: Reservation, customer: Customer, me
|
|||||||
comments_xml = alpine_bits_factory.create(
|
comments_xml = alpine_bits_factory.create(
|
||||||
comments_data, message_type
|
comments_data, message_type
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
company_name = Profile.CompanyInfo.CompanyName(value="99tales GmbH", code="who knows?", code_context="who knows?")
|
||||||
|
|
||||||
|
company_info = Profile.CompanyInfo(company_name=company_name)
|
||||||
|
|
||||||
|
profile = Profile(company_info=company_info, profile_type=ProfileProfileType.VALUE_4)
|
||||||
|
|
||||||
|
profile_info = HotelReservation.ResGlobalInfo.Profiles.ProfileInfo(profile=profile)
|
||||||
|
|
||||||
|
_LOGGER.info(f"Type of profile_info: {type(profile_info)}")
|
||||||
|
|
||||||
|
profiles = HotelReservation.ResGlobalInfo.Profiles(profile_info=profile_info)
|
||||||
|
|
||||||
res_global_info = (
|
res_global_info = (
|
||||||
HotelReservation.ResGlobalInfo(
|
HotelReservation.ResGlobalInfo(
|
||||||
hotel_reservation_ids=hotel_res_ids,
|
hotel_reservation_ids=hotel_res_ids,
|
||||||
basic_property_info=basic_property_info,
|
basic_property_info=basic_property_info,
|
||||||
comments=comments_xml,
|
comments=comments_xml,
|
||||||
|
profiles=profiles,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -917,6 +949,7 @@ def _create_xml_from_db(entries: list[Tuple[Reservation, Customer]] | Tuple[Rese
|
|||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
f"Error creating XML for reservation {reservation.unique_id} and customer {customer.given_name}: {e}"
|
f"Error creating XML for reservation {reservation.unique_id} and customer {customer.given_name}: {e}"
|
||||||
)
|
)
|
||||||
|
_LOGGER.debug(traceback.format_exc())
|
||||||
|
|
||||||
if type == OtaMessageType.NOTIF:
|
if type == OtaMessageType.NOTIF:
|
||||||
retrieved_reservations = OtaHotelResNotifRq.HotelReservations(
|
retrieved_reservations = OtaHotelResNotifRq.HotelReservations(
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ from datetime import datetime
|
|||||||
from typing import Dict, Any, Optional, List
|
from typing import Dict, Any, Optional, List
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import asyncio
|
||||||
import gzip
|
import gzip
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
from .alpinebits_server import AlpineBitsClientInfo, AlpineBitsServer, Version, AlpineBitsActionName
|
from .alpinebits_server import AlpineBitsClientInfo, AlpineBitsServer, Version, AlpineBitsActionName
|
||||||
@@ -113,13 +114,25 @@ async def push_listener(customer: DBCustomer, reservation: DBReservation, hotel)
|
|||||||
if request.status_code != 200:
|
if request.status_code != 200:
|
||||||
_LOGGER.error(f"Failed to generate push request for hotel {hotel_id}, reservation {reservation.unique_id}: {request.xml_content}")
|
_LOGGER.error(f"Failed to generate push request for hotel {hotel_id}, reservation {reservation.unique_id}: {request.xml_content}")
|
||||||
return
|
return
|
||||||
|
|
||||||
print(request.xml_content)
|
|
||||||
# TODO: Generate AlpineBits OTA_HotelResNotifRQ request
|
|
||||||
# action = "OTA_HotelResNotifRQ"
|
|
||||||
# request = server.handle_request(action, ...)
|
|
||||||
|
|
||||||
print(f"--- Push Payload --- received. Sending to endpoint., hotelid {hotel_id}, reservation {reservation.unique_id}")
|
|
||||||
|
# save push request to file
|
||||||
|
|
||||||
|
logs_dir = "logs/push_requests"
|
||||||
|
if not os.path.exists(logs_dir):
|
||||||
|
os.makedirs(logs_dir, mode=0o755, exist_ok=True)
|
||||||
|
stat_info = os.stat(logs_dir)
|
||||||
|
_LOGGER.info(
|
||||||
|
f"Created directory owner: uid:{stat_info.st_uid}, gid:{stat_info.st_gid}"
|
||||||
|
)
|
||||||
|
_LOGGER.info(f"Directory mode: {oct(stat_info.st_mode)[-3:]}")
|
||||||
|
log_filename = (
|
||||||
|
f"{logs_dir}/alpinebits_push_{hotel_id}_{reservation.unique_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
with open(log_filename, "w", encoding="utf-8") as f:
|
||||||
|
f.write(request.xml_content)
|
||||||
return
|
return
|
||||||
|
|
||||||
headers = {"Authorization": f"Bearer {push_endpoint.get('token','')}"} if push_endpoint.get('token') else {}
|
headers = {"Authorization": f"Bearer {push_endpoint.get('token','')}"} if push_endpoint.get('token') else {}
|
||||||
@@ -337,7 +350,7 @@ async def process_wix_form_submission(request: Request, data: Dict[str, Any], db
|
|||||||
|
|
||||||
name_prefix = data.get("field:anrede")
|
name_prefix = data.get("field:anrede")
|
||||||
email_newsletter_string = data.get("field:form_field_5a7b", "")
|
email_newsletter_string = data.get("field:form_field_5a7b", "")
|
||||||
yes_values = {"Selezionato", "Angekreuzt"}
|
yes_values = {"Selezionato", "Angekreuzt", "Checked"}
|
||||||
email_newsletter = (email_newsletter_string in yes_values)
|
email_newsletter = (email_newsletter_string in yes_values)
|
||||||
address_line = None
|
address_line = None
|
||||||
city_name = None
|
city_name = None
|
||||||
@@ -460,17 +473,21 @@ async def process_wix_form_submission(request: Request, data: Dict[str, Any], db
|
|||||||
await db.commit()
|
await db.commit()
|
||||||
await db.refresh(db_reservation)
|
await db.refresh(db_reservation)
|
||||||
|
|
||||||
|
|
||||||
|
async def push_event():
|
||||||
|
# Fire event for listeners (push, etc.) - hotel-specific dispatch
|
||||||
|
dispatcher = getattr(request.app.state, "event_dispatcher", None)
|
||||||
|
if dispatcher:
|
||||||
|
# Get hotel_code from reservation to target the right listeners
|
||||||
|
hotel_code = getattr(db_reservation, 'hotel_code', None)
|
||||||
|
if hotel_code and hotel_code.strip():
|
||||||
|
await dispatcher.dispatch_for_hotel("form_processed", hotel_code, db_customer, db_reservation)
|
||||||
|
_LOGGER.info(f"Dispatched form_processed event for hotel {hotel_code}")
|
||||||
|
else:
|
||||||
|
_LOGGER.warning("No hotel_code in reservation, skipping push notifications")
|
||||||
|
|
||||||
# Fire event for listeners (push, etc.) - hotel-specific dispatch
|
asyncio.create_task(push_event())
|
||||||
dispatcher = getattr(request.app.state, "event_dispatcher", None)
|
|
||||||
if dispatcher:
|
|
||||||
# Get hotel_code from reservation to target the right listeners
|
|
||||||
hotel_code = getattr(db_reservation, 'hotel_code', None)
|
|
||||||
if hotel_code and hotel_code.strip():
|
|
||||||
await dispatcher.dispatch_for_hotel("form_processed", hotel_code, db_customer, db_reservation)
|
|
||||||
_LOGGER.info(f"Dispatched form_processed event for hotel {hotel_code}")
|
|
||||||
else:
|
|
||||||
_LOGGER.warning("No hotel_code in reservation, skipping push notifications")
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status": "success",
|
"status": "success",
|
||||||
|
|||||||
Reference in New Issue
Block a user