78 lines
2.8 KiB
Python
78 lines
2.8 KiB
Python
|
|
"""
|
||
|
|
Collection models for user card collections
|
||
|
|
"""
|
||
|
|
|
||
|
|
from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, Text, Float, JSON
|
||
|
|
from sqlalchemy.orm import relationship
|
||
|
|
from sqlalchemy.sql import func
|
||
|
|
from app.database import Base
|
||
|
|
|
||
|
|
|
||
|
|
class Collection(Base):
|
||
|
|
__tablename__ = "collections"
|
||
|
|
|
||
|
|
id = Column(Integer, primary_key=True, index=True)
|
||
|
|
name = Column(String, nullable=False)
|
||
|
|
description = Column(Text)
|
||
|
|
is_public = Column(Boolean, default=False)
|
||
|
|
owner_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
||
|
|
|
||
|
|
# Metadata
|
||
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||
|
|
|
||
|
|
# Relationships
|
||
|
|
owner = relationship("User", back_populates="collections")
|
||
|
|
collection_cards = relationship("CollectionCard", back_populates="collection", cascade="all, delete-orphan")
|
||
|
|
|
||
|
|
@property
|
||
|
|
def total_cards(self):
|
||
|
|
"""Calculate total number of cards in collection"""
|
||
|
|
return sum(cc.quantity for cc in self.collection_cards)
|
||
|
|
|
||
|
|
@property
|
||
|
|
def total_value(self):
|
||
|
|
"""Calculate total estimated value of collection"""
|
||
|
|
total = 0
|
||
|
|
for cc in self.collection_cards:
|
||
|
|
if cc.card.current_price:
|
||
|
|
total += cc.card.current_price * cc.quantity
|
||
|
|
return total
|
||
|
|
|
||
|
|
def __repr__(self):
|
||
|
|
return f"<Collection(id={self.id}, name='{self.name}', owner_id={self.owner_id})>"
|
||
|
|
|
||
|
|
|
||
|
|
class CollectionCard(Base):
|
||
|
|
__tablename__ = "collection_cards"
|
||
|
|
|
||
|
|
id = Column(Integer, primary_key=True, index=True)
|
||
|
|
collection_id = Column(Integer, ForeignKey("collections.id"), nullable=False)
|
||
|
|
card_id = Column(Integer, ForeignKey("cards.id"), nullable=False)
|
||
|
|
|
||
|
|
# Ownership details
|
||
|
|
quantity = Column(Integer, default=1)
|
||
|
|
condition = Column(String, default="NM") # NM, LP, MP, HP, DMG
|
||
|
|
foil = Column(Boolean, default=False)
|
||
|
|
language = Column(String, default="English")
|
||
|
|
|
||
|
|
# Storage and notes
|
||
|
|
location = Column(String) # Binder 1, Page 5, etc.
|
||
|
|
notes = Column(Text)
|
||
|
|
purchase_price = Column(Float) # What user paid for it
|
||
|
|
purchase_date = Column(DateTime)
|
||
|
|
|
||
|
|
# User's card images
|
||
|
|
user_images = Column(JSON) # Array of image URLs/paths for this specific card copy
|
||
|
|
condition_notes = Column(Text) # Detailed condition description
|
||
|
|
|
||
|
|
# Metadata
|
||
|
|
added_at = Column(DateTime(timezone=True), server_default=func.now())
|
||
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||
|
|
|
||
|
|
# Relationships
|
||
|
|
collection = relationship("Collection", back_populates="collection_cards")
|
||
|
|
card = relationship("Card", back_populates="collection_cards")
|
||
|
|
|
||
|
|
def __repr__(self):
|
||
|
|
return f"<CollectionCard(collection_id={self.collection_id}, card_id={self.card_id}, quantity={self.quantity})>"
|