from datetime import datetime, timezone from enum import Enum from sqlalchemy import ( Column, String, ForeignKey, UniqueConstraint, Integer, DateTime, Enum as SQLEnum ) from sqlalchemy.dialects.postgresql import UUID, JSONB from sqlalchemy.orm import relationship from .base import Base, TimestampMixin, UUIDMixin class RSVPStatus(str, Enum): ATTENDING = "attending" NOT_ATTENDING = "not_attending" MAYBE = "maybe" class RSVP(Base, UUIDMixin, TimestampMixin): __tablename__ = 'rsvps' # Foreign Keys event_id = Column(UUID(as_uuid=True), ForeignKey('events.id'), nullable=False) guest_id = Column(UUID(as_uuid=True), ForeignKey('guests.id'), nullable=False) # RSVP Details status = Column(SQLEnum(RSVPStatus), nullable=False) number_of_guests = Column(Integer, default=1, nullable=False) response_message = Column(String) # Additional Information dietary_requirements = Column(String) additional_info = Column(JSONB) # Tracking response_date = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False) last_updated = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) # Relationships event = relationship("Event", back_populates="rsvps") guest = relationship("Guest", back_populates="rsvp") # Ensure one RSVP per guest per event __table_args__ = ( UniqueConstraint('event_id', 'guest_id', name='uq_event_guest_rsvp'), ) def __repr__(self): return f"" @property def is_attending(self) -> bool: """Check if the RSVP indicates attendance""" return self.status == RSVPStatus.ATTENDING def update_status(self, new_status: RSVPStatus, guests_count: int = None): """ Update RSVP status and optionally number of guests """ self.status = new_status if guests_count is not None: self.number_of_guests = max(1, guests_count) # Ensure at least 1 guest self.last_updated = datetime.now(timezone.utc)