Add RSVP model with status tracking and guest constraints
All checks were successful
Build and Push Docker Images / changes (push) Successful in 6s
Build and Push Docker Images / build-backend (push) Successful in 50s
Build and Push Docker Images / build-frontend (push) Has been skipped

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.
This commit is contained in:
2025-02-27 18:45:08 +01:00
parent 1d1452f716
commit e60a016ab1

121
backend/app/models/gift.py Normal file
View File

@@ -0,0 +1,121 @@
from datetime import datetime, timezone
from enum import Enum
from sqlalchemy import (
Column, String, Boolean, ForeignKey, UniqueConstraint,
Integer, DateTime, Enum as SQLEnum, Table, Float
)
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID, JSONB
from .base import Base, TimestampMixin, UUIDMixin
class GiftStatus(str, Enum):
AVAILABLE = "available"
RESERVED = "reserved"
PURCHASED = "purchased"
RECEIVED = "received"
REMOVED = "removed"
class GiftPriority(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
MUST_HAVE = "must_have"
class GiftItem(Base, UUIDMixin, TimestampMixin):
__tablename__ = 'gift_items'
# Foreign Keys
event_id = Column(UUID(as_uuid=True), ForeignKey('events.id'), nullable=False)
added_by = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False)
category_id = Column(UUID(as_uuid=True), ForeignKey('gift_categories.id'))
# Gift Details
name = Column(String, nullable=False)
description = Column(String)
price = Column(Float)
currency = Column(String, default='USD')
quantity_requested = Column(Integer, default=1)
quantity_received = Column(Integer, default=0)
# Status and Priority
status = Column(SQLEnum(GiftStatus), nullable=False, default=GiftStatus.AVAILABLE)
priority = Column(SQLEnum(GiftPriority), default=GiftPriority.MEDIUM)
# Purchase Information
purchase_url = Column(String)
store_name = Column(String)
brand = Column(String)
model = Column(String)
# Display
image_url = Column(String)
display_order = Column(Integer)
is_visible = Column(Boolean, default=True)
# Additional Information
notes = Column(String)
custom_fields = Column(JSONB)
# Tracking
last_status_change = Column(DateTime(timezone=True))
# Relationships
event = relationship("Event", back_populates="gifts")
added_by_user = relationship("User", foreign_keys=[added_by])
category = relationship("GiftCategory", back_populates="gifts")
reserved_by = relationship("Guest",
secondary="guest_gifts",
back_populates="gifts")
purchase_history = relationship("GiftPurchase",
back_populates="gift_item",
order_by="desc(GiftPurchase.purchased_at)")
def __repr__(self):
return f"<GiftItem {self.name} ({self.status.value})>"
def update_status(self, new_status: GiftStatus):
"""Update gift status and record the change time"""
self.status = new_status
self.last_status_change = datetime.now(timezone.utc)
@property
def remaining_quantity(self) -> int:
"""Calculate remaining quantity needed"""
return max(0, self.quantity_requested - self.quantity_received)
@property
def is_fully_received(self) -> bool:
"""Check if all requested quantities have been received"""
return self.quantity_received >= self.quantity_requested
@property
def formatted_price(self) -> str:
"""Return formatted price with currency"""
if self.price is None:
return "Price not set"
return f"{self.price:.2f} {self.currency}"
# Association table for tracking gift purchases
class GiftPurchase(Base, UUIDMixin):
__tablename__ = 'gift_purchases'
gift_id = Column(UUID(as_uuid=True), ForeignKey('gift_items.id'), nullable=False)
guest_id = Column(UUID(as_uuid=True), ForeignKey('guests.id'), nullable=False)
quantity = Column(Integer, default=1, nullable=False)
purchased_at = Column(DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
nullable=False)
purchase_price = Column(Float)
purchase_currency = Column(String)
notes = Column(String)
# Relationships
gift_item = relationship("GiftItem", back_populates="purchase_history")
guest = relationship("Guest")
def __repr__(self):
return f"<GiftPurchase gift_id={self.gift_id} guest_id={self.guest_id}>"