Fixed removing hashed_customer

This commit is contained in:
Jonas Linter
2025-12-03 12:12:37 +01:00
parent ca1f4a010b
commit 8c09094535
2 changed files with 25 additions and 35 deletions

View File

@@ -471,7 +471,6 @@ class ConversionService:
"total_daily_sales": 0, "total_daily_sales": 0,
"matched_to_reservation": 0, "matched_to_reservation": 0,
"matched_to_customer": 0, "matched_to_customer": 0,
"matched_to_hashed_customer": 0,
"unmatched": 0, "unmatched": 0,
"errors": 0, "errors": 0,
} }
@@ -1471,41 +1470,40 @@ class ConversionService:
session: AsyncSession for database queries session: AsyncSession for database queries
""" """
# Get all ConversionGuests that have ANY customer link # Collect every guest/customer pair derived from conversions.
# This includes:
# 1. Guests matched via guest-details (hashed_customer_id is not null)
# 2. Guests matched via ID-based matching (customer_id is not null via conversion)
result = await session.execute( result = await session.execute(
select(ConversionGuest).where( select(Conversion.guest_id, Conversion.customer_id).where(
ConversionGuest.hashed_customer_id.isnot(None) Conversion.guest_id.isnot(None), Conversion.customer_id.isnot(None)
) )
) )
matched_guests = result.scalars().all() guest_customer_rows = result.all()
if not matched_guests: if not guest_customer_rows:
_LOGGER.debug("Phase 3d: No matched guests to check for regularity") _LOGGER.debug("Phase 3d: No matched guests to check for regularity")
return return
# Deduplicate by guest_id to avoid recalculating when multiple conversions share the same guest.
guest_to_customer: dict[int, int] = {}
for guest_id, customer_id in guest_customer_rows:
if guest_id is None or customer_id is None:
continue
if guest_id not in guest_to_customer:
guest_to_customer[guest_id] = customer_id
elif guest_to_customer[guest_id] != customer_id:
_LOGGER.warning(
"Guest %s linked to multiple customers (%s, %s); keeping first match",
guest_id,
guest_to_customer[guest_id],
customer_id,
)
_LOGGER.debug( _LOGGER.debug(
"Phase 3d: Checking regularity for %d matched guests", len(matched_guests) "Phase 3d: Checking regularity for %d matched guests",
len(guest_to_customer),
) )
for conversion_guest in matched_guests: for guest_id, customer_id in guest_to_customer.items():
if not conversion_guest.hashed_customer_id: await self._check_if_guest_is_regular(guest_id, customer_id, session)
continue
# Get the customer ID from the hashed_customer
hashed_customer_result = await session.execute(
select(Customer).where(
Customer.id == conversion_guest.hashed_customer_id
)
)
hashed_customer = hashed_customer_result.scalar_one_or_none()
if hashed_customer and hashed_customer.id:
await self._check_if_guest_is_regular(
conversion_guest.guest_id, hashed_customer.id, session
)
async def _match_conversions_from_db_sequential( async def _match_conversions_from_db_sequential(
self, pms_reservation_ids: list[str], stats: dict[str, int] self, pms_reservation_ids: list[str], stats: dict[str, int]
@@ -1721,7 +1719,6 @@ class ConversionService:
# Guest detail matching is deferred to Phase 3b/3c # Guest detail matching is deferred to Phase 3b/3c
matched_reservation = None matched_reservation = None
matched_customer = None matched_customer = None
matched_hashed_customer = None
if conversion.advertising_campagne: if conversion.advertising_campagne:
matched_reservation = await self._match_by_advertising( matched_reservation = await self._match_by_advertising(
@@ -1755,10 +1752,6 @@ class ConversionService:
conversion.directly_attributable = True conversion.directly_attributable = True
conversion.guest_matched = False conversion.guest_matched = False
# Update conversion_guest with hashed_customer reference if matched
if conversion_guest and matched_hashed_customer:
conversion_guest.hashed_customer_id = matched_hashed_customer.id
conversion.updated_at = datetime.now() conversion.updated_at = datetime.now()
# Update stats if provided # Update stats if provided
@@ -1767,8 +1760,6 @@ class ConversionService:
stats["matched_to_reservation"] += 1 stats["matched_to_reservation"] += 1
elif matched_customer: elif matched_customer:
stats["matched_to_customer"] += 1 stats["matched_to_customer"] += 1
elif matched_hashed_customer:
stats["matched_to_hashed_customer"] += 1
else: else:
stats["unmatched"] += 1 stats["unmatched"] += 1

View File

@@ -562,7 +562,6 @@ class ConversionData(BaseModel):
# Foreign key references (nullable - matched after creation) # Foreign key references (nullable - matched after creation)
reservation_id: int | None = Field(None, gt=0) reservation_id: int | None = Field(None, gt=0)
customer_id: int | None = Field(None, gt=0) customer_id: int | None = Field(None, gt=0)
hashed_customer_id: int | None = Field(None, gt=0)
# Required reservation metadata from PMS # Required reservation metadata from PMS
hotel_id: str = Field(..., min_length=1, max_length=50) hotel_id: str = Field(..., min_length=1, max_length=50)
@@ -591,7 +590,7 @@ class ConversionData(BaseModel):
@field_validator( @field_validator(
"pms_reservation_id", "guest_id", "reservation_id", "customer_id", "pms_reservation_id", "guest_id", "reservation_id", "customer_id",
"hashed_customer_id", mode="before" mode="before"
) )
@classmethod @classmethod
def convert_int_fields(cls, v: Any) -> int | None: def convert_int_fields(cls, v: Any) -> int | None: