""" Portfolio related models. """ from datetime import datetime from sqlalchemy import ( Column, Integer, String, Numeric, DateTime, Date, ForeignKey, Text, Enum as SQLEnum ) from sqlalchemy.orm import relationship import enum from app.core.database import Base class PortfolioType(str, enum.Enum): PENSION = "pension" GENERAL = "general" class TransactionType(str, enum.Enum): BUY = "buy" SELL = "sell" class Portfolio(Base): __tablename__ = "portfolios" id = Column(Integer, primary_key=True, index=True) user_id = Column(Integer, ForeignKey("users.id"), nullable=False) name = Column(String(100), nullable=False) portfolio_type = Column(SQLEnum(PortfolioType), default=PortfolioType.GENERAL) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) targets = relationship("Target", back_populates="portfolio", cascade="all, delete-orphan") holdings = relationship("Holding", back_populates="portfolio", cascade="all, delete-orphan") transactions = relationship("Transaction", back_populates="portfolio", cascade="all, delete-orphan") snapshots = relationship("PortfolioSnapshot", back_populates="portfolio", cascade="all, delete-orphan") class Target(Base): __tablename__ = "targets" portfolio_id = Column(Integer, ForeignKey("portfolios.id"), primary_key=True) ticker = Column(String(20), primary_key=True) target_ratio = Column(Numeric(5, 2), nullable=False) portfolio = relationship("Portfolio", back_populates="targets") class Holding(Base): __tablename__ = "holdings" portfolio_id = Column(Integer, ForeignKey("portfolios.id"), primary_key=True) ticker = Column(String(20), primary_key=True) quantity = Column(Integer, nullable=False, default=0) avg_price = Column(Numeric(12, 2), nullable=False, default=0) portfolio = relationship("Portfolio", back_populates="holdings") class Transaction(Base): __tablename__ = "transactions" id = Column(Integer, primary_key=True, index=True) portfolio_id = Column(Integer, ForeignKey("portfolios.id"), nullable=False) ticker = Column(String(20), nullable=False) tx_type = Column(SQLEnum(TransactionType), nullable=False) quantity = Column(Integer, nullable=False) price = Column(Numeric(12, 2), nullable=False) executed_at = Column(DateTime, nullable=False) memo = Column(Text, nullable=True) portfolio = relationship("Portfolio", back_populates="transactions") class PortfolioSnapshot(Base): __tablename__ = "portfolio_snapshots" id = Column(Integer, primary_key=True, index=True) portfolio_id = Column(Integer, ForeignKey("portfolios.id"), nullable=False) total_value = Column(Numeric(15, 2), nullable=False) snapshot_date = Column(Date, nullable=False) portfolio = relationship("Portfolio", back_populates="snapshots") holdings = relationship("SnapshotHolding", back_populates="snapshot", cascade="all, delete-orphan") class SnapshotHolding(Base): __tablename__ = "snapshot_holdings" snapshot_id = Column(Integer, ForeignKey("portfolio_snapshots.id"), primary_key=True) ticker = Column(String(20), primary_key=True) quantity = Column(Integer, nullable=False) price = Column(Numeric(12, 2), nullable=False) value = Column(Numeric(15, 2), nullable=False) current_ratio = Column(Numeric(5, 2), nullable=False) snapshot = relationship("PortfolioSnapshot", back_populates="holdings")