from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from db import get_session from models import Invoice, Payment from schemas import PaymentIn, PaymentOut router = APIRouter() @router.get("", response_model=list[PaymentOut]) def list_payments( invoice_id: int | None = None, session: Session = Depends(get_session) ): query = session.query(Payment).order_by(Payment.paid_at.desc()) if invoice_id: query = query.filter(Payment.invoice_id == invoice_id) return query.all() @router.post("/invoices/{invoice_id}", response_model=PaymentOut, status_code=201) def record_payment( invoice_id: int, payload: PaymentIn, session: Session = Depends(get_session) ): invoice = session.get(Invoice, invoice_id) if not invoice: raise HTTPException(404, "invoice not found") payment = Payment(invoice_id=invoice_id, **payload.model_dump()) session.add(payment) total_paid = sum( (p.amount for p in invoice.payments), start=payment.amount ) total_owed = sum((li.unit_price * li.quantity for li in invoice.line_items), start=0) if total_owed > 0 and total_paid >= total_owed: invoice.status = "paid" session.commit() session.refresh(payment) return payment @router.delete("/{payment_id}", status_code=204) def delete_payment(payment_id: int, session: Session = Depends(get_session)): payment = session.get(Payment, payment_id) if not payment: raise HTTPException(404, "payment not found") session.delete(payment) session.commit()