flowise1 / app.py
Persano's picture
Update app.py
6265dca verified
raw
history blame
9.15 kB
import os
os.environ['FONTCONFIG_PATH'] = '/tmp/fontconfig'
os.makedirs('/tmp/fontconfig', exist_ok=True)
from flask import Flask, render_template, request, send_file
import pandas as pd
import io
import matplotlib.pyplot as plt
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
from reportlab.lib import colors
from reportlab.platypus import Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
app = Flask(__name__)
def calcula_investimentos(capital, studio_ret, valorizacao, franquia_ret, acoes_ret, renda_fixa, inflacao, anos=5):
# capital inicial
dados = []
# Valores iniciais
studio_valor = capital
franquia_valor = capital
acoes_valor = capital
renda_valor = capital
# Para calcular valor patrimonial do studio: só considera valorização acumulada (sem renda)
studio_valor_patrimonial = capital
for ano in range(1, anos+1):
# Studio: valor patrimonial aumenta pela valorização anual
studio_valor_patrimonial *= (1 + valorizacao / 100)
# Renda mensal acumulada convertida para anual, reinvestida mensalmente - simplificamos usando juros compostos anualizados aproximados
studio_valor *= (1 + studio_ret / 100) ** 12
studio_valor *= (1 + valorizacao / 100) # valor patrimonial cresce
# Franquia: apenas retorno anual fixo somado
franquia_valor += franquia_ret
# Ações: cresce pelo retorno anual
acoes_valor *= (1 + acoes_ret / 100)
# Renda fixa: cresce pelo retorno anual
renda_valor *= (1 + renda_fixa / 100)
# Ajuste pela inflação para valores reais (opcional)
# Para esse exemplo, só mostramos valores nominais
dados.append({
'Ano': ano,
'Studio Valor Total (R$)': round(studio_valor, 2),
'Studio Valor Patrimonial (R$)': round(studio_valor_patrimonial, 2),
'Franquia Valor Total (R$)': round(franquia_valor, 2),
'Ações Valor Total (R$)': round(acoes_valor, 2),
'Renda Fixa Valor Total (R$)': round(renda_valor, 2),
})
df = pd.DataFrame(dados)
return df, studio_valor_patrimonial, studio_valor
def gera_grafico(df):
plt.switch_backend('Agg')
plt.figure(figsize=(8,5))
plt.plot(df['Ano'], df['Studio Valor Total (R$)'], label='Studio Total')
plt.plot(df['Ano'], df['Franquia Valor Total (R$)'], label='Franquia Total')
plt.plot(df['Ano'], df['Ações Valor Total (R$)'], label='Ações Total')
plt.plot(df['Ano'], df['Renda Fixa Valor Total (R$)'], label='Renda Fixa Total')
plt.title('Evolução do Investimento ao Longo dos Anos')
plt.xlabel('Ano')
plt.ylabel('Valor (R$)')
plt.legend()
plt.grid(True)
buf = io.BytesIO()
plt.savefig(buf, format='PNG')
plt.close()
buf.seek(0)
return buf
def gera_pdf(df, grafico_buf, params, valor_patrimonial, analise_final):
buffer = io.BytesIO()
c = canvas.Canvas(buffer, pagesize=A4)
width, height = A4
styles = getSampleStyleSheet()
normal_style = styles["Normal"]
title_style = styles["Title"]
c.setFont("Helvetica-Bold", 16)
c.drawString(50, height-50, "Relatório de Investimentos")
y = height - 80
# Mostrar dados de entrada
c.setFont("Helvetica-Bold", 12)
c.drawString(50, y, "Parâmetros de Entrada:")
y -= 20
c.setFont("Helvetica", 10)
for k,v in params.items():
c.drawString(55, y, f"{k}: {v}")
y -= 15
y -= 15
# Mostrar explicação do valor patrimonial do Studio
c.setFont("Helvetica-Bold", 12)
c.drawString(50, y, "Valor Patrimonial do Studio:")
y -= 15
text = ("O valor patrimonial do Studio é o valor acumulado do aumento do patrimônio, "
"considerando apenas a valorização do imóvel, sem a renda gerada.")
p = Paragraph(text, normal_style)
w, h = p.wrap(width - 100, y)
p.drawOn(c, 50, y - h)
y -= h + 10
c.setFont("Helvetica", 10)
c.drawString(50, y, f"Valor Patrimonial estimado após 5 anos: R$ {valor_patrimonial:,.2f}".replace(",", "X").replace(".", ",").replace("X", "."))
y -= 30
# Inserir gráfico
img = ImageReader(grafico_buf)
c.drawImage(img, 50, y - 250, width=500, height=250)
y -= 260
# Criar tabela com dados
data = [df.columns.to_list()] + df.round(2).astype(str).values.tolist()
# Formatar números para formato brasileiro (vírgula)
for i in range(1, len(data)):
for j in range(1, len(data[i])):
data[i][j] = data[i][j].replace('.', ',')
table = Table(data, colWidths=[50, 100, 110, 110, 110, 110])
style = TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#2E7D32')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('ALIGN', (1,1), (-1,-1), 'RIGHT'),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('GRID', (0,0), (-1,-1), 0.5, colors.grey),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.whitesmoke, colors.lightgrey]),
])
table.setStyle(style)
w, h = table.wrapOn(c, width-100, y)
if y - h < 50:
c.showPage()
y = height - 50
table.drawOn(c, 50, y - h)
y -= h + 20
# Análise final
p2 = Paragraph(f"<b>Considerações finais:</b><br/>{analise_final}", normal_style)
w2, h2 = p2.wrap(width - 100, y)
if y - h2 < 50:
c.showPage()
y = height - 50
p2.drawOn(c, 50, y - h2)
c.save()
buffer.seek(0)
return buffer
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
capital = float(request.form.get("capital"))
studio_ret = float(request.form.get("studio_ret"))
valorizacao = float(request.form.get("valorizacao"))
franquia_ret = float(request.form.get("franquia_ret"))
acoes_ret = float(request.form.get("acoes_ret"))
renda_fixa = float(request.form.get("renda_fixa"))
inflacao = float(request.form.get("inflacao"))
df, valor_patrimonial, valor_total_studio = calcula_investimentos(
capital, studio_ret, valorizacao, franquia_ret, acoes_ret, renda_fixa, inflacao
)
# Construir tabela HTML simples para mostrar na página
tabela_html = df.to_html(classes="table table-striped table-bordered", index=False, float_format="R$ {:,.2f}".format)
# Identificar maior retorno final
max_valor = max(df.iloc[-1][1:])
max_col = df.columns[(df.iloc[-1][1:] == max_valor).idxmax()]
analise_final = (f"Após análise dos cenários projetados para 5 anos, o investimento Studio apresenta o melhor desempenho, "
f"com um valor final estimado de R$ {valor_total_studio:,.2f}. "
f"Isto representa um retorno significativo sobre o capital inicial.")
return render_template(
"index.html",
tabela=tabela_html,
capital=capital,
studio_ret=studio_ret,
valorizacao=valorizacao,
franquia_ret=franquia_ret,
acoes_ret=acoes_ret,
renda_fixa=renda_fixa,
inflacao=inflacao,
analise_final=analise_final,
investimento_mais_valorizado=max_col,
valor_mais_alto=max_valor
)
else:
return render_template("index.html")
@app.route("/download_pdf", methods=["POST"])
def download_pdf():
capital = float(request.form.get("capital"))
studio_ret = float(request.form.get("studio_ret"))
valorizacao = float(request.form.get("valorizacao"))
franquia_ret = float(request.form.get("franquia_ret"))
acoes_ret = float(request.form.get("acoes_ret"))
renda_fixa = float(request.form.get("renda_fixa"))
inflacao = float(request.form.get("inflacao"))
df, valor_patrimonial, valor_total_studio = calcula_investimentos(
capital, studio_ret, valorizacao, franquia_ret, acoes_ret, renda_fixa, inflacao
)
analise_final = (f"Após análise dos cenários projetados para 5 anos, o investimento Studio apresenta o melhor desempenho, "
f"com um valor final estimado de R$ {valor_total_studio:,.2f}, equivalente a um retorno significativo sobre o capital inicial.")
grafico_buf = gera_grafico(df)
params = {
"Capital Inicial (R$)": f"R$ {capital:,.2f}",
"Retorno Mensal Studio (%)": f"{studio_ret}%",
"Valorização Anual Studio (%)": f"{valorizacao}%",
"Retorno Anual Franquia (R$)": f"R$ {franquia_ret:,.2f}",
"Retorno Anual Ações (%)": f"{acoes_ret}%",
"Retorno Anual Renda Fixa (%)": f"{renda_fixa}%",
"Inflação Anual Estimada (%)": f"{inflacao}%"
}
pdf_buffer = gera_pdf(df, grafico_buf, params, valor_patrimonial, analise_final)
return send_file(pdf_buffer, as_attachment=True, download_name="relatorio_investimentos.pdf", mimetype="application/pdf")
if __name__ == "__main__":
app.run(debug=True)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=True)