Files
LerNotaFiscal/app/routes/documents_routes.py
T

138 lines
4.4 KiB
Python

"""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)