Persano commited on
Commit
cebf85b
·
verified ·
1 Parent(s): 699ea8b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +260 -0
app.py ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import base64
3
+ from datetime import datetime
4
+ from flask import Flask, render_template, request, send_file
5
+ import pandas as pd
6
+ import matplotlib.pyplot as plt
7
+ from matplotlib.ticker import FuncFormatter
8
+ from reportlab.lib.pagesizes import A4
9
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image, PageBreak
10
+ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
11
+ from reportlab.lib import colors
12
+ from reportlab.lib.units import cm
13
+
14
+ app = Flask(__name__)
15
+
16
+ def formatar_brl(valor):
17
+ return f"R$ {valor:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
18
+
19
+ def calcular_valor_patrimonial(capital, taxa_valorizacao_anual, anos=5):
20
+ return capital * ((1 + taxa_valorizacao_anual / 100) ** anos)
21
+
22
+ def gerar_analise(investimentos_finais, capital):
23
+ melhor = max(investimentos_finais, key=investimentos_finais.get)
24
+ valor_melhor = investimentos_finais[melhor]
25
+ retorno_pct = ((valor_melhor - capital) / capital) * 100
26
+ analise = f"""
27
+ Após análise dos cenários projetados para 5 anos, o investimento <strong>{melhor}</strong> apresenta o melhor desempenho,
28
+ com um valor final estimado de <strong>{formatar_brl(valor_melhor)}</strong>, equivalente a um retorno de <strong>{retorno_pct:.1f}%</strong> sobre o capital inicial.
29
+ """
30
+ return analise, melhor, valor_melhor
31
+
32
+ @app.route("/", methods=["GET", "POST"])
33
+ def index():
34
+ if request.method == "POST":
35
+ # Captura dados do formulário
36
+ capital = float(request.form["capital"])
37
+ studio_ret = float(request.form["studio_ret"])
38
+ valorizacao = float(request.form["valorizacao"])
39
+ franquia_ret = float(request.form["franquia_ret"])
40
+ acoes_ret = float(request.form["acoes_ret"])
41
+ renda_fixa = float(request.form["renda_fixa"])
42
+ inflacao = float(request.form["inflacao"])
43
+
44
+ anos = list(range(1, 6))
45
+
46
+ # Cálculos dos investimentos
47
+ patrimonio_studio = [capital * ((1 + valorizacao / 100) ** ano) for ano in anos]
48
+ renda_acumulada_studio = [capital * (((1 + studio_ret / 100) ** (12 * ano)) - 1) for ano in anos]
49
+ studio_total = [p + r for p, r in zip(patrimonio_studio, renda_acumulada_studio)]
50
+
51
+ franquia = [capital + (franquia_ret * ano) for ano in anos]
52
+ acoes = [capital * ((1 + acoes_ret / 100) ** ano) for ano in anos]
53
+ renda_fixa_valores = [capital * ((1 + renda_fixa / 100) ** ano) for ano in anos]
54
+
55
+ dados = {
56
+ "Ano": anos,
57
+ "Studio (Patrimônio + Renda)": studio_total,
58
+ "Franquia": franquia,
59
+ "Ações": acoes,
60
+ "Renda Fixa": renda_fixa_valores
61
+ }
62
+ df = pd.DataFrame(dados)
63
+
64
+ investimentos_finais = {
65
+ "Studio": studio_total[-1],
66
+ "Franquia": franquia[-1],
67
+ "Ações": acoes[-1],
68
+ "Renda Fixa": renda_fixa_valores[-1],
69
+ }
70
+
71
+ analise_final, investimento_mais_valorizado, valor_mais_alto = gerar_analise(investimentos_finais, capital)
72
+
73
+ # Preparar tabela HTML formatada para o browser
74
+ df_formatado = df.copy()
75
+ for col in df.columns:
76
+ if col != "Ano":
77
+ df_formatado[col] = df_formatado[col].apply(formatar_brl)
78
+ tabela = df_formatado.to_html(index=False, classes="table table-striped table-sm", border=0)
79
+
80
+ return render_template(
81
+ "index.html",
82
+ capital=capital,
83
+ studio_ret=studio_ret,
84
+ valorizacao=valorizacao,
85
+ franquia_ret=franquia_ret,
86
+ acoes_ret=acoes_ret,
87
+ renda_fixa=renda_fixa,
88
+ inflacao=inflacao,
89
+ anos=anos,
90
+ tabela=tabela,
91
+ analise_final=analise_final,
92
+ investimento_mais_valorizado=investimento_mais_valorizado,
93
+ valor_mais_alto=valor_mais_alto,
94
+ resumo=investimentos_finais
95
+ )
96
+ return render_template("index.html")
97
+
98
+ @app.route("/download_pdf", methods=["POST"])
99
+ def download_pdf():
100
+ capital = float(request.form["capital"])
101
+ studio_ret = float(request.form["studio_ret"])
102
+ valorizacao = float(request.form["valorizacao"])
103
+ franquia_ret = float(request.form["franquia_ret"])
104
+ acoes_ret = float(request.form["acoes_ret"])
105
+ renda_fixa = float(request.form["renda_fixa"])
106
+ inflacao = float(request.form["inflacao"])
107
+
108
+ anos = list(range(1, 6))
109
+
110
+ patrimonio_studio = [capital * ((1 + valorizacao / 100) ** ano) for ano in anos]
111
+ renda_acumulada_studio = [capital * (((1 + studio_ret / 100) ** (12 * ano)) - 1) for ano in anos]
112
+ studio_total = [p + r for p, r in zip(patrimonio_studio, renda_acumulada_studio)]
113
+
114
+ franquia = [capital + (franquia_ret * ano) for ano in anos]
115
+ acoes = [capital * ((1 + acoes_ret / 100) ** ano) for ano in anos]
116
+ renda_fixa_valores = [capital * ((1 + renda_fixa / 100) ** ano) for ano in anos]
117
+
118
+ dados = {
119
+ "Ano": anos,
120
+ "Studio (Patrimônio + Renda)": studio_total,
121
+ "Franquia": franquia,
122
+ "Ações": acoes,
123
+ "Renda Fixa": renda_fixa_valores
124
+ }
125
+ df = pd.DataFrame(dados)
126
+
127
+ investimentos_finais = {
128
+ "Studio": studio_total[-1],
129
+ "Franquia": franquia[-1],
130
+ "Ações": acoes[-1],
131
+ "Renda Fixa": renda_fixa_valores[-1],
132
+ }
133
+
134
+ analise_final, investimento_mais_valorizado, valor_mais_alto = gerar_analise(investimentos_finais, capital)
135
+
136
+ valor_patrimonial = calcular_valor_patrimonial(capital, valorizacao)
137
+
138
+ # Gerar gráfico matplotlib e salvar em buffer para o PDF
139
+ plt.figure(figsize=(8, 4.5))
140
+ plt.plot(anos, studio_total, label="Studio (Patrimônio + Renda)", marker="o")
141
+ plt.plot(anos, franquia, label="Franquia", marker="o")
142
+ plt.plot(anos, acoes, label="Ações", marker="o")
143
+ plt.plot(anos, renda_fixa_valores, label="Renda Fixa", marker="o")
144
+ plt.title("Projeção de Investimentos - 5 anos")
145
+ plt.xlabel("Ano")
146
+ plt.ylabel("Valor (R$)")
147
+ plt.legend()
148
+ plt.grid(True)
149
+ plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, _: f"R${x:,.0f}".replace(",", ".")))
150
+ plt.tight_layout()
151
+
152
+ img_buffer = io.BytesIO()
153
+ plt.savefig(img_buffer, format="PNG")
154
+ img_buffer.seek(0)
155
+ plt.close()
156
+
157
+ # Montar PDF com reportlab
158
+ pdf_buffer = io.BytesIO()
159
+ doc = SimpleDocTemplate(pdf_buffer, pagesize=A4, rightMargin=2*cm,leftMargin=2*cm, topMargin=2*cm, bottomMargin=2*cm)
160
+ styles = getSampleStyleSheet()
161
+ styleN = styles['Normal']
162
+ styleH = styles['Heading1']
163
+
164
+ elementos = []
165
+
166
+ # Página 1: Dados de entrada
167
+ elementos.append(Paragraph("Dados de Entrada da Simulação", styleH))
168
+ elementos.append(Spacer(1, 12))
169
+ dados_entrada = [
170
+ ["Parâmetro", "Valor"],
171
+ ["Capital Inicial (R$)", formatar_brl(capital)],
172
+ ["Retorno Mensal Studio (%)", f"{studio_ret:.2f}%"],
173
+ ["Valorização Anual Studio (%)", f"{valorizacao:.2f}%"],
174
+ ["Retorno Anual Franquia (R$)", formatar_brl(franquia_ret)],
175
+ ["Retorno Anual Ações (%)", f"{acoes_ret:.2f}%"],
176
+ ["Retorno Anual Renda Fixa (%)", f"{renda_fixa:.2f}%"],
177
+ ["Inflação Anual Estimada (%)", f"{inflacao:.2f}%"],
178
+ ]
179
+ tabela_entrada = Table(dados_entrada, colWidths=[200, 150])
180
+ tabela_entrada.setStyle(TableStyle([
181
+ ('BACKGROUND', (0,0), (-1,0), colors.HexColor("#2E7D32")),
182
+ ('TEXTCOLOR', (0,0), (-1,0), colors.white),
183
+ ('ALIGN', (0,0), (-1,-1), 'LEFT'),
184
+ ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
185
+ ('FONTSIZE', (0,0), (-1,-1), 10),
186
+ ('BOTTOMPADDING', (0,0), (-1,0), 8),
187
+ ('BACKGROUND', (0,1), (-1,-1), colors.whitesmoke),
188
+ ('GRID', (0,0), (-1,-1), 0.5, colors.grey),
189
+ ]))
190
+ elementos.append(tabela_entrada)
191
+ elementos.append(PageBreak())
192
+
193
+ # Página 2: Explicação valor patrimonial
194
+ texto_patrimonial = f"""
195
+ O valor patrimonial do Studio corresponde ao valor acumulado da valorização do imóvel, sem considerar a renda gerada pelo investimento.
196
+ Após 5 anos, este valor é estimado em <strong>{formatar_brl(valor_patrimonial)}</strong>. Este cálculo segue as normas contábeis e práticas recomendadas por investidores profissionais,
197
+ refletindo o aumento do patrimônio imobiliário ao longo do tempo.
198
+ """
199
+ elementos.append(Paragraph("Valor Patrimonial do Studio", styleH))
200
+ elementos.append(Spacer(1, 12))
201
+ elementos.append(Paragraph(texto_patrimonial, styleN))
202
+ elementos.append(PageBreak())
203
+
204
+ # Página 3: Gráfico de evolução
205
+ elementos.append(Paragraph("Gráfico de Evolução dos Investimentos", styleH))
206
+ elementos.append(Spacer(1, 12))
207
+ img = Image(img_buffer)
208
+ img._restrictSize(17*cm, 9*cm)
209
+ elementos.append(img)
210
+ elementos.append(PageBreak())
211
+
212
+ # Página 4: Tabela evolução ano a ano
213
+ elementos.append(Paragraph("Evolução Ano a Ano dos Investimentos", styleH))
214
+ elementos.append(Spacer(1, 12))
215
+
216
+ df_formatado = df.copy()
217
+ for col in df.columns:
218
+ if col != "Ano":
219
+ df_formatado[col] = df_formatado[col].apply(formatar_brl)
220
+ dados_tabela = [df_formatado.columns.to_list()] + df_formatado.values.tolist()
221
+
222
+ tabela_invest = Table(dados_tabela, colWidths=[50, 120, 120, 120, 120])
223
+ tabela_invest.setStyle(TableStyle([
224
+ ('BACKGROUND', (0,0), (-1,0), colors.HexColor("#2E7D32")),
225
+ ('TEXTCOLOR', (0,0), (-1,0), colors.white),
226
+ ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
227
+ ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
228
+ ('FONTSIZE', (0,0), (-1,-1), 9),
229
+ ('BOTTOMPADDING', (0,0), (-1,0), 8),
230
+ ('BACKGROUND', (0,1), (-1,-1), colors.whitesmoke),
231
+ ('GRID', (0,0), (-1,-1), 0.5, colors.grey),
232
+ ]))
233
+ elementos.append(tabela_invest)
234
+ elementos.append(PageBreak())
235
+
236
+ # Página 5: Considerações finais
237
+ elementos.append(Paragraph("Considerações Finais", styleH))
238
+ elementos.append(Spacer(1, 12))
239
+
240
+ analise_texto = analise_final.replace("<strong>", "").replace("</strong>", "")
241
+ texto_final = (
242
+ analise_texto +
243
+ f"\n\nO valor patrimonial do investimento {investimento_mais_valorizado} é de {formatar_brl(valor_mais_alto)}.\n\n"
244
+ "O valor patrimonial é uma métrica essencial para investidores profissionais, pois reflete o patrimônio líquido acumulado do investimento, "
245
+ "de acordo com normas contábeis vigentes e práticas do mercado financeiro."
246
+ )
247
+ elementos.append(Paragraph(texto_final, styleN))
248
+
249
+ doc.build(elementos)
250
+
251
+ pdf_buffer.seek(0)
252
+ return send_file(
253
+ pdf_buffer,
254
+ mimetype="application/pdf",
255
+ as_attachment=True,
256
+ download_name="relatorio_investimentos.pdf"
257
+ )
258
+
259
+ if __name__ == "__main__":
260
+ app.run(debug=True)