118 lines
4.3 KiB
Python

from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException
from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session
from app import models, schemas
from app.core.deps import get_current_active_user, get_db
from app.services.invoice import invoice_service
from app.services.customer import customer_service
from app.services.pdf_generator import pdf_generator
router = APIRouter()
@router.get("/", response_model=List[schemas.Invoice])
def read_invoices(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
current_user: models.User = Depends(get_current_active_user),
) -> Any:
invoices = invoice_service.get_multi_by_user(db, user_id=current_user.id, skip=skip, limit=limit)
return invoices
@router.post("/", response_model=schemas.Invoice)
def create_invoice(
*,
db: Session = Depends(get_db),
invoice_in: schemas.InvoiceCreate,
current_user: models.User = Depends(get_current_active_user),
) -> Any:
customer = customer_service.get(db=db, customer_id=invoice_in.customer_id)
if not customer or customer.user_id != current_user.id:
raise HTTPException(status_code=400, detail="Customer not found or not owned by user")
existing_invoice = invoice_service.get_by_number(db=db, invoice_number=invoice_in.invoice_number)
if existing_invoice:
raise HTTPException(status_code=400, detail="Invoice number already exists")
invoice = invoice_service.create(db=db, obj_in=invoice_in, user_id=current_user.id)
return invoice
@router.put("/{invoice_id}", response_model=schemas.Invoice)
def update_invoice(
*,
db: Session = Depends(get_db),
invoice_id: int,
invoice_in: schemas.InvoiceUpdate,
current_user: models.User = Depends(get_current_active_user),
) -> Any:
invoice = invoice_service.get(db=db, invoice_id=invoice_id)
if not invoice:
raise HTTPException(status_code=404, detail="Invoice not found")
if invoice.user_id != current_user.id:
raise HTTPException(status_code=400, detail="Not enough permissions")
if invoice_in.customer_id:
customer = customer_service.get(db=db, customer_id=invoice_in.customer_id)
if not customer or customer.user_id != current_user.id:
raise HTTPException(status_code=400, detail="Customer not found or not owned by user")
invoice = invoice_service.update(db=db, db_obj=invoice, obj_in=invoice_in)
return invoice
@router.get("/{invoice_id}", response_model=schemas.Invoice)
def read_invoice(
*,
db: Session = Depends(get_db),
invoice_id: int,
current_user: models.User = Depends(get_current_active_user),
) -> Any:
invoice = invoice_service.get(db=db, invoice_id=invoice_id)
if not invoice:
raise HTTPException(status_code=404, detail="Invoice not found")
if invoice.user_id != current_user.id:
raise HTTPException(status_code=400, detail="Not enough permissions")
return invoice
@router.delete("/{invoice_id}", response_model=schemas.Invoice)
def delete_invoice(
*,
db: Session = Depends(get_db),
invoice_id: int,
current_user: models.User = Depends(get_current_active_user),
) -> Any:
invoice = invoice_service.get(db=db, invoice_id=invoice_id)
if not invoice:
raise HTTPException(status_code=404, detail="Invoice not found")
if invoice.user_id != current_user.id:
raise HTTPException(status_code=400, detail="Not enough permissions")
invoice = invoice_service.remove(db=db, invoice_id=invoice_id)
return invoice
@router.get("/{invoice_id}/pdf")
def download_invoice_pdf(
*,
db: Session = Depends(get_db),
invoice_id: int,
current_user: models.User = Depends(get_current_active_user),
) -> StreamingResponse:
invoice = invoice_service.get(db=db, invoice_id=invoice_id)
if not invoice:
raise HTTPException(status_code=404, detail="Invoice not found")
if invoice.user_id != current_user.id:
raise HTTPException(status_code=400, detail="Not enough permissions")
pdf_buffer = pdf_generator.generate_invoice_pdf(invoice)
return StreamingResponse(
iter([pdf_buffer.read()]),
media_type="application/pdf",
headers={"Content-Disposition": f"attachment; filename=invoice_{invoice.invoice_number}.pdf"}
)