import enum from sqlalchemy import Column, String, Text, ForeignKey, Integer, Enum, Float, Date, Boolean from sqlalchemy.orm import relationship from app.db.base_class import Base class InvoiceStatus(str, enum.Enum): DRAFT = "draft" SENT = "sent" PAID = "paid" OVERDUE = "overdue" CANCELLED = "cancelled" class Invoice(Base): invoice_number = Column(String, index=True, nullable=False) status = Column(Enum(InvoiceStatus), default=InvoiceStatus.DRAFT) issue_date = Column(Date, nullable=False) due_date = Column(Date, nullable=False) subtotal = Column(Float(precision=2), nullable=False) tax_rate = Column(Float(precision=2), default=0.0) tax_amount = Column(Float(precision=2), default=0.0) discount = Column(Float(precision=2), default=0.0) total = Column(Float(precision=2), nullable=False) notes = Column(Text) terms = Column(Text) is_recurring = Column(Boolean, default=False) recurring_interval = Column(String) # Foreign keys client_id = Column(Integer, ForeignKey("client.id", ondelete="CASCADE")) organization_id = Column(Integer, ForeignKey("organization.id", ondelete="CASCADE")) created_by_id = Column(Integer, ForeignKey("user.id", ondelete="SET NULL"), nullable=True) # Relationships items = relationship("InvoiceItem", back_populates="invoice", cascade="all, delete-orphan") client = relationship("Client", back_populates="invoices") organization = relationship("Organization", back_populates="invoices") created_by = relationship("User", back_populates="invoices") class InvoiceItem(Base): description = Column(String, nullable=False) quantity = Column(Float(precision=2), nullable=False) unit_price = Column(Float(precision=2), nullable=False) amount = Column(Float(precision=2), nullable=False) # Foreign key invoice_id = Column(Integer, ForeignKey("invoice.id", ondelete="CASCADE")) # Relationship invoice = relationship("Invoice", back_populates="items")