from enum import Enum from typing import Optional import pendulum from pydantic import BaseModel, ConfigDict, Field, field_validator from pydantic_extra_types.pendulum_dt import DateTime class User(BaseModel): login: str password: str = Field(repr=False) club_id: Optional[str] = Field(default=None) class BookingOpening(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True) days_before: Optional[int] = Field(default=7, alias="daysBefore") opening_time: Optional[str] = Field(alias="time", default=None, repr=False) time_after_booking: Optional[str] = Field( alias="timeAfterBookingTime", default=None, repr=False ) def __repr__(self): base = super().__repr__() time = f", time: {self.time})" if self.time else "" time_after_booking = ( f", time_after_booking_time: {self.time_after_booking_time})" if self.time_after_booking_time else "" ) return base.removesuffix(")") + time + time_after_booking @property def time(self): return pendulum.parse(self.opening_time).time() @property def time_after_booking_time(self): return ( pendulum.parse(self.time_after_booking).time() if self.time_after_booking else None ) class TotalBookings(BaseModel): peak_hours: int | str = Field(alias="peakHours") off_peak_hours: int | str = Field(alias="offPeakHours") class Court(BaseModel): id: int name: str number: int is_indoor: Optional[bool] = Field(alias="isIndoor") class Sport(BaseModel): name: str id: int duration: int price: int players: int courts: list[Court] class Url(BaseModel): name: str path: str payload_template: Optional[str] = Field(default=None, alias="payloadTemplate") class BookingPlatform(BaseModel): id: str club_id: int = Field(alias="clubId") url: str hours_before_cancellation: int = Field(alias="hoursBeforeCancellation") booking_opening: BookingOpening = Field(alias="bookingOpening") total_bookings: TotalBookings = Field(alias="totalBookings") sports: list[Sport] urls: dict[str, Url] class Club(BaseModel): id: str name: str url: str booking_platform: BookingPlatform = Field(alias="bookingPlatform") class PlatformDefinition(BaseModel): id: str name: str url: str urls: list[Url] class BookingFilter(BaseModel): date: DateTime sport_name: str @field_validator("sport_name", mode="before") @classmethod def to_lower_case(cls, d: str) -> str: return d.lower() class Booking(BaseModel): id: int booking_date: DateTime = Field(alias="dateResa") start_time: DateTime = Field(alias="startTime") sport: str court: str game_creation: Optional[int] = Field(default=None, alias="creaPartie") game_creation_limit: Optional[DateTime] = Field( default=None, alias="limitCreaPartie" ) cancel: Optional[bool] = Field(default=True) block_player_replacement: Optional[int] = Field( default=None, alias="bloquerRemplacementJoueur" ) can_remove_parteners: bool = Field(default=True, alias="canRemovePartners") end_time: Optional[DateTime] = Field(default=None, alias="endTime") day_fr: Optional[str] = Field(default=None, alias="dayFr") live_xperience_code: Optional[str] = Field(default=None, alias="codeLiveXperience") spartime_qr_code: Optional[str] = Field(default=None, alias="qrCodeSpartime") remaining_places: int = Field(default=3, alias="remainingPlaces") is_captain: bool = Field(default=True, alias="isCaptain") dt_start: Optional[DateTime] = Field(default=None, alias="dtStart") credit_card_guaranty: Optional[str] = Field(default=None, alias="garantieCb") certificate_validity_duration: Optional[int] = Field( alias="dureeValidCertif", default=None ) charge_id: Optional[str] = Field(default=None, alias="chargeId") partners: Optional[list] = Field(default=[]) player_status: Optional[int] = Field(default=None, alias="playerStatus") products: Optional[list] = Field(default=[]) @field_validator("booking_date", mode="before") @classmethod def validate_date(cls, d: str) -> DateTime: return pendulum.from_format( d, "DD/MM/YYYY", tz=pendulum.timezone("Europe/Paris") ) @field_validator("start_time", "end_time", mode="before") @classmethod def validate_time(cls, t: str) -> DateTime: return pendulum.from_format(t, "HH:mm", tz=pendulum.timezone("Europe/Paris")) @field_validator("game_creation_limit", mode="before") @classmethod def validate_datetime_add_tz(cls, dt: str) -> DateTime: return pendulum.parse(dt, tz=pendulum.timezone("Europe/Paris")) @field_validator("dt_start", mode="before") @classmethod def validate_datetime(cls, dt: str) -> DateTime: return pendulum.parse(dt) @field_validator("sport", mode="before") @classmethod def to_lower_case(cls, d: str) -> str: return d.lower() class Action(Enum): BOOK = "book" CANCEL = "cancel"