Small db improvements. Still needs migration for alembic

This commit is contained in:
2025-12-02 09:45:27 +00:00
parent 6c50273f54
commit e24866d8a0
2 changed files with 35 additions and 15 deletions

View File

@@ -37,7 +37,7 @@ class ConversionService:
2. Concurrent mode: SessionMaker passed in, creates independent sessions per task
"""
def __init__(self, session: AsyncSession | SessionMaker | None = None):
def __init__(self, session: AsyncSession | SessionMaker | None = None, hotel_id: str | None = None):
"""Initialize the ConversionService.
Args:
@@ -45,11 +45,13 @@ class ConversionService:
- AsyncSession: Single session for sequential processing
- SessionMaker: Factory for creating sessions in concurrent mode
- None: Not recommended, but allowed for subclassing
hotel_id: Hotel ID for this conversion service context (from authenticated user)
"""
self.session = None
self.session_maker = None
self.supports_concurrent = False
self.hotel_id = hotel_id
# Cache for reservation and customer data within a single XML processing run
# Maps hotel_code -> list of (reservation, hashed_customer) tuples
@@ -248,8 +250,12 @@ class ConversionService:
# Process deleted reservations
for deleted_res in root.findall("Deletedreservation"):
stats["deleted_reservations"] += 1
pms_reservation_id = deleted_res.get("ID")
pms_reservation_id_str = deleted_res.get("ID")
try:
pms_reservation_id = int(pms_reservation_id_str) if pms_reservation_id_str else None
if pms_reservation_id is None:
_LOGGER.warning("Deleted reservation missing ID attribute, skipping")
continue
await self._handle_deleted_reservation(pms_reservation_id, session)
await session.commit()
except Exception as e:
@@ -552,7 +558,7 @@ class ConversionService:
await session.close()
async def _handle_deleted_reservation(
self, pms_reservation_id: str, session: AsyncSession
self, pms_reservation_id: int, session: AsyncSession
):
"""Handle deleted reservation by marking conversions as deleted or removing them.
@@ -561,13 +567,16 @@ class ConversionService:
session: AsyncSession to use for the operation
"""
# For now, we'll just log it. You could add a 'deleted' flag to the Conversion table
# or actually delete the conversion records
_LOGGER.info("Processing deleted reservation: PMS ID %s", pms_reservation_id)
if not self.hotel_id:
_LOGGER.error("Cannot delete reservation: hotel_id not set in ConversionService")
return
# Option 1: Delete conversion records
_LOGGER.info("Processing deleted reservation: Hotel %s, PMS ID %s", self.hotel_id, pms_reservation_id)
# Delete conversion records for this hotel + pms_reservation_id
result = await session.execute(
select(Conversion).where(
Conversion.hotel_id == self.hotel_id,
Conversion.pms_reservation_id == pms_reservation_id
)
)
@@ -578,8 +587,9 @@ class ConversionService:
if conversions:
_LOGGER.info(
"Deleted %d conversion records for PMS reservation %s",
"Deleted %d conversion records for hotel %s, PMS reservation %s",
len(conversions),
self.hotel_id,
pms_reservation_id,
)
@@ -673,6 +683,7 @@ class ConversionService:
# Check if conversion already exists (upsert logic)
existing_result = await session.execute(
select(Conversion).where(
Conversion.hotel_id == hotel_id,
Conversion.pms_reservation_id == pms_reservation_id
)
)
@@ -1498,7 +1509,7 @@ class ConversionService:
async def _match_conversion_using_db_data(
self,
pms_reservation_id: str,
pms_reservation_id: int,
session: AsyncSession | None = None,
stats: dict[str, int] | None = None,
) -> None:
@@ -1521,10 +1532,17 @@ class ConversionService:
if session is None:
session = self.session
if not self.hotel_id:
_LOGGER.error("Cannot match conversion: hotel_id not set in ConversionService")
return
# Get the conversion from the database with related data
result = await session.execute(
select(Conversion)
.where(Conversion.pms_reservation_id == pms_reservation_id)
.where(
Conversion.hotel_id == self.hotel_id,
Conversion.pms_reservation_id == pms_reservation_id
)
.options(selectinload(Conversion.guest), selectinload(Conversion.conversion_rooms))
)
conversion = result.scalar_one_or_none()

View File

@@ -383,8 +383,8 @@ class ConversionGuest(Base):
__tablename__ = "conversion_guests"
# Natural keys from PMS - composite primary key
hotel_id = Column(String, nullable=False, primary_key=True, index=True)
guest_id = Column(String, nullable=False, primary_key=True, index=True)
hotel_id = Column(String(50), ForeignKey("hotels.hotel_id", ondelete="CASCADE"), nullable=False, primary_key=True, index=True)
guest_id = Column(Integer, nullable=False, primary_key=True, index=True)
# Unhashed guest information (for reference/transition period)
guest_first_name = Column(String)
@@ -578,9 +578,10 @@ class Conversion(Base):
)
# Reservation metadata from XML
hotel_id = Column(String, index=True) # hotelID attribute
guest_id = Column(String, nullable=True, index=True) # PMS guest ID, FK to conversion_guests
pms_reservation_id = Column(String, index=True) # id attribute from reservation
hotel_id = Column(String(50), ForeignKey("hotels.hotel_id", ondelete="CASCADE"), nullable=False, index=True) # hotelID attribute
pms_reservation_id = Column(Integer, nullable=False, index=True) # id attribute from reservation
guest_id = Column(Integer, nullable=True, index=True) # PMS guest ID, FK to conversion_guests
reservation_number = Column(String) # number attribute
reservation_date = Column(Date) # date attribute (when reservation was made)
creation_time = Column(DateTime(timezone=True)) # creationTime attribute
@@ -616,6 +617,7 @@ class Conversion(Base):
["conversion_guests.hotel_id", "conversion_guests.guest_id"],
ondelete="SET NULL",
),
UniqueConstraint("hotel_id", "pms_reservation_id", name="uq_conversion_hotel_reservation"),
)
# Relationships