"""CRUD de documentos fiscais confirmados.""" from __future__ import annotations from fastapi import APIRouter, Form, Query, Request from starlette.responses import RedirectResponse from .. import auth from .. import database as db from ..dates import resolve_purchase_date from ..storage import money from ..templating import flash, render router = APIRouter() def _parse_money(value: str) -> float | None: text = (value or "").strip().replace("R$", "").replace(" ", "") if not text: return None if "," in text and "." in text: text = text.replace(".", "").replace(",", ".") elif "," in text: text = text.replace(",", ".") try: return round(float(text), 2) except ValueError: return None @router.get("/documents") def list_documents( request: Request, start: str = Query(""), end: str = Query(""), supplier: str = Query(""), ): with db.session() as conn: rows = [dict(r) for r in db.list_fiscal(conn, start=start or None, end=end or None, supplier=supplier or None)] total = sum(r["total_paid"] for r in rows) return render( request, "documents_list.html", rows=rows, total=total, filters={"start": start, "end": end, "supplier": supplier}, money=money, ) @router.get("/documents/new") def new_form(request: Request): return render(request, "document_form.html", doc=None, mode="new") @router.post("/documents/new") def create_document( request: Request, csrf_token: str = Form(""), purchase_date: str = Form(""), supplier_name: str = Form(""), total_paid: str = Form(""), ): if not auth.check_csrf(request, csrf_token): flash(request, "Sessão expirada.", "error") return RedirectResponse("/documents/new", status_code=303) total = _parse_money(total_paid) supplier = supplier_name.strip() if not supplier or total is None: flash(request, "Informe fornecedor e valor válidos.", "error") return RedirectResponse("/documents/new", status_code=303) with db.session() as conn: db.create_fiscal( conn, purchase_date=resolve_purchase_date(purchase_date), supplier_name=supplier, total_paid=total, ) flash(request, "Documento lançado.", "success") return RedirectResponse("/documents", status_code=303) @router.get("/documents/{doc_id}/edit") def edit_form(request: Request, doc_id: int): with db.session() as conn: doc = db.get_fiscal(conn, doc_id) if doc is None: flash(request, "Documento não encontrado.", "error") return RedirectResponse("/documents", status_code=303) return render(request, "document_form.html", doc=dict(doc), mode="edit") @router.post("/documents/{doc_id}/edit") def update_document( request: Request, doc_id: int, csrf_token: str = Form(""), purchase_date: str = Form(""), supplier_name: str = Form(""), total_paid: str = Form(""), ): if not auth.check_csrf(request, csrf_token): flash(request, "Sessão expirada.", "error") return RedirectResponse(f"/documents/{doc_id}/edit", status_code=303) total = _parse_money(total_paid) supplier = supplier_name.strip() if not supplier or total is None: flash(request, "Informe fornecedor e valor válidos.", "error") return RedirectResponse(f"/documents/{doc_id}/edit", status_code=303) with db.session() as conn: if db.get_fiscal(conn, doc_id) is None: flash(request, "Documento não encontrado.", "error") return RedirectResponse("/documents", status_code=303) db.update_fiscal( conn, doc_id, purchase_date=resolve_purchase_date(purchase_date), supplier_name=supplier, total_paid=total, ) flash(request, "Documento atualizado.", "success") return RedirectResponse("/documents", status_code=303) @router.post("/documents/{doc_id}/delete") def delete_document(request: Request, doc_id: int, csrf_token: str = Form("")): if not auth.check_csrf(request, csrf_token): flash(request, "Sessão expirada.", "error") return RedirectResponse("/documents", status_code=303) with db.session() as conn: db.delete_fiscal(conn, doc_id) flash(request, "Documento excluído.", "info") return RedirectResponse("/documents", status_code=303)