
- Set up FastAPI application with CORS support - Configure SQLite database connection - Create database models for users, clients, invoices, and line items - Set up Alembic for database migrations - Implement JWT-based authentication system - Create basic CRUD endpoints for users, clients, and invoices - Add PDF generation functionality - Implement activity logging - Update README with project information
43 lines
1.9 KiB
Python
43 lines
1.9 KiB
Python
from sqlalchemy import Column, String, Float, ForeignKey, Date, Enum, DateTime, func
|
|
from sqlalchemy.orm import relationship
|
|
import uuid
|
|
import enum
|
|
from datetime import datetime, timedelta
|
|
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):
|
|
id = Column(String, primary_key=True, index=True, default=lambda: str(uuid.uuid4()))
|
|
invoice_number = Column(String, index=True, nullable=False)
|
|
status = Column(Enum(InvoiceStatus), default=InvoiceStatus.DRAFT, nullable=False)
|
|
issued_date = Column(Date, default=datetime.utcnow().date, nullable=False)
|
|
due_date = Column(Date, default=lambda: (datetime.utcnow() + timedelta(days=30)).date(), nullable=False)
|
|
client_id = Column(String, ForeignKey("client.id", ondelete="CASCADE"), nullable=False)
|
|
user_id = Column(String, ForeignKey("user.id", ondelete="CASCADE"), nullable=False)
|
|
notes = Column(String, nullable=True)
|
|
created_at = Column(DateTime, default=func.now(), nullable=False)
|
|
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False)
|
|
|
|
# Relationships
|
|
client = relationship("Client", back_populates="invoices")
|
|
user = relationship("User", back_populates="invoices")
|
|
items = relationship("InvoiceItem", back_populates="invoice", cascade="all, delete-orphan")
|
|
|
|
|
|
class InvoiceItem(Base):
|
|
id = Column(String, primary_key=True, index=True, default=lambda: str(uuid.uuid4()))
|
|
description = Column(String, nullable=False)
|
|
quantity = Column(Float, nullable=False, default=1.0)
|
|
unit_price = Column(Float, nullable=False)
|
|
invoice_id = Column(String, ForeignKey("invoice.id", ondelete="CASCADE"), nullable=False)
|
|
|
|
# Relationships
|
|
invoice = relationship("Invoice", back_populates="items") |