Compare commits
3 Commits
69fb1374b2
...
95b17b8776
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95b17b8776 | ||
|
|
1b3ebb3cad | ||
|
|
18d30a140f |
@@ -1,7 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import UTC, datetime
|
from datetime import UTC
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
@@ -786,7 +786,7 @@ def _process_single_reservation(
|
|||||||
)
|
)
|
||||||
|
|
||||||
hotel_reservation = HotelReservation(
|
hotel_reservation = HotelReservation(
|
||||||
create_date_time=datetime.now(UTC).isoformat(),
|
create_date_time=reservation.created_at.replace(tzinfo=UTC).isoformat(),
|
||||||
res_status=HotelReservationResStatus.REQUESTED,
|
res_status=HotelReservationResStatus.REQUESTED,
|
||||||
room_stay_reservation="true",
|
room_stay_reservation="true",
|
||||||
unique_id=unique_id,
|
unique_id=unique_id,
|
||||||
|
|||||||
@@ -505,6 +505,9 @@ class ReadAction(AlpineBitsAction):
|
|||||||
|
|
||||||
start_date = None
|
start_date = None
|
||||||
|
|
||||||
|
"""When given, the server will send only inquiries generated after the Start timestamp, regardless
|
||||||
|
whether the client has retrieved them before or not."""
|
||||||
|
|
||||||
if hotel_read_request.selection_criteria is not None:
|
if hotel_read_request.selection_criteria is not None:
|
||||||
start_date = datetime.fromisoformat(
|
start_date = datetime.fromisoformat(
|
||||||
hotel_read_request.selection_criteria.start
|
hotel_read_request.selection_criteria.start
|
||||||
@@ -518,7 +521,8 @@ class ReadAction(AlpineBitsAction):
|
|||||||
.filter(Reservation.hotel_code == hotelid)
|
.filter(Reservation.hotel_code == hotelid)
|
||||||
)
|
)
|
||||||
if start_date:
|
if start_date:
|
||||||
stmt = stmt.filter(Reservation.start_date >= start_date)
|
_LOGGER.info("Filtering reservations from start date %s", start_date)
|
||||||
|
stmt = stmt.filter(Reservation.created_at >= start_date)
|
||||||
# remove reservations that have been acknowledged via client_id
|
# remove reservations that have been acknowledged via client_id
|
||||||
elif client_info.client_id:
|
elif client_info.client_id:
|
||||||
subquery = (
|
subquery = (
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from XML generation (xsdata) follows clean architecture principles.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
from datetime import date
|
from datetime import date, datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
from pydantic import BaseModel, EmailStr, Field, field_validator, model_validator
|
from pydantic import BaseModel, EmailStr, Field, field_validator, model_validator
|
||||||
@@ -43,6 +43,7 @@ class ReservationData(BaseModel):
|
|||||||
md5_unique_id: str | None = Field(None, min_length=1, max_length=32)
|
md5_unique_id: str | None = Field(None, min_length=1, max_length=32)
|
||||||
start_date: date
|
start_date: date
|
||||||
end_date: date
|
end_date: date
|
||||||
|
created_at: datetime = Field(default_factory=datetime.now)
|
||||||
num_adults: int = Field(..., ge=1)
|
num_adults: int = Field(..., ge=1)
|
||||||
num_children: int = Field(0, ge=0, le=10)
|
num_children: int = Field(0, ge=0, le=10)
|
||||||
children_ages: list[int] = Field(default_factory=list)
|
children_ages: list[int] = Field(default_factory=list)
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ def sample_reservation(sample_customer):
|
|||||||
num_children=1,
|
num_children=1,
|
||||||
children_ages=[8],
|
children_ages=[8],
|
||||||
offer="Christmas Special",
|
offer="Christmas Special",
|
||||||
created_at=datetime.now(UTC),
|
created_at=datetime(2024, 11, 1, 12, 0, 0, tzinfo=UTC),
|
||||||
utm_source="google",
|
utm_source="google",
|
||||||
utm_medium="cpc",
|
utm_medium="cpc",
|
||||||
utm_campaign="winter2024",
|
utm_campaign="winter2024",
|
||||||
@@ -109,8 +109,6 @@ def sample_reservation(sample_customer):
|
|||||||
children_csv = ",".join(str(int(a)) for a in children_list) if children_list else ""
|
children_csv = ",".join(str(int(a)) for a in children_list) if children_list else ""
|
||||||
data["children_ages"] = children_csv
|
data["children_ages"] = children_csv
|
||||||
|
|
||||||
print(data)
|
|
||||||
|
|
||||||
return Reservation(
|
return Reservation(
|
||||||
id=1,
|
id=1,
|
||||||
customer_id=1,
|
customer_id=1,
|
||||||
@@ -141,7 +139,7 @@ def minimal_reservation(minimal_customer):
|
|||||||
num_children=0,
|
num_children=0,
|
||||||
children_ages=[],
|
children_ages=[],
|
||||||
hotel_code="HOTEL123",
|
hotel_code="HOTEL123",
|
||||||
created_at=datetime.now(UTC),
|
created_at=datetime(2024, 12, 2, 12, 0, 0, tzinfo=UTC),
|
||||||
hotel_name="Alpine Paradise Resort",
|
hotel_name="Alpine Paradise Resort",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -169,7 +167,7 @@ def read_request_xml():
|
|||||||
Version="8.000">
|
Version="8.000">
|
||||||
<ReadRequests>
|
<ReadRequests>
|
||||||
<HotelReadRequest HotelCode="HOTEL123" HotelName="Alpine Paradise Resort">
|
<HotelReadRequest HotelCode="HOTEL123" HotelName="Alpine Paradise Resort">
|
||||||
<SelectionCriteria Start="2024-12-01" End="2025-01-31"/>
|
<SelectionCriteria Start="2024-10-01" End="2025-01-31"/>
|
||||||
</HotelReadRequest>
|
</HotelReadRequest>
|
||||||
</ReadRequests>
|
</ReadRequests>
|
||||||
</OTA_ReadRQ>"""
|
</OTA_ReadRQ>"""
|
||||||
@@ -334,7 +332,7 @@ class TestXMLParsing:
|
|||||||
assert hotel_req.hotel_code == "HOTEL123"
|
assert hotel_req.hotel_code == "HOTEL123"
|
||||||
assert hotel_req.hotel_name == "Alpine Paradise Resort"
|
assert hotel_req.hotel_name == "Alpine Paradise Resort"
|
||||||
assert hotel_req.selection_criteria is not None
|
assert hotel_req.selection_criteria is not None
|
||||||
assert hotel_req.selection_criteria.start == "2024-12-01"
|
assert hotel_req.selection_criteria.start == "2024-10-01"
|
||||||
|
|
||||||
def test_parse_read_request_no_date(self, read_request_xml_no_date_filter):
|
def test_parse_read_request_no_date(self, read_request_xml_no_date_filter):
|
||||||
"""Test parsing of OTA_ReadRQ without date filter."""
|
"""Test parsing of OTA_ReadRQ without date filter."""
|
||||||
@@ -715,7 +713,11 @@ class TestAcknowledgments:
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_acknowledgments_work_with_date_filters(
|
async def test_acknowledgments_work_with_date_filters(
|
||||||
self, alpinebits_server, populated_db_session, client_info
|
self,
|
||||||
|
alpinebits_server,
|
||||||
|
populated_db_session,
|
||||||
|
client_info,
|
||||||
|
read_request_xml_no_date_filter,
|
||||||
):
|
):
|
||||||
"""Test 5: Verify acknowledgments still work when SelectionCriteria date filters are applied."""
|
"""Test 5: Verify acknowledgments still work when SelectionCriteria date filters are applied."""
|
||||||
# Read request with date filter
|
# Read request with date filter
|
||||||
@@ -726,7 +728,7 @@ class TestAcknowledgments:
|
|||||||
Version="8.000">
|
Version="8.000">
|
||||||
<ReadRequests>
|
<ReadRequests>
|
||||||
<HotelReadRequest HotelCode="HOTEL123" HotelName="Alpine Paradise Resort">
|
<HotelReadRequest HotelCode="HOTEL123" HotelName="Alpine Paradise Resort">
|
||||||
<SelectionCriteria Start="2024-12-01" End="2025-02-01"/>
|
<SelectionCriteria Start="2024-12-01"/>
|
||||||
</HotelReadRequest>
|
</HotelReadRequest>
|
||||||
</ReadRequests>
|
</ReadRequests>
|
||||||
</OTA_ReadRQ>"""
|
</OTA_ReadRQ>"""
|
||||||
@@ -751,9 +753,14 @@ class TestAcknowledgments:
|
|||||||
):
|
):
|
||||||
initial_count = len(initial_parsed.reservations_list.hotel_reservation)
|
initial_count = len(initial_parsed.reservations_list.hotel_reservation)
|
||||||
|
|
||||||
|
assert initial_count > 0, "Initial count with date filter should be > 0"
|
||||||
|
assert initial_count == 1, (
|
||||||
|
"Should only return one reservation with this date filter"
|
||||||
|
)
|
||||||
|
|
||||||
# Acknowledge one reservation that falls within the date range
|
# Acknowledge one reservation that falls within the date range
|
||||||
# The sample_reservation has dates 2024-12-25 to 2024-12-31, which should be in range
|
# The sample_reservation was created at 2024-11-01 and thus falls out of range
|
||||||
sample_unique_id = "RES-2024-001"
|
sample_unique_id = "RES-2024-002"
|
||||||
md5_hash = hashlib.md5(sample_unique_id.encode()).hexdigest()
|
md5_hash = hashlib.md5(sample_unique_id.encode()).hexdigest()
|
||||||
|
|
||||||
acked_request = AckedRequest(
|
acked_request = AckedRequest(
|
||||||
@@ -764,6 +771,31 @@ class TestAcknowledgments:
|
|||||||
populated_db_session.add(acked_request)
|
populated_db_session.add(acked_request)
|
||||||
await populated_db_session.commit()
|
await populated_db_session.commit()
|
||||||
|
|
||||||
|
without_filter_read = await alpinebits_server.handle_request(
|
||||||
|
request_action_name="OTA_Read:GuestRequests",
|
||||||
|
request_xml=read_request_xml_no_date_filter,
|
||||||
|
client_info=client_info,
|
||||||
|
version="2024-10",
|
||||||
|
dbsession=populated_db_session,
|
||||||
|
)
|
||||||
|
|
||||||
|
without_filter_parsed = parser.from_string(
|
||||||
|
without_filter_read.xml_content, OtaResRetrieveRs
|
||||||
|
)
|
||||||
|
|
||||||
|
without_filter_count = 0
|
||||||
|
if (
|
||||||
|
without_filter_parsed.reservations_list
|
||||||
|
and without_filter_parsed.reservations_list.hotel_reservation
|
||||||
|
):
|
||||||
|
without_filter_count = len(
|
||||||
|
without_filter_parsed.reservations_list.hotel_reservation
|
||||||
|
)
|
||||||
|
|
||||||
|
assert without_filter_count == 1, (
|
||||||
|
"Without date filter, should return one reservation after acknowledgment"
|
||||||
|
)
|
||||||
|
|
||||||
# Second read with same date filter
|
# Second read with same date filter
|
||||||
second_response = await alpinebits_server.handle_request(
|
second_response = await alpinebits_server.handle_request(
|
||||||
request_action_name="OTA_Read:GuestRequests",
|
request_action_name="OTA_Read:GuestRequests",
|
||||||
@@ -783,8 +815,10 @@ class TestAcknowledgments:
|
|||||||
):
|
):
|
||||||
second_count = len(second_parsed.reservations_list.hotel_reservation)
|
second_count = len(second_parsed.reservations_list.hotel_reservation)
|
||||||
|
|
||||||
# Should have fewer reservations even with date filter
|
# Should have exactly the same amount of reservations
|
||||||
assert second_count < initial_count
|
assert second_count == initial_count, (
|
||||||
|
"Acknowledgment should not affect count when date filter is applied"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user