From d52ee29e2db0d0f3d649e2b167328d00af2ba5b2 Mon Sep 17 00:00:00 2001
From: Renzo Fraga <130428183+Kenko2002@users.noreply.github.com>
Date: Sat, 2 Sep 2023 00:49:03 -0300
Subject: [PATCH 1/2] =?UTF-8?q?Solu=C3=A7=C3=A3o.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Minha Solução para o problema apresentado.
---
documentacao.txt | 44 ++++++++++++++
main (2).py | 154 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 198 insertions(+)
create mode 100644 documentacao.txt
create mode 100644 main (2).py
diff --git a/documentacao.txt b/documentacao.txt
new file mode 100644
index 0000000..881c9fc
--- /dev/null
+++ b/documentacao.txt
@@ -0,0 +1,44 @@
+O Problema:
+ A princípio, o problema abordado seria a necessidade da leitura e organização dos dados dos xmls.
+
+Ferramentas de Solução:
+ Linguagem Python
+ Biblioteca xmltodict
+ Conector de banco de dados psycopg2
+ banco de dados SQL
+
+A solução:
+ Passo 1: Em primeiro lugar, o XML fornecido está extremamente mal organizado e ininteligível, então eu passei ele por um formatador automático de HTML, https://www.freeformatter.com/html-formatter.html, o que tornou eles mais legíveis.
+
+ Passo 2: Entender como o Emitente e o Destinatário estão estruturados dentro do xml. basicamente eu só procurei a tag e , e considerei todas as tags dentro dela como atributos de um objeto, e fiz o mesmo para a tag e .
+
+ Passo 3: a noção de orientação a objetos casa muito bem com a Estrutura de Dados "Dicionário",
+amplamente usada no python, então eu procurei uma biblioteca que convertesse XML para Dicionário.
+Depois disso eu converti os arquivos de XML para Dicionários dentro do código.
+
+ Passo 4:
+ Após isso, eu configurei um banco de dados PostgreSQL para acomodar os dados, já que esse é um diferencial importante. O site que usei para isso é o Elephant SQL. https://www.elephantsql.com/
+ As credenciais do banco de dados estão na variavel connection/conn do código.
+ Após a leitura dos dados pro usuário, o sistema copia tudo que foi mostrado pro usuário e enviar pro banco de dados fazendo um insert simples.
+
+ Create do banco de dados:
+ CREATE TABLE VALORES_E_VENCIMENTOS_BOLETOS (
+ data_validade DATE,
+ valor_boleto DECIMAL(10, 2)
+ );
+ CREATE TABLE CLIENTES (
+ nome VARCHAR(100),
+ cpf VARCHAR(30),
+ cnpj VARCHAR(30),
+ endereco VARCHAR(200),
+ );
+
+ TEMPLATE DE INSERT:
+-- Inserção vazia na tabela VALORES_E_VENCIMENTOS_BOLETOS
+INSERT INTO VALORES_E_VENCIMENTOS_BOLETOS (data_validade, valor_boleto)
+VALUES (NULL, NULL);
+
+-- Inserção vazia na tabela CLIENTES
+INSERT INTO CLIENTES (nome, cpf, cnpj, endereco)
+VALUES (NULL, NULL, NULL, NULL);
+
diff --git a/main (2).py b/main (2).py
new file mode 100644
index 0000000..5a71fdf
--- /dev/null
+++ b/main (2).py
@@ -0,0 +1,154 @@
+import xmltodict
+import psycopg2
+
+def abrir_conexão_bd():
+ connection="ERRO"
+ dbname = "eggvfinq"
+ user = "eggvfinq"
+ password = "9iD3LdnjQpf4zd-OBSJvo2FM55tDppev"
+ host = "silly.db.elephantsql.com"
+ port = "5432" # Porta padrão do PostgreSQL
+
+ try:
+ connection = psycopg2.connect(
+ dbname=dbname,
+ user=user,
+ password=password,
+ host=host,
+ port=port
+ )
+ print("Conexão estabelecida com sucesso!")
+
+ # Aqui você pode realizar operações no banco de dados usando a conexão
+
+ except psycopg2.Error as e:
+ print("Erro ao conectar ao banco de dados:", e)
+ return connection
+
+def inserir_registro_tabela_valores_e_vencimentos_boletos(valor,vencimento,connection):
+ cursor = connection.cursor()
+ query = "INSERT INTO VALORES_E_VENCIMENTOS_BOLETOS (data_validade, valor_boleto) VALUES (%s,%s);"
+ data_to_insert = (vencimento,valor)
+ cursor.execute(query, data_to_insert)
+ connection.commit()
+ print("Inserção realizada com sucesso!")
+
+def inserir_registro_tabela_clientes(nome, cpf, cnpj, endereco,connection):
+ cursor = connection.cursor()
+ query = "INSERT INTO CLIENTES (nome, cpf, cnpj, endereco) VALUES (%s, %s, %s, %s);"
+ data_to_insert = (nome, cpf, cnpj, endereco)
+ cursor.execute(query, data_to_insert)
+ connection.commit()
+ print("Inserção realizada com sucesso!")
+
+def ler_arquivo(patharquivo):
+ with open(patharquivo, 'r', encoding='utf-8') as xml_file:
+ xml_string = xml_file.read()
+ dicionario = xmltodict.parse(xml_string)
+ return dicionario
+
+def buscar_arquivo_de_nota_fiscal(cpf_cnpj_fornecedor):
+ dic_arquivo1 = ler_arquivo(
+ "32211207872718000117550010000217781877120005-nfe.xml")
+ dic_arquivo2 = ler_arquivo("NFe-002-3103.xml")
+
+ emitente1 = dic_arquivo1['nfeProc']['NFe']['infNFe']['emit']
+ emitente2 = dic_arquivo2['nfeProc']['NFe']['infNFe']['emit']
+
+ if 'CNPJ' in emitente1:
+ if emitente1['CNPJ'] == cpf_cnpj_fornecedor:
+ print("Emitente 1/CNPJ: " + emitente1['CNPJ'])
+ return dic_arquivo1
+ if 'CPF' in emitente1:
+ if emitente1['CPF'] == cpf_cnpj_fornecedor:
+ print("Emitente 1/CPF: " + emitente1['CPF'])
+ return dic_arquivo1
+ if 'CNPJ' in emitente2:
+ if emitente2['CNPJ'] == cpf_cnpj_fornecedor:
+ print("Emitente 2/CNPJ: " + emitente2['CNPJ'])
+ return dic_arquivo2
+ if 'CPF' in emitente2:
+ if emitente2['CPF'] == cpf_cnpj_fornecedor:
+ print("Emitente 2/CPF: " + emitente2['CPF'])
+ return dic_arquivo2
+
+def printar_valores_e_vencimento_dos_boletos(dic_arquivo,connection):
+ d_vencimento=dic_arquivo['nfeProc']['NFe']['infNFe']["cobr"]["dup"]["dVenc"]
+ v_dup=dic_arquivo['nfeProc']['NFe']['infNFe']["cobr"]["dup"]["vDup"]
+ print("Vencimento: "+d_vencimento)
+ print("Valor do Boleto: R$"+v_dup)
+ inserir_registro_tabela_valores_e_vencimentos_boletos(v_dup,d_vencimento,connection)
+
+def printar_nome_cpf_ou_cnpj_endereco_dos_clientes(dic_arquivo,connection):
+ cpf=""
+ cnpj=""
+
+ dest=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['xNome']
+ print("Destinatário: "+dest)
+ if 'CNPJ' in dic_arquivo['nfeProc']['NFe']['infNFe']['dest']:
+ cnpj=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['CNPJ']
+ print("CNPJ:"+cnpj)
+ if 'CPF' in dic_arquivo['nfeProc']['NFe']['infNFe']['dest']:
+ cpf=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['CPF']
+ print("CPF:"+cpf)
+ print("ENDEREÇO:")
+
+ logr=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['xLgr']
+ numero=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['nro']
+ bairro=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['xBairro']
+ num_municipio=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['cMun']
+ municipio=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['xMun']
+ uf=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['UF']
+ cep=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['CEP']
+ num_pais=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['cPais']
+ pais=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['xPais']
+ telefone=dic_arquivo['nfeProc']['NFe']['infNFe']['dest']['enderDest']['fone']
+
+ print("Logradouro:"+logr)
+ print("Número:"+numero)
+ print("Bairro:"+bairro)
+ print("NumMunicípio:"+num_municipio)
+ print("Município:"+municipio)
+ print("UF:"+uf)
+ print("CEP:"+cep)
+ print("numPaís:"+num_pais)
+ print("País:"+pais)
+ print("Telefone:"+telefone)
+ inserir_registro_tabela_clientes(dest, cpf, cnpj,(municipio+"-"+logr+"-"+numero),connection)
+
+def main():
+ '''faça um programa que informado o CPF leia todos os arquivos buscando um fornecedor com esse CPF, selecionado o arquivo mostre as seguintes opções: 1) Listar os valores e data de Vencimento dos boletos presentes em um nota fiscal conforme o CPF ou CNPJ de um fornecedor.2) Apresentar o nome, identificador (CPF ou CNPJ), endereço dos clientes de um fornecedor.
+
+ 0-conectar ao banco de dados
+ 1-informar_cpf
+ 2-buscar_arquivo_de_nota_fiscal(cpf_cnpj_fornecedor)
+ 3-pedir input de 1 ou 2.
+ 3.1- caso 1: printar_valores_e_vencimento_dos_boletos(dic_arquivo)
+ 3.2- caso 2: printar_nome_cpf_ou_cnpj_endereco_dos_clientes(dic_arquivo)'''
+
+ #0
+ conn=abrir_conexão_bd()
+ #1
+ cpf_cnpj = input("Insira o CPF/CNPJ do fornecedor: ")
+ #2
+ dic_arquivo_alvo = buscar_arquivo_de_nota_fiscal(cpf_cnpj)
+ #print(dic_arquivo_alvo) descomente para validar a variavel dic_arquivo_alvo.
+
+ #3
+ teclado = ""
+ while teclado != "1" and teclado != "2":
+ teclado = input(
+ "1-Mostrar Valores e Vencimentos dos boletos \n2-Mostrar Nome,CPF/CNPJ e endereço dos clientes"
+ )
+ if teclado == "1": #3.1
+ printar_valores_e_vencimento_dos_boletos(dic_arquivo_alvo,conn)
+ #inserir dados lidos no banco de dados
+ if teclado == "2": #3.2
+ printar_nome_cpf_ou_cnpj_endereco_dos_clientes(dic_arquivo_alvo,conn)
+ #inserir dados lidos no banco de dados
+
+
+main()
+
+
+
From fba83fa23899a76714db72a3e8fa20e54ada39c3 Mon Sep 17 00:00:00 2001
From: Renzo Fraga <130428183+Kenko2002@users.noreply.github.com>
Date: Sat, 2 Sep 2023 00:49:22 -0300
Subject: [PATCH 2/2] Rename main (2).py to main.py
---
main (2).py => main.py | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename main (2).py => main.py (100%)
diff --git a/main (2).py b/main.py
similarity index 100%
rename from main (2).py
rename to main.py