from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session, joinedload from db import get_session from models import Invoice from schemas import InvoiceDetail, InvoiceIn, InvoiceOut router = APIRouter() @router.get("", response_model=list[InvoiceOut]) def list_invoices( status: str | None = None, customer_id: int | None = None, session: Session = Depends(get_session), ): query = session.query(Invoice).order_by(Invoice.issued_at.desc()) if status: query = query.filter(Invoice.status == status) if customer_id: query = query.filter(Invoice.customer_id == customer_id) return query.all() @router.post("", response_model=InvoiceOut, status_code=201) def create_invoice(payload: InvoiceIn, session: Session = Depends(get_session)): invoice = Invoice(**payload.model_dump()) session.add(invoice) session.commit() session.refresh(invoice) return invoice @router.get("/{invoice_id}", response_model=InvoiceDetail) def get_invoice(invoice_id: int, session: Session = Depends(get_session)): invoice = ( session.query(Invoice) .options( joinedload(Invoice.customer), joinedload(Invoice.line_items), joinedload(Invoice.payments), ) .filter(Invoice.id == invoice_id) .first() ) if not invoice: raise HTTPException(404, "invoice not found") return invoice @router.put("/{invoice_id}", response_model=InvoiceOut) def update_invoice( invoice_id: int, payload: InvoiceIn, session: Session = Depends(get_session) ): invoice = session.get(Invoice, invoice_id) if not invoice: raise HTTPException(404, "invoice not found") for k, v in payload.model_dump().items(): setattr(invoice, k, v) session.commit() session.refresh(invoice) return invoice @router.delete("/{invoice_id}", status_code=204) def delete_invoice(invoice_id: int, session: Session = Depends(get_session)): invoice = session.get(Invoice, invoice_id) if not invoice: raise HTTPException(404, "invoice not found") session.delete(invoice) session.commit()