Introduce a new RSVP model to manage responses for events, including status, guest count, and additional details like dietary requirements. Enforce uniqueness for each guest per event and provide functionality to update RSVP status. This will support efficient event RSVP handling and data integrity.
69 lines
2.2 KiB
Python
69 lines
2.2 KiB
Python
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"<RSVP guest_id={self.guest_id} status={self.status.value}>"
|
|
|
|
@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)
|