gbope commited on
Commit
bf5a0d9
·
verified ·
1 Parent(s): c0ae6cd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +255 -52
app.py CHANGED
@@ -1,66 +1,265 @@
1
  import gradio as gr
2
  import re
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  def limpar_texto_para_copiar(texto):
5
- # Remove tags HTML e formata para texto puro
6
  texto_limpo = re.sub('<[^<]+?>', '', texto)
7
  texto_limpo = texto_limpo.replace('</ul>', '\n').replace('</li>', '\n')
8
  texto_limpo = re.sub('\n+', '\n', texto_limpo).strip()
9
  return texto_limpo
10
 
11
- def criar_botao_copiar():
12
- # JavaScript que será injetado na interface
13
- js = """
14
- async function copiarTexto() {
15
- const texto = document.querySelector("#texto-para-copiar textarea").value;
16
- try {
17
- await navigator.clipboard.writeText(texto);
18
- return "✅ Copiado para área de transferência!";
19
- } catch (err) {
20
- // Fallback para o método antigo se o novo não funcionar
21
- const textarea = document.createElement('textarea');
22
- textarea.value = texto;
23
- document.body.appendChild(textarea);
24
- textarea.select();
25
- document.execCommand('copy');
26
- document.body.removeChild(textarea);
27
- return "✅ Copiado (método alternativo)!";
28
- }
29
- }
30
- """
31
-
32
- with gr.Blocks() as demo:
33
- texto_para_copiar = gr.Textbox(visible=False)
34
- btn_copiar = gr.Button("📋 Copiar Lista")
35
- status_copia = gr.Textbox(label="Status", interactive=False, visible=False)
36
 
37
- btn_copiar.click(
38
- fn=lambda x: x, # Função vazia, o trabalho é feito no JavaScript
39
- inputs=texto_para_copiar,
40
- outputs=status_copia,
41
- js=js + "async () => { return await copiarTexto(); }"
42
- ).then(
43
- lambda: gr.update(visible=True),
44
- None,
45
- status_copia
46
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
- return demo
 
 
 
 
 
 
 
 
 
 
49
 
50
- # Adicione esta função à sua interface principal
51
- def criar_interface_completa():
52
- with gr.Blocks() as app:
53
- # ... (todo o resto do seu código existente)
 
54
 
55
- # Substitua a parte do botão de copiar por:
56
- texto_para_copiar = gr.Textbox(visible=False)
57
- btn_copiar = gr.Button("📋 Copiar Lista")
58
- status_copia = gr.Textbox(label="Status", interactive=False, visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
- # Quando gerar a lista de documentos:
61
  btn_submit.click(
62
  processar_documentos,
63
- inputs=[...],
 
 
 
 
 
 
64
  outputs=output
65
  ).then(
66
  limpar_texto_para_copiar,
@@ -68,13 +267,13 @@ def criar_interface_completa():
68
  outputs=texto_para_copiar
69
  )
70
 
71
- # Configuração do botão de copiar
72
  btn_copiar.click(
73
- fn=lambda x: x,
74
- inputs=texto_para_copiar,
75
  outputs=status_copia,
76
  js="""
77
- async (texto) => {
 
78
  try {
79
  await navigator.clipboard.writeText(texto);
80
  return "✅ Copiado para área de transferência!";
@@ -95,4 +294,8 @@ def criar_interface_completa():
95
  status_copia
96
  )
97
 
98
- return app
 
 
 
 
 
1
  import gradio as gr
2
  import re
3
 
4
+ def obter_documentos_padrao_2010_mais():
5
+ return [
6
+ "Certidão de Nascimento (Não pode ser só o RG)",
7
+ "Documento com Foto (RG/CNH/OUTROS - se houver)",
8
+ "CPF (se não tiver em outro documento)",
9
+ "Foto Corporal Completa para Verificação de Saúde (explicação abaixo)",
10
+ "Email e celular do responsável"
11
+ ]
12
+
13
+ def obter_documentos_padrao_2009_menos():
14
+ return [
15
+ "Documento com Foto (RG/CNH/OUTROS)",
16
+ "CPF (se não tiver no documento com foto)",
17
+ "Foto com Documento ao lado do rosto",
18
+ "Email e celular"
19
+ ]
20
+
21
+ def obter_documentos_carencia():
22
+ return [
23
+ "3 últimos boletos pagos e seus comprovantes",
24
+ "Carteirinha",
25
+ "Carta de permanência (solicitar à administradora do plano, geralmente por ligação)"
26
+ ]
27
+
28
+ def obter_documentos_titular(categoria, modalidade, documentos_padrao):
29
+ documentos = documentos_padrao.copy()
30
+ documentos.append("Comprovante de Residência (no nome do titular ou dos parents)")
31
+
32
+ if categoria == "CNPJ":
33
+ documentos.append("DA EMPRESA:")
34
+ if modalidade == "MEI":
35
+ documentos.extend(["CNPJ", "CCMEI"])
36
+ elif modalidade == "OUTROS":
37
+ documentos.extend(["CNPJ", "Contrato Social e suas alterações"])
38
+
39
+ elif categoria == "ADESAO":
40
+ documentos_map = {
41
+ "ENTIDADE ABERTA": None,
42
+ "ESTUDANTE": "Declaração Escolar",
43
+ "TRABALHADOR": "Contracheque",
44
+ "PROFISSIONAL LIBERAL": "Documento de Registro no Conselho na validade + Diploma",
45
+ "APOSENTADO": "Comprovante de Pensão"
46
+ }
47
+ doc_extra = documentos_map.get(modalidade)
48
+ if doc_extra:
49
+ documentos.append(doc_extra)
50
+
51
+ return documentos
52
+
53
+ def simplificar_dependente(nome):
54
+ simplificacoes = {
55
+ "Cônjuge ou companheiro(a)": "Cônjuge",
56
+ "Filhos(as) solteiros naturais, tutelados, enteados e adotivos": "Filhos",
57
+ "Filhos(as) inválidos declarados no imposto de renda do titular": "Filho inválido",
58
+ "Pai e mãe": "Pais",
59
+ "Padrasto e madrasta": "Padrastos",
60
+ "Irmãos(ãs) consanguíneos ou adotivos": "Irmãos",
61
+ "Netos": "Netos",
62
+ "Sobrinhos": "Sobrinhos",
63
+ "Primos": "Primos",
64
+ "Tios": "Tios",
65
+ "Cunhados(as)": "Cunhados",
66
+ "Sogro(a)": "Sogro(a)",
67
+ "Genros e noras": "Genros/Noras",
68
+ "Avô e avó": "Avós"
69
+ }
70
+ return simplificacoes.get(nome, nome)
71
+
72
+ def formatar_documentos(nome, documentos):
73
+ resultado = f"<h3>Documentos necessários para {nome}:</h3><ul>"
74
+ for doc in documentos:
75
+ if doc == "DA EMPRESA:":
76
+ resultado += f"</ul><h4>{doc}</h4><ul>"
77
+ else:
78
+ resultado += f"<li>{doc}</li>"
79
+ resultado += "</ul>"
80
+ return resultado
81
+
82
+ def obter_documentos_dependente(dependente, nascido_2010):
83
+ documentos = obter_documentos_padrao_2010_mais() if nascido_2010 else obter_documentos_padrao_2009_menos()
84
+
85
+ if dependente == "Cônjuge ou companheiro(a)":
86
+ documentos.append("Certidão de casamento ou declaração de união estável (lavrada em cartório).")
87
+ elif "inválido" in dependente:
88
+ documentos.append("Declaração de imposto de renda do titular comprovando a condição.")
89
+ elif dependente in ["Netos", "Sobrinhos", "Primos", "Tios"]:
90
+ documentos.append("Documento com foto (RG/CNH/outros) do pai/mãe.")
91
+ elif dependente in ["Cunhados(as)", "Genros e noras"]:
92
+ documentos.append("Certidão de casamento.")
93
+ elif dependente == "Sogro(a)":
94
+ documentos.append("Certidão de casamento do titular")
95
+
96
+ return documentos
97
+
98
+ def processar_documentos(titular_nascido_2010, categoria, modalidade, titular_carencia, dependentes_info):
99
+ resultado = ""
100
+ lista_completa = []
101
+ docs_carencia = obter_documentos_carencia()
102
+
103
+ documentos_padrao_titular = obter_documentos_padrao_2010_mais() if titular_nascido_2010 else obter_documentos_padrao_2009_menos()
104
+ documentos_titular = obter_documentos_titular(categoria, modalidade, documentos_padrao_titular)
105
+
106
+ if titular_carencia:
107
+ documentos_titular.extend(docs_carencia)
108
+
109
+ lista_completa.append(("TITULAR", documentos_titular))
110
+
111
+ if dependentes_info:
112
+ for dep_info in dependentes_info:
113
+ dep_nascido_2010, dep_tipo, dep_carencia = dep_info
114
+ nome_simples = simplificar_dependente(dep_tipo)
115
+ docs_dep = obter_documentos_dependente(dep_tipo, dep_nascido_2010)
116
+
117
+ if dep_carencia:
118
+ docs_dep.extend(docs_carencia)
119
+
120
+ lista_completa.append((f"Dependente: {nome_simples}", docs_dep))
121
+
122
+ for nome, documentos in lista_completa:
123
+ resultado += formatar_documentos(nome, documentos)
124
+
125
+ return resultado
126
+
127
+ def atualizar_lista_inclusos(titular_nascido_2010, categoria, modalidade, titular_carencia, dependentes_info):
128
+ lista_inclusos = []
129
+
130
+ tipo_titular = "Titular (2010+)" if titular_nascido_2010 else "Titular (2009-)"
131
+ if titular_carencia:
132
+ tipo_titular += " + carência"
133
+ lista_inclusos.append([tipo_titular, categoria, modalidade if modalidade else "PF"])
134
+
135
+ if dependentes_info:
136
+ for dep_info in dependentes_info:
137
+ dep_nascido_2010, dep_tipo, dep_carencia = dep_info
138
+ tipo_dep = f"Dep. {simplificar_dependente(dep_tipo)} (2010+)" if dep_nascido_2010 else f"Dep. {simplificar_dependente(dep_tipo)} (2009-)"
139
+ if dep_carencia:
140
+ tipo_dep += " + carência"
141
+ lista_inclusos.append([tipo_dep, "Dependente", dep_tipo])
142
+
143
+ return lista_inclusos
144
+
145
  def limpar_texto_para_copiar(texto):
 
146
  texto_limpo = re.sub('<[^<]+?>', '', texto)
147
  texto_limpo = texto_limpo.replace('</ul>', '\n').replace('</li>', '\n')
148
  texto_limpo = re.sub('\n+', '\n', texto_limpo).strip()
149
  return texto_limpo
150
 
151
+ def criar_interface():
152
+ with gr.Blocks(title="Documentos para Plano de Saúde", theme=gr.themes.Soft()) as app:
153
+ gr.Markdown("# 📋 Documentos Necessários para Plano de Saúde")
154
+ gr.Markdown("Preencha os dados abaixo para obter a lista de documentos necessários.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
+ with gr.Row():
157
+ with gr.Column():
158
+ with gr.Group():
159
+ gr.Markdown("### Titular")
160
+ categoria = gr.Radio(
161
+ choices=["PF", "CNPJ", "ADESAO"],
162
+ label="Categoria do Titular",
163
+ value="PF"
164
+ )
165
+ modalidade = gr.Dropdown(
166
+ choices=[],
167
+ label="Modalidade (se aplicável)",
168
+ interactive=False
169
+ )
170
+ with gr.Row():
171
+ titular_nascido_2010 = gr.Checkbox(label="Nasceu em 2010 ou depois?")
172
+ titular_carencia = gr.Checkbox(label="Fará compra de carência?")
173
+
174
+ with gr.Accordion("Adicionar Dependentes", open=True) as accordion_deps:
175
+ with gr.Group():
176
+ gr.Markdown("### Novo Dependente")
177
+ dep_tipo = gr.Dropdown(
178
+ choices=[
179
+ "Cônjuge ou companheiro(a)",
180
+ "Filhos(as) solteiros naturais, tutelados, enteados e adotivos",
181
+ "Filhos(as) inválidos declarados no imposto de renda do titular",
182
+ "Pai e mãe",
183
+ "Padrasto e madrasta",
184
+ "Irmãos(ãs) consanguíneos ou adotivos",
185
+ "Netos",
186
+ "Sobrinhos",
187
+ "Primos",
188
+ "Tios",
189
+ "Cunhados(as)",
190
+ "Sogro(a)",
191
+ "Genros e noras",
192
+ "Avô e avó"
193
+ ],
194
+ label="Tipo de Dependente"
195
+ )
196
+ with gr.Row():
197
+ dep_nascido_2010 = gr.Checkbox(label="Nasceu em 2010 ou depois?")
198
+ dep_carencia = gr.Checkbox(label="Fará compra de carência?")
199
+ btn_adicionar_dep = gr.Button("➕ Adicionar Dependente", variant="primary")
200
+
201
+ lista_inclusos = gr.Dataframe(
202
+ headers=["Inclusos nessa cotação", "Tipo", "Detalhes"],
203
+ datatype=["str", "str", "str"],
204
+ interactive=False,
205
+ label="Inclusos nessa cotação",
206
+ value=[["Titular (2009-)", "PF", ""]]
207
+ )
208
+ dependentes_info = gr.State([])
209
+
210
+ btn_submit = gr.Button("🔍 Gerar Lista de Documentos", variant="primary")
211
+
212
+ with gr.Column():
213
+ output = gr.HTML(label="Documentos Necessários")
214
+ texto_para_copiar = gr.Textbox(visible=False)
215
+ btn_copiar = gr.Button("📋 Copiar Lista")
216
+ status_copia = gr.Textbox(label="Status", interactive=False, visible=False)
217
 
218
+ def atualizar_modalidades(categoria):
219
+ if categoria == "CNPJ":
220
+ return gr.Dropdown(choices=["MEI", "OUTROS"], label="Modalidade CNPJ", interactive=True)
221
+ elif categoria == "ADESAO":
222
+ return gr.Dropdown(
223
+ choices=["ENTIDADE ABERTA", "ESTUDANTE", "TRABALHADOR", "PROFISSIONAL LIBERAL", "APOSENTADO"],
224
+ label="Modalidade Adesão",
225
+ interactive=True
226
+ )
227
+ else:
228
+ return gr.Dropdown(choices=[], label="Modalidade (não aplicável)", interactive=False)
229
 
230
+ categoria.change(
231
+ atualizar_modalidades,
232
+ inputs=categoria,
233
+ outputs=modalidade
234
+ )
235
 
236
+ inputs_lista = [titular_nascido_2010, categoria, modalidade, titular_carencia, dependentes_info]
237
+ for input_component in inputs_lista:
238
+ input_component.change(
239
+ atualizar_lista_inclusos,
240
+ inputs=inputs_lista,
241
+ outputs=lista_inclusos
242
+ )
243
+
244
+ btn_adicionar_dep.click(
245
+ lambda dep_info, dep_nasc, dep_tipo, dep_carencia: (dep_info + [(dep_nasc, dep_tipo, dep_carencia)]),
246
+ inputs=[dependentes_info, dep_nascido_2010, dep_tipo, dep_carencia],
247
+ outputs=dependentes_info
248
+ ).then(
249
+ atualizar_lista_inclusos,
250
+ inputs=inputs_lista,
251
+ outputs=lista_inclusos
252
+ )
253
 
 
254
  btn_submit.click(
255
  processar_documentos,
256
+ inputs=[
257
+ titular_nascido_2010,
258
+ categoria,
259
+ modalidade,
260
+ titular_carencia,
261
+ dependentes_info
262
+ ],
263
  outputs=output
264
  ).then(
265
  limpar_texto_para_copiar,
 
267
  outputs=texto_para_copiar
268
  )
269
 
 
270
  btn_copiar.click(
271
+ lambda: None,
272
+ inputs=None,
273
  outputs=status_copia,
274
  js="""
275
+ async () => {
276
+ const texto = document.querySelector("#texto-para-copiar textarea").value;
277
  try {
278
  await navigator.clipboard.writeText(texto);
279
  return "✅ Copiado para área de transferência!";
 
294
  status_copia
295
  )
296
 
297
+ return app
298
+
299
+ # Criação e lançamento da interface
300
+ app = criar_interface()
301
+ app.launch()