From 46fabc38a40f113e3e23a372b07e31e306b1dc79 Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Thu, 27 Feb 2025 19:08:48 +0100 Subject: [PATCH] Add EventMedia and GiftCategory models Introduce EventMedia for managing media files linked to events, including file metadata, purpose, and relationships. Add GiftCategory to categorize gifts, featuring unique constraints, display options, and utility methods for handling related gifts. --- backend/app/models/event_media.py | 68 +++++++++++++++++++++++++++++++ backend/app/models/gift.py | 60 ++++++++++++++++++++++++++- 2 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 backend/app/models/event_media.py diff --git a/backend/app/models/event_media.py b/backend/app/models/event_media.py new file mode 100644 index 0000000..f3b88ce --- /dev/null +++ b/backend/app/models/event_media.py @@ -0,0 +1,68 @@ +from enum import Enum +from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, JSON, Enum as SQLEnum +from sqlalchemy.dialects.postgresql import UUID +from sqlalchemy.orm import relationship +from .base import Base, TimestampMixin, UUIDMixin + + +class MediaType(str, Enum): + IMAGE = "image" + VIDEO = "video" + DOCUMENT = "document" + + +class MediaPurpose(str, Enum): + BANNER = "banner" + GALLERY = "gallery" + ATTACHMENT = "attachment" + + +class EventMedia(Base, UUIDMixin, TimestampMixin): + __tablename__ = 'event_media' + + # Foreign Keys + event_id = Column(UUID(as_uuid=True), ForeignKey('events.id'), nullable=False) + uploaded_by = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False) + + # File Information + file_path = Column(String, nullable=False) + original_filename = Column(String, nullable=False) + media_type = Column(SQLEnum(MediaType), nullable=False) + content_type = Column(String, nullable=False) + file_size = Column(Integer, nullable=False) + + # Organization + purpose = Column(SQLEnum(MediaPurpose), nullable=False) + is_public = Column(Boolean, default=True, nullable=False) + display_order = Column(Integer, default=0) + title = Column(String) + description = Column(String) + + # Additional Metadata + metadata = Column(JSON, default=dict) + + # Relationships + event = relationship("Event", back_populates="media") + uploader = relationship("User", foreign_keys=[uploaded_by]) + + def __repr__(self): + return f"" + + @property + def is_image(self): + return self.media_type == MediaType.IMAGE + + @property + def is_video(self): + return self.media_type == MediaType.VIDEO + + @property + def is_document(self): + return self.media_type == MediaType.DOCUMENT + + @property + def url(self): + """Generate the URL for the media file""" + # This should be implemented based on your storage solution + # Example: return f"/media/{self.file_path}" + pass \ No newline at end of file diff --git a/backend/app/models/gift.py b/backend/app/models/gift.py index 7cf2f59..b1f5307 100644 --- a/backend/app/models/gift.py +++ b/backend/app/models/gift.py @@ -118,4 +118,62 @@ class GiftPurchase(Base, UUIDMixin): guest = relationship("Guest") def __repr__(self): - return f"" \ No newline at end of file + return f"" + + +class GiftCategory(Base, UUIDMixin, TimestampMixin): + __tablename__ = 'gift_categories' + + # Foreign Keys + event_id = Column(UUID(as_uuid=True), ForeignKey('events.id'), nullable=False) + created_by = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False) + + # Category Details + name = Column(String, nullable=False) + description = Column(String) + + # Display + icon = Column(String) # Icon identifier or URL + color = Column(String) # Color code (hex/rgb) + display_order = Column(Integer, default=0) + is_visible = Column(Boolean, default=True) + + # Additional Settings + custom_fields = Column(JSONB) + + # Relationships + event = relationship("Event", back_populates="gift_categories") + gifts = relationship("GiftItem", + back_populates="category", + order_by="GiftItem.display_order") + created_by_user = relationship("User", foreign_keys=[created_by]) + + # Ensure unique category names within an event + __table_args__ = ( + UniqueConstraint('event_id', 'name', name='uq_event_category_name'), + ) + + def __repr__(self): + return f"" + + @property + def total_gifts(self) -> int: + """Get total number of gifts in category""" + return len(self.gifts) + + @property + def available_gifts(self) -> int: + """Get number of available gifts in category""" + return sum(1 for gift in self.gifts + if gift.status == 'available' and gift.is_visible) + + def reorder_gifts(self, gift_ids: list[UUID]) -> None: + """ + Reorder gifts within the category + Args: + gift_ids: List of gift IDs in desired order + """ + gift_order = {gift_id: idx for idx, gift_id in enumerate(gift_ids)} + for gift in self.gifts: + if gift.id in gift_order: + gift.display_order = gift_order[gift.id]