|
|
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): |
|
|
|
|
|
dados = [] |
|
|
|
|
|
studio_valor = capital |
|
|
franquia_valor = capital |
|
|
acoes_valor = capital |
|
|
renda_valor = capital |
|
|
|
|
|
|
|
|
studio_valor_patrimonial = capital |
|
|
|
|
|
for ano in range(1, anos+1): |
|
|
|
|
|
studio_valor_patrimonial *= (1 + valorizacao / 100) |
|
|
|
|
|
studio_valor *= (1 + studio_ret / 100) ** 12 |
|
|
studio_valor *= (1 + valorizacao / 100) |
|
|
|
|
|
|
|
|
franquia_valor += franquia_ret |
|
|
|
|
|
|
|
|
acoes_valor *= (1 + acoes_ret / 100) |
|
|
|
|
|
|
|
|
renda_valor *= (1 + renda_fixa / 100) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
img = ImageReader(grafico_buf) |
|
|
c.drawImage(img, 50, y - 250, width=500, height=250) |
|
|
y -= 260 |
|
|
|
|
|
|
|
|
data = [df.columns.to_list()] + df.round(2).astype(str).values.tolist() |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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 |
|
|
) |
|
|
|
|
|
|
|
|
tabela_html = df.to_html(classes="table table-striped table-bordered", index=False, float_format="R$ {:,.2f}".format) |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|