fschwartzer commited on
Commit
545fa66
·
verified ·
1 Parent(s): 41b540b

Delete src/app.py

Browse files
Files changed (1) hide show
  1. src/app.py +0 -233
src/app.py DELETED
@@ -1,233 +0,0 @@
1
- import streamlit as st
2
- import os
3
- from datetime import date
4
- import io
5
- from reportlab.platypus import (
6
- BaseDocTemplate, PageTemplate, Frame, Paragraph, Spacer,
7
- Table, TableStyle, PageBreak
8
- )
9
- from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
10
- from reportlab.lib.pagesizes import A4
11
- from reportlab.lib import colors
12
- from reportlab.lib.units import cm
13
- from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY, TA_LEFT, TA_RIGHT
14
-
15
- # =================================================================================
16
- # FUNÇÃO DE GERAÇÃO DE PDF (MODIFICADA PARA ACEITAR DADOS E RETORNAR BYTES)
17
- # =================================================================================
18
- def create_pdf_report(user_data):
19
- """
20
- Gera o relatório em PDF em memória, preenchido com os dados do usuário.
21
- """
22
- buffer = io.BytesIO()
23
- doc = BaseDocTemplate(buffer, pagesize=A4)
24
-
25
- HEADER_HEIGHT = 3.5 * cm
26
- main_frame = Frame(
27
- doc.leftMargin,
28
- doc.bottomMargin,
29
- doc.width,
30
- doc.height - HEADER_HEIGHT,
31
- id='main_frame'
32
- )
33
-
34
- def header(canvas, doc):
35
- canvas.saveState()
36
- page_width = doc.width + doc.leftMargin + doc.rightMargin
37
-
38
- # Logos (mantenha a lógica de verificar se existem)
39
- if os.path.exists('logo_pref.png'):
40
- canvas.drawImage('logo_pref.png', doc.leftMargin, 740, width=4*cm, preserveAspectRatio=True, mask='auto')
41
- if os.path.exists('logo_receita.png'):
42
- logo_width = 3.5 * cm
43
- x_centered = (page_width - logo_width) / 2
44
- canvas.drawImage('logo_receita.png', x_centered, 740, width=logo_width, preserveAspectRatio=True, mask='auto')
45
-
46
- header_style = ParagraphStyle(name='HeaderStyle', fontSize=8, alignment=TA_RIGHT)
47
- p = Paragraph("<b>DAI-ESJL</b><br/>Divisão de Avaliação de Imóveis<br/>Equipe de Suporte, Judiciais e Locações", header_style)
48
- p.wrapOn(canvas, doc.width, doc.topMargin)
49
- p.drawOn(canvas, doc.leftMargin, 757.5)
50
-
51
- # PROCESSO com número do usuário
52
- processo_style = ParagraphStyle(name='ProcessoStyle', fontSize=10, alignment=TA_RIGHT, textColor=colors.black)
53
- p_proc = Paragraph(f"PROCESSO {user_data['processo_numero']}", processo_style)
54
- p_proc.wrapOn(canvas, doc.width, 1*cm)
55
- p_proc.drawOn(canvas, doc.leftMargin, 730)
56
-
57
- canvas.restoreState()
58
-
59
- def footer(canvas, doc):
60
- canvas.saveState()
61
- canvas.setFont('Helvetica', 9)
62
- canvas.drawRightString(A4[0] - doc.rightMargin, doc.bottomMargin - 0.5*cm, str(doc.page))
63
- canvas.restoreState()
64
-
65
- doc.addPageTemplates([PageTemplate(id='main', frames=main_frame, onPage=header, onPageEnd=footer)])
66
-
67
- styles = getSampleStyleSheet()
68
- styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY, fontSize=10, leading=14))
69
- styles.add(ParagraphStyle(name='Center', alignment=TA_CENTER, fontSize=10, leading=14))
70
- styles.add(ParagraphStyle(name='MainTitle', fontSize=12, fontName='Helvetica-Bold', alignment=TA_CENTER, textColor=colors.black, borderPadding=(5, 2, 5, 2)))
71
- styles.add(ParagraphStyle(name='SectionTitle', fontSize=10, fontName='Helvetica-Bold', spaceBefore=16, spaceAfter=6))
72
- styles.add(ParagraphStyle(name='TableLabel', fontName='Helvetica-Bold', fontSize=9, alignment=TA_LEFT))
73
- styles.add(ParagraphStyle(name='TableContent', fontSize=9, alignment=TA_LEFT, leading=11))
74
-
75
- def create_styled_table(data, col_widths):
76
- styled_data = []
77
- for row_idx, row in enumerate(data):
78
- styled_row = []
79
- for col_idx, cell_content in enumerate(row):
80
- # O conteúdo da segunda coluna é tratado como 'TableContent'
81
- style = styles['TableLabel'] if col_idx == 0 else styles['TableContent']
82
- styled_row.append(Paragraph(str(cell_content), style))
83
- styled_data.append(styled_row)
84
- tbl = Table(styled_data, colWidths=col_widths)
85
- tbl.setStyle(TableStyle([
86
- ('VALIGN', (0, 0), (-1, -1), 'TOP'),
87
- ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
88
- ('LEFTPADDING', (0, 0), (-1, -1), 6), ('RIGHTPADDING', (0, 0), (-1, -1), 6),
89
- ('TOPPADDING', (0, 0), (-1, -1), 4), ('BOTTOMPADDING', (0, 0), (-1, -1), 4),
90
- ]))
91
- return tbl
92
-
93
- story = []
94
-
95
- # --- PÁGINA 1 ---
96
- story.append(Spacer(1, 0.5 * cm))
97
- # Título com número do usuário
98
- story.append(Paragraph(f"INFORMAÇÃO TÉCNICA<br/>IT_{user_data['it_numero']}", styles['MainTitle']))
99
-
100
- story.append(Paragraph("• SOLICITAÇÃO", styles['SectionTitle']))
101
- solicitacao_data = [
102
- ['Unidade demandante:', user_data['unidade_demandante']],
103
- ['Finalidade da Avaliação:', user_data['finalidade_avaliacao']]
104
- ]
105
- story.append(create_styled_table(solicitacao_data, col_widths=[4.5*cm, '*']))
106
-
107
- story.append(Paragraph("• IMÓVEL OBJETO", styles['SectionTitle']))
108
- imovel_data = [
109
- ['Endereço - SMF:', user_data['endereco_smf']],
110
- ['Bairro (Setor/Quarteirão) - SMF:', user_data['bairro_smf']],
111
- ['Lote Fiscal / Inscrição - SMF:', user_data['lote_fiscal']],
112
- ['Registro imóvel nº - SMF:', user_data['registro_imovel']],
113
- ['Finalidade Imóvel - SMF:', user_data['finalidade_imovel']],
114
- ['Área Territorial - SMF:', user_data['area_territorial']],
115
- ['Área construída – SMF:', user_data['area_construida']],
116
- ['Exercícios em análise:', user_data['exercicios_analise']],
117
- ['Valores Venais Guias IPTU (Exercícios):', user_data['valores_venais']]
118
- ]
119
- story.append(create_styled_table(imovel_data, col_widths=[4.5*cm, '*']))
120
- story.append(PageBreak())
121
-
122
- # --- PÁGINA 2 ---
123
- story.append(Paragraph("• ANÁLISE TÉCNICA PRELIMINAR", styles['SectionTitle']))
124
- analise_data = [
125
- ['Unidade responsável:', user_data['unidade_responsavel']],
126
- ['Técnico responsável:', user_data['tecnico_responsavel']],
127
- ['Método de Avaliação (ABNT NBR 14.653-2):', user_data['metodo_avaliacao']]
128
- ]
129
- story.append(create_styled_table(analise_data, col_widths=[4.5*cm, '*']))
130
-
131
- story.append(Paragraph("• CONCLUSÃO TÉCNICA", styles['SectionTitle']))
132
- conclusao_data = [
133
- ['Características particularmente<br/>desvalorizantes:', user_data['caracteristicas_desvalorizantes']],
134
- ['Conclusão:', user_data['conclusao_preliminar']]
135
- ]
136
- story.append(create_styled_table(conclusao_data, col_widths=[6*cm, '*']))
137
- story.append(PageBreak())
138
-
139
- # --- PÁGINAS SEGUINTES (CONTEÚDO TEXTUAL) ---
140
- story.append(Paragraph("1. CONSIDERAÇÕES INICIAIS", styles['SectionTitle']))
141
- story.append(Paragraph(user_data['texto_consideracoes'], styles['Justify']))
142
-
143
- story.append(Paragraph("2. ANÁLISE TÉCNICA PRELIMINAR", styles['SectionTitle']))
144
- story.append(Paragraph(user_data['texto_analise'], styles['Justify']))
145
-
146
- # ... Adicione os outros parágrafos da mesma forma ...
147
-
148
- story.append(Spacer(1, 3*cm))
149
-
150
- # Data automática
151
- today = date.today()
152
- meses = ("janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro")
153
- data_formatada = f"Porto Alegre, {today.day} de {meses[today.month - 1]} de {today.year}."
154
- story.append(Paragraph(data_formatada, styles['Center']))
155
-
156
- doc.build(story)
157
-
158
- # Retorna os bytes do PDF gerado
159
- pdf_bytes = buffer.getvalue()
160
- buffer.close()
161
- return pdf_bytes
162
-
163
- # =================================================================================
164
- # INTERFACE DO STREAMLIT
165
- # =================================================================================
166
- st.set_page_config(layout="wide")
167
- st.title("Gerador de Relatório Técnico")
168
-
169
- # Coletando os dados do usuário em colunas para melhor organização
170
- col1, col2 = st.columns(2)
171
-
172
- with col1:
173
- st.header("Dados Gerais e de Capa")
174
- user_data = {}
175
- user_data['processo_numero'] = st.text_input("Número do Processo:", "SEI-...")
176
- user_data['it_numero'] = st.text_input("Número da Informação Técnica (ex: 001/2025):", "XXX/2025")
177
-
178
- st.subheader("Solicitação (Página 1)")
179
- user_data['unidade_demandante'] = st.text_input("Unidade demandante:", "Equipe da Planta Genérica de Valores - EPGV (DAI/RM/SMF)")
180
- user_data['finalidade_avaliacao'] = st.text_input("Finalidade da Avaliação:", "Análise Técnica Preliminar - Finalidade Conforme Demanda EPGV")
181
-
182
- st.subheader("Imóvel Objeto (Página 1)")
183
- user_data['endereco_smf'] = st.text_input("Endereço - SMF:")
184
- user_data['bairro_smf'] = st.text_input("Bairro (Setor/Quarteirão) - SMF:")
185
- user_data['lote_fiscal'] = st.text_input("Lote Fiscal / Inscrição - SMF:")
186
- user_data['registro_imovel'] = st.text_input("Registro imóvel nº - SMF:", "Matrícula xxxxx / yª Zona de Porto Alegre")
187
- user_data['finalidade_imovel'] = st.text_area("Finalidade Imóvel - SMF:", "Opção A: 10-Terreno\nOpção B: 20 - Residência Isolada", height=100)
188
- user_data['area_territorial'] = st.text_input("Área Territorial - SMF:", "0,00 m² (privativa) / 0,00 m² (total)")
189
- user_data['area_construida'] = st.text_area("Área construída – SMF:", "00,00m² / YYYY / 35-ALVENARIA (C) - CASAS ATE 2 PAVIM.\n00,00m² / YYYY / 35-ALVENARIA (C) - CASAS ATE 2 PAVIM.", height=100)
190
- user_data['exercicios_analise'] = st.text_area("Exercícios em análise:", "XXXX a YYYY (não há lançamentos anteriores a XXXX)", height=150)
191
- user_data['valores_venais'] = st.text_input("Valores Venais Guias IPTU (Exercícios):")
192
-
193
- with col2:
194
- st.header("Análise e Conclusão (Página 2)")
195
- user_data['unidade_responsavel'] = st.text_input("Unidade responsável:", "Equipe de Suporte, Judiciais e Locações - ESJL (DAI/RM/SMF)")
196
- user_data['tecnico_responsavel'] = st.text_input("Técnico responsável:")
197
- user_data['metodo_avaliacao'] = st.text_area("Método de Avaliação (ABNT NBR 14.653-2):", "Opção A: Método Comparativo de Dados de Mercado\nOpção B:\n- Método Comparativo de Dados de Mercado\n- Método de Quantificação de Custo", height=150)
198
- user_data['caracteristicas_desvalorizantes'] = st.text_input("Características particularmente desvalorizantes:")
199
- user_data['conclusao_preliminar'] = st.text_area("Conclusão:", "Opção A: Requer análise técnica pormenorizada\n\nOpção B: Não requer análise técnica pormenorizada.\n\nOpção C: Sugerida análise fiscal quanto a ocorrência de característica particularmente desvalorizante prevista na Legislação.", height=200)
200
-
201
- st.header("Corpo do Relatório (Textos Longos)")
202
- user_data['texto_consideracoes'] = st.text_area(
203
- "1. CONSIDERAÇÕES INICIAIS",
204
- "A presente Informação Técnica foi elaborada por esta Equipe de Suporte, Judiciais e Locações (ESJL)...",
205
- height=200
206
- )
207
- user_data['texto_analise'] = st.text_area(
208
- "2. ANÁLISE TÉCNICA PRELIMINAR",
209
- "Para garantir o embasamento técnico desta análise preliminar...",
210
- height=200
211
- )
212
- # Adicione mais st.text_area para cada parágrafo longo que você precisa editar
213
-
214
- st.markdown("---")
215
-
216
- if st.button("Gerar Relatório em PDF"):
217
- with st.spinner("Gerando PDF..."):
218
- # Chamar a função para gerar o PDF em memória
219
- pdf_bytes = create_pdf_report(user_data)
220
-
221
- # Armazenar os bytes do PDF no estado da sessão para o download
222
- st.session_state.pdf_bytes = pdf_bytes
223
- st.session_state.file_name = f"IT_{user_data['it_numero'].replace('/', '_')}.pdf"
224
-
225
- # Botão de download só aparece se o PDF foi gerado
226
- if 'pdf_bytes' in st.session_state and st.session_state.pdf_bytes:
227
- st.success("Seu relatório está pronto para download!")
228
- st.download_button(
229
- label="Baixar PDF",
230
- data=st.session_state.pdf_bytes,
231
- file_name=st.session_state.file_name,
232
- mime="application/pdf"
233
- )