Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions documentacao.txt
Original file line number Diff line number Diff line change
@@ -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 <emit> e </emit>, e considerei todas as tags dentro dela como atributos de um objeto, e fiz o mesmo para a tag <dest> e </dest>.

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);

154 changes: 154 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -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()