Done but not really complete
This commit is contained in:
@@ -3,7 +3,7 @@ import hashlib
|
||||
import os
|
||||
from typing import Any, AsyncGenerator, Callable, TypeVar
|
||||
|
||||
from sqlalchemy import Boolean, Column, Date, DateTime, ForeignKey, Integer, String
|
||||
from sqlalchemy import Boolean, Column, Date, DateTime, ForeignKey, Integer, String, JSON
|
||||
from sqlalchemy.exc import DBAPIError
|
||||
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine, async_sessionmaker
|
||||
from sqlalchemy.orm import declarative_base, relationship
|
||||
@@ -337,11 +337,14 @@ class AckedRequest(Base):
|
||||
|
||||
|
||||
class Conversion(Base):
|
||||
"""Conversion/daily sales data from hotel PMS.
|
||||
"""Conversion data from hotel PMS.
|
||||
|
||||
Tracks actual sales revenue for reservations. Each row represents one day
|
||||
of a reservation stay. Linked to reservations via advertising tracking data
|
||||
(fbclid, gclid, etc) stored in advertisingCampagne field.
|
||||
Represents a single reservation event from the PMS XML with all its metadata.
|
||||
Each row links to one reservation from the PMS system. A reservation can have
|
||||
multiple room reservations (stored in RoomReservation table).
|
||||
|
||||
Linked to reservations via advertising tracking data (fbclid, gclid, etc)
|
||||
stored in advertisingCampagne field.
|
||||
"""
|
||||
|
||||
__tablename__ = "conversions"
|
||||
@@ -382,30 +385,66 @@ class Conversion(Base):
|
||||
String, index=True
|
||||
) # advertisingCampagne (contains fbclid/gclid)
|
||||
|
||||
# Room reservation details
|
||||
arrival_date = Column(Date)
|
||||
departure_date = Column(Date)
|
||||
room_status = Column(String) # status attribute (e.g., "reserved", "checked-in")
|
||||
room_type = Column(String) # roomType attribute
|
||||
room_number = Column(String) # roomNumber attribute
|
||||
num_adults = Column(Integer) # adults attribute
|
||||
rate_plan_code = Column(String) # ratePlanCode attribute
|
||||
|
||||
# Daily sales data (one row per day)
|
||||
sale_date = Column(Date, index=True) # date attribute from dailySale
|
||||
revenue_total = Column(
|
||||
String
|
||||
) # revenueTotal - keeping as string to preserve decimals
|
||||
revenue_logis = Column(String) # revenueLogis (accommodation)
|
||||
revenue_board = Column(String) # revenueBoard (meal plan)
|
||||
revenue_fb = Column(String) # revenueFB (food & beverage)
|
||||
revenue_spa = Column(String) # revenueSpa
|
||||
revenue_other = Column(String) # revenueOther
|
||||
|
||||
# Metadata
|
||||
created_at = Column(DateTime(timezone=True)) # When this record was imported
|
||||
updated_at = Column(DateTime(timezone=True)) # When this record was last updated
|
||||
|
||||
# Relationships
|
||||
reservation = relationship("Reservation", backref="conversions")
|
||||
customer = relationship("Customer", backref="conversions")
|
||||
hashed_customer = relationship("HashedCustomer", backref="conversions")
|
||||
room_reservations = relationship(
|
||||
"RoomReservation", back_populates="conversion", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class RoomReservation(Base):
|
||||
"""Room reservation data from hotel PMS.
|
||||
|
||||
Represents a single room reservation within a conversion/PMS reservation.
|
||||
One conversion can have multiple room reservations (e.g., customer books 3 rooms).
|
||||
|
||||
Daily sales are stored as a JSON blob with an extracted total_revenue field
|
||||
for efficient querying.
|
||||
"""
|
||||
|
||||
__tablename__ = "room_reservations"
|
||||
id = Column(Integer, primary_key=True)
|
||||
|
||||
# Link to the parent conversion/PMS reservation
|
||||
conversion_id = Column(
|
||||
Integer, ForeignKey("conversions.id"), nullable=False, index=True
|
||||
)
|
||||
|
||||
# Unique identifier for this room reservation (for upserts)
|
||||
# Composite: pms_reservation_id + room_number
|
||||
pms_hotel_reservation_id = Column(String, unique=True, index=True)
|
||||
|
||||
# Room reservation details
|
||||
arrival_date = Column(Date, index=True) # arrival attribute
|
||||
departure_date = Column(Date, index=True) # departure attribute
|
||||
room_status = Column(String) # status attribute (e.g., "reserved", "departed")
|
||||
room_type = Column(String) # roomType attribute (e.g., "VDS", "EZR")
|
||||
room_number = Column(String, index=True) # roomNumber attribute
|
||||
num_adults = Column(Integer) # adults attribute
|
||||
rate_plan_code = Column(String) # ratePlanCode attribute
|
||||
connected_room_type = Column(String) # connectedRoomType attribute
|
||||
|
||||
# Daily sales data stored as JSON
|
||||
# Format: [
|
||||
# {"date": "2021-10-09", "revenueTotal": "13.6", "revenueOther": "13.6"},
|
||||
# {"date": "2021-10-10", "revenueTotal": "306.1", "revenueLogis": "254", ...},
|
||||
# ...
|
||||
# ]
|
||||
daily_sales = Column(JSON, nullable=True) # JSON array of daily sales
|
||||
|
||||
# Extracted total revenue for efficient querying (sum of all revenue_total in daily_sales)
|
||||
# Kept as string to preserve decimal precision
|
||||
total_revenue = Column(String, nullable=True)
|
||||
|
||||
# Metadata
|
||||
created_at = Column(DateTime(timezone=True)) # When this record was imported
|
||||
updated_at = Column(DateTime(timezone=True)) # When this record was last updated
|
||||
|
||||
# Relationships
|
||||
conversion = relationship("Conversion", back_populates="room_reservations")
|
||||
|
||||
Reference in New Issue
Block a user