from sqlalchemy import Column, Integer, String, DateTime, Float, ForeignKey, Text, Boolean from sqlalchemy.sql import func from sqlalchemy.orm import relationship from app.core.database import Base class Expense(Base): __tablename__ = "expenses" id = Column(Integer, primary_key=True, index=True) trip_id = Column(Integer, ForeignKey("trips.id"), nullable=False) description = Column(String(255), nullable=False) amount = Column(Float, nullable=False) currency_code = Column(String(3), nullable=False) exchange_rate = Column(Float, nullable=False, default=1.0) # Rate to trip currency at time of expense category = Column(String(50), nullable=True) receipt_url = Column(Text, nullable=True) paid_by_id = Column(Integer, ForeignKey("participants.id"), nullable=False) date_incurred = Column(DateTime(timezone=True), nullable=False, server_default=func.now()) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) # Relationships trip = relationship("Trip", back_populates="expenses") paid_by = relationship("Participant", foreign_keys=[paid_by_id], back_populates="expenses_paid") splits = relationship("ExpenseSplit", back_populates="expense", cascade="all, delete-orphan") class ExpenseSplit(Base): __tablename__ = "expense_splits" id = Column(Integer, primary_key=True, index=True) expense_id = Column(Integer, ForeignKey("expenses.id"), nullable=False) participant_id = Column(Integer, ForeignKey("participants.id"), nullable=False) percentage = Column(Float, nullable=False) # Percentage of expense this participant owes amount = Column(Float, nullable=False) # Actual amount owed in expense currency is_settled = Column(Boolean, default=False) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) # Relationships expense = relationship("Expense", back_populates="splits") participant = relationship("Participant", back_populates="expense_splits")