"""Participant business logic utilities.""" from typing import TYPE_CHECKING if TYPE_CHECKING: from src.models import Participant def get_active_participants(exchange_id: int) -> list["Participant"]: """Get all active (non-withdrawn) participants for an exchange. Args: exchange_id: ID of the exchange Returns: List of active participants, ordered by name """ from src.models.participant import Participant result: list[Participant] = ( Participant.query.filter( Participant.exchange_id == exchange_id, Participant.withdrawn_at.is_(None) ) .order_by(Participant.name) .all() ) return result def is_withdrawn(participant: "Participant") -> bool: """Check if participant has withdrawn. Args: participant: The participant to check Returns: True if withdrawn, False otherwise """ return participant.withdrawn_at is not None def can_update_profile(participant: "Participant") -> bool: """Check if participant can update their profile. Profile updates are allowed until matching occurs. Args: participant: The participant to check Returns: True if profile updates are allowed, False otherwise """ exchange = participant.exchange allowed_states = ["draft", "registration_open", "registration_closed"] return exchange.state in allowed_states def can_withdraw(participant: "Participant") -> bool: """Check if participant can withdraw from the exchange. Withdrawals are only allowed before registration closes. After that, admin intervention is required. Args: participant: The participant to check Returns: True if withdrawal is allowed, False otherwise """ # Already withdrawn if participant.withdrawn_at is not None: return False exchange = participant.exchange allowed_states = ["draft", "registration_open"] return exchange.state in allowed_states