Files
app_faturas/main.py

137 lines
4.6 KiB
Python
Raw Normal View History

import uuid
from fastapi import FastAPI, Request, UploadFile, File
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
import os, shutil
from fastapi.responses import StreamingResponse
from io import BytesIO
import pandas as pd
from sqlalchemy.future import select
from database import AsyncSessionLocal
from models import Fatura
from processor import (
fila_processamento,
processar_em_lote,
status_arquivos,
limpar_arquivos_processados
)
app = FastAPI()
templates = Jinja2Templates(directory="templates")
app.mount("/static", StaticFiles(directory="static"), name="static")
UPLOAD_DIR = "uploads/temp"
os.makedirs(UPLOAD_DIR, exist_ok=True)
@app.get("/", response_class=HTMLResponse)
def dashboard(request: Request):
indicadores = [
{"titulo": "Total de Faturas", "valor": 124},
{"titulo": "Faturas com ICMS", "valor": "63%"},
{"titulo": "Valor Total", "valor": "R$ 280.000,00"},
]
analise_stf = {
"antes": {"percentual_com_icms": 80, "media_valor": 1200},
"depois": {"percentual_com_icms": 20, "media_valor": 800},
}
return templates.TemplateResponse("dashboard.html", {
"request": request,
"cliente_atual": "",
"clientes": ["Cliente A", "Cliente B"],
"indicadores": indicadores,
"analise_stf": analise_stf
})
@app.get("/upload", response_class=HTMLResponse)
def upload_page(request: Request):
return templates.TemplateResponse("upload.html", {"request": request})
@app.get("/relatorios", response_class=HTMLResponse)
def relatorios_page(request: Request):
return templates.TemplateResponse("relatorios.html", {"request": request})
@app.get("/parametros", response_class=HTMLResponse)
def parametros_page(request: Request):
return templates.TemplateResponse("parametros.html", {"request": request})
@app.post("/upload-files")
async def upload_files(files: list[UploadFile] = File(...)):
for file in files:
temp_path = os.path.join(UPLOAD_DIR, f"{uuid.uuid4()}_{file.filename}")
with open(temp_path, "wb") as f:
shutil.copyfileobj(file.file, f)
await fila_processamento.put({
"caminho_pdf": temp_path,
"nome_original": file.filename
})
return {"message": "Arquivos enviados para fila"}
@app.post("/process-queue")
async def process_queue():
resultados = await processar_em_lote()
return {"message": "Processamento concluído", "resultados": resultados}
@app.get("/get-status")
async def get_status():
files = []
for nome, status in status_arquivos.items():
files.append({
"nome": nome,
"status": status,
"mensagem": "---" if status == "Concluído" else status
})
is_processing = not fila_processamento.empty()
return JSONResponse(content={"is_processing": is_processing, "files": files})
@app.post("/clear-all")
async def clear_all():
limpar_arquivos_processados()
for f in os.listdir(UPLOAD_DIR):
os.remove(os.path.join(UPLOAD_DIR, f))
return {"message": "Fila e arquivos limpos"}
@app.get("/export-excel")
async def export_excel():
async with AsyncSessionLocal() as session:
result = await session.execute(select(Fatura))
faturas = result.scalars().all()
dados = []
for f in faturas:
dados.append({
"Nome": f.nome,
"UC": f.unidade_consumidora,
"Referência": f.referencia,
"Nota Fiscal": f.nota_fiscal,
"Valor Total": f.valor_total,
"ICMS (%)": f.icms_aliq,
"ICMS (R$)": f.icms_valor,
"Base ICMS": f.icms_base,
"PIS (%)": f.pis_aliq,
"PIS (R$)": f.pis_valor,
"Base PIS": f.pis_base,
"COFINS (%)": f.cofins_aliq,
"COFINS (R$)": f.cofins_valor,
"Base COFINS": f.cofins_base,
"Consumo (kWh)": f.consumo,
"Tarifa": f.tarifa,
"Cidade": f.cidade,
"Estado": f.estado,
"Distribuidora": f.distribuidora,
"Data Processamento": f.data_processamento,
})
df = pd.DataFrame(dados)
output = BytesIO()
df.to_excel(output, index=False, sheet_name="Faturas")
output.seek(0)
return StreamingResponse(
output,
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
headers={"Content-Disposition": "attachment; filename=relatorio_faturas.xlsx"}
)