From 40cd01b858ae09770ddfb3e8c157d18ddd941c68 Mon Sep 17 00:00:00 2001 From: Lucas_Moraes_Wize Date: Tue, 29 Mar 2022 20:20:11 -0300 Subject: [PATCH 1/7] =?UTF-8?q?Feature:=20Listar=20os=20valores=20e=20data?= =?UTF-8?q?=20de=20Vencimento=20dos=20boletos=20presentes=20em=20um=20nota?= =?UTF-8?q?=20fiscal=20conforme=20o=20CPF=20ou=20CNPJ=20de=20um=20forneced?= =?UTF-8?q?or.=20Feature:=20Apresentar=20o=20nome,=20identificador=20(CPF?= =?UTF-8?q?=20ou=20CNPJ),=20endere=C3=A7o=20dos=20clientes=20de=20um=20for?= =?UTF-8?q?necedor.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2718000117550010000217781877120005-nfe.xml | 2 - NFe-002-3103.xml | 11 - NotaFiscal.py | 162 +++++++++ __pycache__/NotaFiscal.cpython-38.pyc | Bin 0 -> 4976 bytes __pycache__/Nota_fiscal.cpython-38.pyc | Bin 0 -> 960 bytes ...2718000117550010000217781877120005-nfe.xml | 277 ++++++++++++++++ notasFiscais/NFe-002-3103.xml | 311 ++++++++++++++++++ parser.py | 45 +++ 8 files changed, 795 insertions(+), 13 deletions(-) delete mode 100644 32211207872718000117550010000217781877120005-nfe.xml delete mode 100644 NFe-002-3103.xml create mode 100644 NotaFiscal.py create mode 100644 __pycache__/NotaFiscal.cpython-38.pyc create mode 100644 __pycache__/Nota_fiscal.cpython-38.pyc create mode 100644 notasFiscais/32211207872718000117550010000217781877120005-nfe.xml create mode 100644 notasFiscais/NFe-002-3103.xml create mode 100644 parser.py diff --git a/32211207872718000117550010000217781877120005-nfe.xml b/32211207872718000117550010000217781877120005-nfe.xml deleted file mode 100644 index 0b01f56..0000000 --- a/32211207872718000117550010000217781877120005-nfe.xml +++ /dev/null @@ -1,2 +0,0 @@ -3287712000VENDA MERCAD.ADQ.TERCEIROS551217782021-12-01T19:03:21-03:002021-12-01T19:03:21-03:0011320130811511010MeLinux 6.307872718000117COMERCIAL S.R.DE ALIMENTOS LTDA-MESR ALIMENTOSR.ODONIA DA COSTA MACHADO TOLEDO56QUADRA 1 LOTE 5TIRADENTES3201308CARIACICAES291435291058BRASIL2733363026082384975317197072000173JEFERSON SIMAO DE OLIVEIRA - MERUA SAO JOAO49ITACIBA3201308CARIACICAES291502301058BRASIL279965021211082917825001378SEM GTINFILE MERLUZA ARGENTINA INTERF.CX 18 c/ 18 KG030474005102CX1503.82503.82SEM GTINCX1827.991220358.82207.4617.0035.279995301503.820.653.2701503.823.0015.110001957896481907388CUPIM MAGRO FRISA CX -+ 18KG0201300017084005405KG21.7129.12989406632.417896481907388KG21.7129.1298940610609995301632.410.654.1101632.413.0018.97207.4635.270.000.000.000.000.000.001136.230.000.000.000.000.000.007.3834.080.001136.23907872718000117COMERCIAL S.R.DE ALIMENTOS LTDA-ME082384975RUA ODONIA DA COSTA MACHADO TOLEDO, 41 QD 1 LOTE 5 TIRADENTECARIACICAES23DIVERSASDIVERSAS40.1060217781136.230.001136.230012022-12-15568.110022022-12-22568.12151136.23Cod.Dest: 7452 Fantasia: REST.ESPA.GRILL Faturista: IGOR REIS # Forma Pag: BOLETO # Vendedor: TACIANI (27)99735-5228 Num.Ped: 102667 # Doc.emitido por ME/EPP optante do SIMPLES NACIONAL; nao gera credito fiscal de IPI e ISS # RUA DA FEIRA # sem email cadastrado para envio do XML # # Confira no ato da entrega, evite reclamacoes posteriores19495981000113OTMA SOLUCOES LTDAcontato@otmasolucoes.com.br2721417943yU29u4Sva8be/dmxDzD7eyMIOaY=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 -1SVRS202111190951322112078727180001175500100002177818771200052021-12-01T19:03:22-03:00332210083442441yU29u4Sva8be/dmxDzD7eyMIOaY=100Autorizado o uso da NF-e \ No newline at end of file diff --git a/NFe-002-3103.xml b/NFe-002-3103.xml deleted file mode 100644 index 831d193..0000000 --- a/NFe-002-3103.xml +++ /dev/null @@ -1,11 +0,0 @@ -3100464032Vendas a prazo55231032019-04-10T17:24:03-02:002019-04-11T17:17:30-02:001131702061171101000106273476000182MECA Office Mobil. Eireli-MEMECA Office Mobil. Eireli-MEAV. MARCOS DE FREITAS COSTA1055DANIEL FOSECA3170206UberlandiaMG384003281058BRASIL34323855857022916720058125587387000155HLTS ENGENHARIA E CONSTRUCOES LTDARUA MACHADO DE ASSIS1324LIDICE3170206UberlandiaMG384000811058BRASIL34322359661702177134005400331SEM GTINCADEIRA GIRATORIA S/ BRACO ALMOFADADA PRETO940190905102UN2165.00000330.00SEM GTINUN2165.00000177.6801020808IMOBILIZADO IMOB - 2317 CADEIRA GIRATORIA S/ BRACO ALMOFADADA PRETO - IMOBILIZADO EQUIP. MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO.01228SEM GTINCADEIRA GIRATORIA C/ BRACO ALMOFADADA PRETO940190905102UN1215.00000215.00SEM GTINUN1215.00000150.6101020808IMOBILIZADO EQUIP/MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO01324SEM GTINBANQUETA ALTA 70CM PARA BALCAO ASSENTO 30 OU940190905102PC190.0000090.00SEM GTINPC190.00000121.190102080840CM NA COR PRETA - IMOBILIZADO EQUIP./MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO01644SEM GTINESTANTE ACO C/ 06 PRATELEIRAS 0,93X040X1,98M940690205102PC2234.00000468.00SEM GTINPC2234.00000145.8701020808(REFORCADA) AMAPA - IMOBILIZADO.0.000.000.000.000.000.000.000.001103.000.000.000.000.000.000.000.000.000.001103.00195.3506VOLUMEVARIAS0.0000.0000000031031103.000.001103.000012019-05-111103.00141103.000.00ORDEM DE FORNECIMENTO 36994 - 28DD - INFORMACOES COMPLEMENTARES a seguinte informacao. EMPRESA ENQUADRADA NO SIMPLES NACIONAL. NAO GERA CREDITO DE IPI/ISS. GERA CREDITO DE ICMS. Trib aprox R$: 54,84 Federal 140,51 Estadual Fonte: IBPT empresometro.com.br S3A6R4ngqVwH6QNCAHyRuI529RIAr7Nyk=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 - 1 - 14.2.26 - 31190406273476000182550020000031031004640327 - 2019-04-10T17:23:27-03:00 - 131193257591884 - ngqVwH6QNCAHyRuI529RIAr7Nyk= - 100 - Autorizado o uso da NF-e - - diff --git a/NotaFiscal.py b/NotaFiscal.py new file mode 100644 index 0000000..9a6104f --- /dev/null +++ b/NotaFiscal.py @@ -0,0 +1,162 @@ +# Biblioteca para trabalhar com XML +from cmath import exp +import xml.etree.ElementTree as ET + +class NotaFiscal: + def __init__(self, input_path: str): + self.xml_path : str = input_path + self.namespace: str = None + self.root : ET.Element = self.xml_to_ElementTree(input_path) + + def __str__(self) -> str: + str = ET.tostring(self.root, encoding='utf8').decode('utf8') + return str + + # Extrai ElementTree da XML + # ElementTree é uma árvore de elementos que representa do XML + # 'elemet' ou 'elemento' da árvore será utilizado para referênciar + # os galhoes ou folhas da árvore principal guardada em self.root + def xml_to_ElementTree(self,input_path: str) -> ET.Element: + try: + root_with_namespace : ET.Element = ET.iterparse(input_path) + except: + print('Erro no XML ', input_path ) + exit(1) + root : ET.Element = self.remove_namespace_from_nota_fiscal(root_with_namespace) + return root + + # Retorna ElementTree sem nameSpace + def remove_namespace_from_nota_fiscal(self, input: ET.Element) -> ET.Element: + + try: + for _, el in input: + prefix, has_namespace, postfix = el.tag.partition('}') + if has_namespace: + if postfix == 'NFe': + self.set_namespace_nota_fiscal(has_namespace) + el.tag = postfix # strip all namespaces + except: + print('Erro no XML ', self.xml_path ) + exit(1) + + root : ET.Element = input.root + return root + + # Guarda Namespace da nota fiscal + def set_namespace_nota_fiscal(self, namespace: str) -> None: + self.namespace = namespace + + # --------- EMIT --------- + + # Retorna cnpj do emissor da nota fiscal caso o + # mesmo seja uma pessoa jurídica + def get_emit_cnpj(self) -> str: + cnpj = self.get_text_from_xml_tree_element('./NFe/infNFe/emit/CNPJ') + return cnpj + + # Retorna cpf do emissor da nota fiscal caso o + # mesmo seja uma pessoa física + def get_emit_cpf(self) -> str: + cpf = self.get_text_from_xml_tree_element('./NFe/infNFe/emit/CPF') + return cpf + + # Retorna identificador do emissor + def get_emit_identifier(self) -> str: + cnpj = self.get_emit_cnpj() + if(cnpj): + return cnpj + else: + return self.get_emit_cpf() + + # Retorna endereço do emissor + def get_emit_enderEmit(self) -> dict: + enderEmit = self.get_dict_from_xml_tree_element('./NFe/infNFe/emit/enderEmit') + return enderEmit + + # --------- DEST --------- + + # Retorna cnpj do destinatário da nota fiscal caso o + # mesmo seja uma pessoa jurídica + def get_dest_cnpj(self) -> str: + cnpj = self.get_text_from_xml_tree_element('./NFe/infNFe/dest/CNPJ') + return cnpj + + # Retorna cpf do destinatário da nota fiscal caso o + # mesmo seja uma pessoa física + def get_dest_cpf(self) -> str: + cnpj = self.get_text_from_xml_tree_element('./NFe/infNFe/dest/CPF') + return cnpj + + # Retorna identificador do destinatário + def get_dest_identifier(self) -> str: + cnpj = self.get_dest_cnpj() + if(cnpj): + return cnpj + else: + return self.get_dest_cpf() + + # Retorna nome do destinatário + def get_dest_name(self) -> str: + name = self.get_text_from_xml_tree_element('./NFe/infNFe/dest/xNome') + return name + + # Retorna endereço do destinatário + def get_dest_enderDest(self) -> dict: + enderDest = self.get_dict_from_xml_tree_element('./NFe/infNFe/dest/enderDest') + return enderDest + + # --------- Specific methods --------- + + # Retorna data de vencimento da nota fiscal + def get_data_vencimento(self) -> str: + data_vencimento = self.get_text_from_xml_tree_element('./NFe/infNFe/cobr/dup/dVenc') + return data_vencimento + + # Retorna valor total da nota fiscal + # (impostos + valor unitário*unidades de cada produto) + def get_valor_total(self) -> str: + valor_total_nota = self.get_text_from_xml_tree_element('./NFe/infNFe/total/ICMSTot/vNF') + return valor_total_nota + + # Retorna lista de faturas contidas em uma + # nota fiscal + def get_faturas(self) -> dict: + faturas = [] + for tree_element_fatura in self.root.findall('./NFe/infNFe/cobr/dup'): + fatura = {} + fatura[tree_element_fatura.find('nDup').tag] = tree_element_fatura.find('nDup').text + fatura['Validade'] = tree_element_fatura.find('dVenc').text + fatura['Valor'] = tree_element_fatura.find('vDup').text + faturas.append(fatura) + return faturas + + # Exibe faturas da nota fiscal + # Listar os valores e data de Vencimento dos boletos + # presentes em um nota fiscal + def print_fatura(self) -> None: + faturas = self.get_faturas() + for fatura in faturas: + print("Valor: R$", fatura['vDup']) + print("Data de cencimento: ", fatura['dVenc']) + + # --------- UTILS --------- + + # Retorna o texto de um determinado elemento + def get_text_from_xml_tree_element(self, tree_path: str) -> str: + xml_tree_element = self.root.find(tree_path) + if xml_tree_element.tag: + return xml_tree_element.text + return None + + # Retorna retorna dicionário equivalente + # a um elemento + def get_dict_from_xml_tree_element(self, tree_path: str) -> dict: + result_dict = {} + xml_tree_element = self.root.find(tree_path) + for chield in xml_tree_element: + result_dict[chield.tag] = chield.text + return result_dict + + + + \ No newline at end of file diff --git a/__pycache__/NotaFiscal.cpython-38.pyc b/__pycache__/NotaFiscal.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65e8df1147aa716b70f89627e62e98068c62cca8 GIT binary patch literal 4976 zcmbtY&2!tv72gFwkd!Ej*0=0fr4#3ai7TdUn!2tglNs6WG?Q>LwVNiGbWoTJT2M#= zT0pA8Ay3Zq*6E>#UUHCb^}mE`PWcyn>hCQe5&-3RG$9Aeefx#?e((2o-|{a@OA8F2 z|NUqG$!LSIA4tf4bO;~g3ExK{nBaXj;1=gp*ZSH(*BEC5!zyw1M<#S(e8+_GOtVa( zJz}lWkC??;Jl5UQpwlHG`WLmiE0NZbMp6r8mV}kT%kh zZ;N*zZ9;3ZwI$w#v;|vr@gA(WBYp{a8**LAyP^&Gx>y3h@5c)rKXM*=Vb|#c=LK&V z97lHGL3pNdt>NXL1ogFYdMv{DIr<0ihN)y%kyF|gZ|Zgeb% zUGQl7A)84XW%G4ZB6bKH4>bXH{YyIo&(8UTk2!GEJF#&b_3mP+iaYH3!W%vX2HJzi zRweSoNJ5rXtPz_6`U|(ENeY};N1rk_DQeVKwr#Z9HenEw28?g;(MnEpH2{lHx2&Vc zxrSJ9Q z_oDVdO20Yun_qtRY4b-ysa2BK@MBfI$d&Lz=*Fc0W=65$o_bMyOS%L9#I>isw|mkb z*h8?*?j>|H6a>lyYn4b~|HF$8W-}CE1#n~qFI~kGlF^K7ybiZ6pj_ain;D4ai3W<5 z6usy1qD7~8^&yNt9`pO`Zy$cGO*BH`5a^M+zt$(lq%<+dC25YaM}4Eo4;B4O=Rj|4 zj&++InLxOiBCHD?l);V$j7!+rW*GBBb5b6cX_xD~;1f&lJapwc-Yv0@vQ|0PBj;&c z1+~h-Zj3$4PF7>H6UM8_>b;nkbkA)JK${@i_QCiLXIBATZ)g1ZRQb^ zC5SDqCZ@rYEJ9H-3m&-x@eZDl)?s{fJEPf40i26_9dnfu#4Z0h|D z-ke51sJ)djBRA}-s;^(7`sWYjExav-)zZ5`uc%vX_R^sD`p9PSAImAQ8Y6!)Zm6T z+PO@-*@QVIU*Y*1^YFPt;mQYa+lBju*L{imFA%Oy=M;@vnHn`6@{nvwj)B4+H$V2O z=H!WtBQ_zjqQj-2D~{4Q#nDbqwIWBS!>+1To}-CYDMv3=N|7^pThM!))2T?#i&1kb zU74Kk;yv;`Dqc!X^|Be)z9P+jlAMJJb4tE~oSQjv(qiq?4l<~0bjJpr$VJ-C+)BMp z4#G>_O2e+IUOsk|dWz)tp{RTt@63mXYA(dQ3J;oTPiOXW%4Sml3XlBQpQmxxe&&l+ke{s?9pRC zYM*rS`+eiY>H89CIR>e;qNx2cA(XxK{f*tpzt zaEEY0Yc7%u!0P7l-;JYBayRL6`FJ- zozEA^=INf8WEDiG&nMq^)3!d>y0y zjVCpM(qP;yTLmAzJPFKQ)yQQO8Om*RrXT{eBr22{;5OXXm>6T@P#bF~^*wg9Hpbs0 zNt%>3h-^_-;dVypvm}G8Md^meee8wEOXME4nB4=B&;Eef_I9h z{X~LugRb6mIM{Z)VA}&<9QUbSv+bi}r=Rply1>aLD%Pk_7s+z^pMbjI$!%(eWU?&1#jcQg=Y?qzuAZ2YGf~qU>(wKMwr!L`~LWrcGI` Wmbgr#xU!dE_Yp0t(m!0hwEqJut!Uc- literal 0 HcmV?d00001 diff --git a/__pycache__/Nota_fiscal.cpython-38.pyc b/__pycache__/Nota_fiscal.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a4b035bdd5c23de904f310af7f9f3ab42dd1e31 GIT binary patch literal 960 zcmZ`&y>8S%5T04vcg}?bbcCd#q_G4!+DHhYKty*LM9pyA&Y;~4Hy@!yK;y4lA;DAYLLQ28oy(}AhcUA*2!f| zXg%G(1liLmp|1J$aqV(-GHr^y%+L>}v-!fQdG00!4R9xHbE~&>nr%`owxFPeD{S$a zZK2^1Zg8AMGW}AO0m47BCf92Aw}p>wUAs*9xH094Wyl+_DSdwJjV5(vM&+W&n~^rn zCs)r$))aL$AAL5nNj}eQ9{l4`hxG3Jt521h&ZbT&25MqbfIYm}>X!W}DUj2*!u|gl z%ke;PjY}HqN?gNIwBisfLuQc|2S+j?8jX?tQ{%!YQ5ZtT&KhHTR2QaMsWo;JQX6y{ zP67@v#fzt1X7_jWe}>NpKr=TugLm+8i`Zc+&Tt1viyc_v`Jm<3BF3Kh20A`+`Kj#X z&e`cP#rlNdqsCd86q9MG@6q*rr6{S?km?%VCtysZhj{V0OZv8Iob`G8v%E4&`GHbZ ztrsQR50pAzZ9Tk?v?~ECSWu>^8Y$ldtSx-KpSG7w^H)i*s qG?kgTBeG=@LUO$mv+H!j3v0sFPK(fy`}p+Lis)+w4=-jIrQ$arj?k+B literal 0 HcmV?d00001 diff --git a/notasFiscais/32211207872718000117550010000217781877120005-nfe.xml b/notasFiscais/32211207872718000117550010000217781877120005-nfe.xml new file mode 100644 index 0000000..a9d9335 --- /dev/null +++ b/notasFiscais/32211207872718000117550010000217781877120005-nfe.xml @@ -0,0 +1,277 @@ + + + + + + 32 + 87712000 + VENDA MERCAD.ADQ.TERCEIROS + 55 + 1 + 21778 + 2021-12-01T19:03:21-03:00 + 2021-12-01T19:03:21-03:00 + 1 + 1 + 3201308 + 1 + 1 + 5 + 1 + 1 + 0 + 1 + 0 + MeLinux 6.3 + + + 07872718000117 + COMERCIAL S.R.DE ALIMENTOS LTDA-ME + SR ALIMENTOS + + R.ODONIA DA COSTA MACHADO TOLEDO + 56 + QUADRA 1 LOTE 5 + TIRADENTES + 3201308 + CARIACICA + ES + 29143529 + 1058 + BRASIL + 2733363026 + + 082384975 + 3 + + + 17197072000173 + JEFERSON SIMAO DE OLIVEIRA - ME + + RUA SAO JOAO + 49 + ITACIBA + 3201308 + CARIACICA + ES + 29150230 + 1058 + BRASIL + 27996502121 + + 1 + 082917825 + + + + 001378 + SEM GTIN + FILE MERLUZA ARGENTINA INTERF.CX 18 c/ 18 KG + 03047400 + 5102 + CX + 1 + 503.82 + 503.82 + SEM GTIN + CX + 18 + 27.99 + 1 + + + + + 2 + 20 + 3 + 58.82 + 207.46 + 17.00 + 35.27 + + + + 999 + + 53 + + + + + 01 + 503.82 + 0.65 + 3.27 + + + + + 01 + 503.82 + 3.00 + 15.11 + + + + + + + 000195 + 7896481907388 + CUPIM MAGRO FRISA CX -+ 18KG + 02013000 + 1708400 + 5405 + KG + 21.71 + 29.12989406 + 632.41 + 7896481907388 + KG + 21.71 + 29.12989406 + 1 + + + + + 0 + 60 + + + + 999 + + 53 + + + + + 01 + 632.41 + 0.65 + 4.11 + + + + + 01 + 632.41 + 3.00 + 18.97 + + + + + + + 207.46 + 35.27 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 1136.23 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 7.38 + 34.08 + 0.00 + 1136.23 + + + + 9 + + 07872718000117 + COMERCIAL S.R.DE ALIMENTOS LTDA-ME + 082384975 + RUA ODONIA DA COSTA MACHADO TOLEDO, 41 QD 1 LOTE 5 TIRADENTE + CARIACICA + ES + + + 23 + DIVERSAS + DIVERSAS + 40.106 + + + + + 021778 + 1136.23 + 0.00 + 1136.23 + + + 001 + 2022-12-15 + 568.11 + + + 002 + 2022-12-22 + 568.12 + + + + + 15 + 1136.23 + + + + Cod.Dest: 7452 Fantasia: REST.ESPA.GRILL Faturista: IGOR REIS # Forma Pag: BOLETO # Vendedor: TACIANI (27)99735-5228 Num.Ped: 102667 # Doc.emitido por ME/EPP optante do SIMPLES NACIONAL; nao gera credito fiscal de IPI e ISS # RUA DA FEIRA # sem email cadastrado para envio do XML # # Confira no ato da entrega, evite reclamacoes posteriores + + + 19495981000113 + OTMA SOLUCOES LTDA + contato@otmasolucoes.com.br + 2721417943 + + + + + + + + + + + + + yU29u4Sva8be/dmxDzD7eyMIOaY= + + + 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 + + + + + + + 1 + SVRS202111190951 + 32211207872718000117550010000217781877120005 + 2021-12-01T19:03:22-03:00 + 332210083442441 + yU29u4Sva8be/dmxDzD7eyMIOaY= + 100 + Autorizado o uso da NF-e + + + \ No newline at end of file diff --git a/notasFiscais/NFe-002-3103.xml b/notasFiscais/NFe-002-3103.xml new file mode 100644 index 0000000..ec2ae56 --- /dev/null +++ b/notasFiscais/NFe-002-3103.xml @@ -0,0 +1,311 @@ + + + + + + 31 + 00464032 + Vendas a prazo + 55 + 2 + 3103 + 2019-04-10T17:24:03-02:00 + 2019-04-11T17:17:30-02:00 + 1 + 1 + 3170206 + 1 + 1 + 7 + 1 + 1 + 0 + 1 + 0 + 001 + + + 06273476000182 + MECA Office Mobil. Eireli-ME + MECA Office Mobil. Eireli-ME + + AV. MARCOS DE FREITAS COSTA + 1055 + DANIEL FOSECA + 3170206 + Uberlandia + MG + 38400328 + 1058 + BRASIL + 3432385585 + + 7022916720058 + 1 + + + 25587387000155 + HLTS ENGENHARIA E CONSTRUCOES LTDA + + RUA MACHADO DE ASSIS + 1324 + LIDICE + 3170206 + Uberlandia + MG + 38400081 + 1058 + BRASIL + 3432235966 + + 1 + 7021771340054 + + + + 00331 + SEM GTIN + CADEIRA GIRATORIA S/ BRACO ALMOFADADA PRETO + 94019090 + 5102 + UN + 2 + 165.00000 + 330.00 + SEM GTIN + UN + 2 + 165.00000 + 1 + + + 77.68 + + + 0 + 102 + + + + + 08 + + + + + 08 + + + + IMOBILIZADO IMOB - 2317 CADEIRA GIRATORIA S/ BRACO ALMOFADADA PRETO - IMOBILIZADO EQUIP. MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO. + + + + 01228 + SEM GTIN + CADEIRA GIRATORIA C/ BRACO ALMOFADADA PRETO + 94019090 + 5102 + UN + 1 + 215.00000 + 215.00 + SEM GTIN + UN + 1 + 215.00000 + 1 + + + 50.61 + + + 0 + 102 + + + + + 08 + + + + + 08 + + + + IMOBILIZADO EQUIP/MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO + + + + 01324 + SEM GTIN + BANQUETA ALTA 70CM PARA BALCAO ASSENTO 30 OU + 94019090 + 5102 + PC + 1 + 90.00000 + 90.00 + SEM GTIN + PC + 1 + 90.00000 + 1 + + + 21.19 + + + 0 + 102 + + + + + 08 + + + + + 08 + + + + 40CM NA COR PRETA - IMOBILIZADO EQUIP./MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO + + + + 01644 + SEM GTIN + ESTANTE ACO C/ 06 PRATELEIRAS 0,93X040X1,98M + 94069020 + 5102 + PC + 2 + 234.00000 + 468.00 + SEM GTIN + PC + 2 + 234.00000 + 1 + + + 45.87 + + + 0 + 102 + + + + + 08 + + + + + 08 + + + + (REFORCADA) AMAPA - IMOBILIZADO. + + + + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 1103.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 1103.00 + 195.35 + + + + 0 + + 6 + VOLUME + VARIAS + 0.000 + 0.000 + + + + + 000003103 + 1103.00 + 0.00 + 1103.00 + + + 001 + 2019-05-11 + 1103.00 + + + + + 14 + 1103.00 + + 0.00 + + + ORDEM DE FORNECIMENTO 36994 - 28DD - INFORMACOES COMPLEMENTARES a seguinte informacao. EMPRESA ENQUADRADA NO SIMPLES NACIONAL. NAO GERA CREDITO DE IPI/ISS. GERA CREDITO DE ICMS. Trib aprox R$: 54,84 Federal 140,51 Estadual Fonte: IBPT empresometro.com.br S3A6R4 + + + + + + + + + + + + + ngqVwH6QNCAHyRuI529RIAr7Nyk= + + + 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 + + + + + + + 1 + 14.2.26 + 31190406273476000182550020000031031004640327 + 2019-04-10T17:23:27-03:00 + 131193257591884 + ngqVwH6QNCAHyRuI529RIAr7Nyk= + 100 + Autorizado o uso da NF-e + + + \ No newline at end of file diff --git a/parser.py b/parser.py new file mode 100644 index 0000000..ac9c60d --- /dev/null +++ b/parser.py @@ -0,0 +1,45 @@ +from ast import Try +from warnings import catch_warnings +from NotaFiscal import NotaFiscal +from typing import List +from pprint import pprint +import os + +print("Bem vindo!") +print("Este progarma irá ler diversas notas fiscais em formato xml guardadas em uma pasta.") +print("Por favor informe o nome da pasta:") + +# Entrada da linha de comando +# Pasta que contem as notas fiscais +path = input() + +try: + # Diretório para ser percorrido em busca + # de novos arquivos + os.chdir(path) +except: + print("Pasta não encontrada.") + exit(1) + +# vetor das notas fiscais lidas na entrada +vet_nota_fiscal : List[NotaFiscal] = [] + +indetifier = input() + +# Percorre os arquivos de uma dada pasta +# e cria um objeto NotaFiscal para armazenar +# e percorrer os dados do arquivo XML da entrada +for file in os.listdir(): + if file.endswith('xml'): + print(file) + nota_fiscal = NotaFiscal(file) + vet_nota_fiscal.append(nota_fiscal) + +# Percorre as notas fiscais guardadas +for nota_fiscal in vet_nota_fiscal: + # Caso uma nota fiscal possua o identificador + # dado como entrada o mesmo deve ser printado + if nota_fiscal.get_emit_identifier() == indetifier: + pprint(nota_fiscal.get_faturas()) + pprint(nota_fiscal.get_dest_identifier()) + pprint(nota_fiscal.get_dest_enderDest()) \ No newline at end of file From 1ed7965ff2b0a8391220bcd9f98adfd4db29765a Mon Sep 17 00:00:00 2001 From: Lucas_Moraes_Wize Date: Thu, 31 Mar 2022 19:16:09 -0300 Subject: [PATCH 2/7] =?UTF-8?q?Feature:=20L=C3=AA=20arquivos=20XML=20e=20s?= =?UTF-8?q?alva=20eles=20num=20banco=20de=20dados.=20Feature:=20Percorre?= =?UTF-8?q?=20o=20banco=20de=20dados=20para=20listar=20destinador=20e=20du?= =?UTF-8?q?plicatas(boletos)=20de=20um=20dado=20emitente.=20Feature:=20Che?= =?UTF-8?q?ca=20se=20os=20dados=20do=20XML=20dado=20como=20entrada=20j?= =?UTF-8?q?=C3=A1=20existe=20no=20banco.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 + Database.py | 117 ++++++++++ NotaFiscal.py | 54 +++-- __pycache__/NotaFiscal.cpython-38.pyc | Bin 4976 -> 5673 bytes database_utils.py | 180 +++++++++++++++ ...05570714000825550010109071851235294293.xml | 205 ++++++++++++++++++ parser.py | 91 ++++---- test.db | Bin 0 -> 45056 bytes 8 files changed, 593 insertions(+), 58 deletions(-) create mode 100644 .gitignore create mode 100644 Database.py create mode 100644 database_utils.py create mode 100644 notasFiscais/32210605570714000825550010109071851235294293.xml create mode 100644 test.db diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9fcd3f4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +bin +env +*png +__pycache__ \ No newline at end of file diff --git a/Database.py b/Database.py new file mode 100644 index 0000000..b2439a0 --- /dev/null +++ b/Database.py @@ -0,0 +1,117 @@ +from multiprocessing.connection import Connection +import sqlite3 +from sqlite3 import Error + +''' +Utilização do banco de dados: + Justificativa: Uma vez que um arquivo é lido ele é salvo no banco permitindo + acesso as informações relevante a aplicação em executações futuras do mesmo + 1. O programa deve listar valores e data de vencimento de boletos segundo um dado + indentificador (CPF OU CNPJ) de um fornecedor (emitente). + 2. o program deve listar nome, identificador (CPF ou CNPJ) e endereço dos + clientes de um dado fornecedor(emitente) + +''' + +class Database(): + def __init__(self, input_path: str): + self.db_path : str = input_path + self.conn : Connection = self.create_connection() + self.cursor = self.conn.cursor() + + def create_connection(self) -> Connection: + """ create a Database connection to the SQLite Database + specified by db_file + :param db_file: Database file + :return: Connection object or None + """ + conn : Connection = None + try: + conn= sqlite3.connect(self.db_path) + return conn + except Error as e: + print(e) + + return conn + + def create_table(self, create_table_sql) -> None: + """ create a table from the create_table_sql statement + :param conn: Connection object + :param create_table_sql: a CREATE TABLE statement + :return: + """ + try: + self.cursor.execute(create_table_sql) + except Error as e: + print(e) + + def create_emitente(self, emitente) -> None: + """ + Create a new project into the projects table + :param conn: + :param project: + :return: project id + """ + sql = ''' INSERT INTO emitente(emitente_id, + nome) + VALUES(?,?) ''' + self.cursor.execute(sql, (emitente['emitente_id'], + emitente['nome'])) + self.conn.commit() + + def create_destinador(self, destinador) -> None: + sql = ''' INSERT INTO destinador(destinador_id, + nome) + VALUES(?,?) ''' + self.cursor.execute(sql, (destinador['destinador_id'], + destinador['nome'])) + self.conn.commit() + + def create_endereco_destinador(self, endereco) -> None: + sql = ''' INSERT INTO endereco_destinador(destinador_endereco_id, + destinador_id, + logradouro, + numero, + bairro, + municipio, + estado, + cep, + telefone) + VALUES(?,?,?,?,?,?,?,?,?) ''' + self.cursor.execute(sql, (endereco['destinador_endereco_id'], + endereco['destinador_id'], + endereco['xLgr'], + endereco['nro'], + endereco['xBairro'], + endereco['xMun'], + endereco['UF'], + endereco['CEP'], + endereco['fone'] + )) + self.conn.commit() + + def create_nota_fiscal(self, nota_fiscal): + # print(nota_fiscal) + sql = ''' INSERT INTO nota_fiscal(nota_fiscal_id, + emitente_id, + destinador_id, + valor_total) + VALUES(?,?,?,?) ''' + + self.cursor.execute(sql, (nota_fiscal['nota_fiscal_id'], + nota_fiscal['emitente_id'], + nota_fiscal['destinador_id'], + nota_fiscal['valor_total'])) + self.conn.commit() + + def create_duplicata(self, duplicata): + sql = ''' INSERT INTO duplicata(duplicata_id, + nota_fiscal_id, + data_vencimento, + valor_pago) + VALUES(?,?,?,?) ''' + self.cursor.execute(sql, (duplicata['duplicata_id'], + duplicata['nota_fiscal_id'], + duplicata['data_vencimento'], + duplicata['valor_pago'])) + self.conn.commit() \ No newline at end of file diff --git a/NotaFiscal.py b/NotaFiscal.py index 9a6104f..342210e 100644 --- a/NotaFiscal.py +++ b/NotaFiscal.py @@ -46,7 +46,12 @@ def remove_namespace_from_nota_fiscal(self, input: ET.Element) -> ET.Element: def set_namespace_nota_fiscal(self, namespace: str) -> None: self.namespace = namespace - # --------- EMIT --------- + # --------- Emitente --------- + + # Retorna nome do destinatário + def get_emit_name(self) -> str: + name = self.get_text_from_xml_tree_element('./NFe/infNFe/emit/xNome') + return name # Retorna cnpj do emissor da nota fiscal caso o # mesmo seja uma pessoa jurídica @@ -73,7 +78,7 @@ def get_emit_enderEmit(self) -> dict: enderEmit = self.get_dict_from_xml_tree_element('./NFe/infNFe/emit/enderEmit') return enderEmit - # --------- DEST --------- + # --------- Destinador --------- # Retorna cnpj do destinatário da nota fiscal caso o # mesmo seja uma pessoa jurídica @@ -99,12 +104,41 @@ def get_dest_identifier(self) -> str: def get_dest_name(self) -> str: name = self.get_text_from_xml_tree_element('./NFe/infNFe/dest/xNome') return name - + + # --------- Endereço --------- + # Retorna endereço do destinatário def get_dest_enderDest(self) -> dict: enderDest = self.get_dict_from_xml_tree_element('./NFe/infNFe/dest/enderDest') + enderDest['destinador_endereco_id'] = self.get_dest_cnpj() + enderDest['destinador_id'] = self.get_dest_cnpj() + return enderDest + # --------- Dados para identificação da nota fiscal --------- + def get_nota_fiscal_id(self) -> str: + xml_tree_element = self.root.find('./NFe/infNFe') + return xml_tree_element.attrib['Id'] + + def get_nota_fiscal_valor_total(self) -> str: + name = self.get_text_from_xml_tree_element('./NFe/infNFe/pag/detPag/vPag') + return name + + # --------- Fatura --------- + + # Retorna lista de faturas contidas em uma + # nota fiscal + def get_faturas(self) -> dict: + faturas = [] + for tree_element_fatura in self.root.findall('./NFe/infNFe/cobr/dup'): + fatura = {} + fatura['duplicata_id'] = tree_element_fatura.find('nDup').text + self.get_nota_fiscal_id() + fatura['nota_fiscal_id'] = self.get_nota_fiscal_id() + fatura['data_vencimento'] = tree_element_fatura.find('dVenc').text + fatura['valor_pago'] = tree_element_fatura.find('vDup').text + faturas.append(fatura) + return faturas + # --------- Specific methods --------- # Retorna data de vencimento da nota fiscal @@ -118,18 +152,6 @@ def get_valor_total(self) -> str: valor_total_nota = self.get_text_from_xml_tree_element('./NFe/infNFe/total/ICMSTot/vNF') return valor_total_nota - # Retorna lista de faturas contidas em uma - # nota fiscal - def get_faturas(self) -> dict: - faturas = [] - for tree_element_fatura in self.root.findall('./NFe/infNFe/cobr/dup'): - fatura = {} - fatura[tree_element_fatura.find('nDup').tag] = tree_element_fatura.find('nDup').text - fatura['Validade'] = tree_element_fatura.find('dVenc').text - fatura['Valor'] = tree_element_fatura.find('vDup').text - faturas.append(fatura) - return faturas - # Exibe faturas da nota fiscal # Listar os valores e data de Vencimento dos boletos # presentes em um nota fiscal @@ -144,7 +166,7 @@ def print_fatura(self) -> None: # Retorna o texto de um determinado elemento def get_text_from_xml_tree_element(self, tree_path: str) -> str: xml_tree_element = self.root.find(tree_path) - if xml_tree_element.tag: + if xml_tree_element != None: return xml_tree_element.text return None diff --git a/__pycache__/NotaFiscal.cpython-38.pyc b/__pycache__/NotaFiscal.cpython-38.pyc index 65e8df1147aa716b70f89627e62e98068c62cca8..adf26a7dcd9254c1f9fc24fddcf3a3a48009431d 100644 GIT binary patch delta 1618 zcmaJ>O>7%g5ZNLc40G#gg{Az%#Z8(y`&o)JFGWp z8#c-T4waBllR5N2Rgx2e3kW0*oaha4KuFwt=$Q)=oT}WI*)>g*1G{?Pn{Q^`%zHEY z_V1yubJlz;W=Qyak)FB!OZT>Qn|-i-=T2PV>V3vLdDo|E(GqcZj!kX_x-=g^UAu_; z9>@70vS&qLd!7#=>u9kIKY^^X<(cItk#)6f!#szqyTwL$9$62M`7sN86j`rO&^mTs z=BM~+8)w4L*-rhFG!P z!mZi*iU2E=h3})izN%C!uZZy-qd!6pK7)thQTRDxS^koXvvaRH16Ugv4Gps?^n}}? zIW_>lhH~rzJPs{IPoUMw5@f&*XV_)f4tp#MR%C&_4kFUfX+0VrMbd13$5_b(oRrZg zV4~DCmxNp5qT!Y*tBdbq^nQ3Fs=<%O<>&}`<_R*OM>FgiW=W&gC!f4m6hfYA_B92BCVM(G!{a3b2()$aWvMp^Yp1h0Y+hfZL zwocuXIweox)I6V|tfEXln(w1*+i6x9&^@3V$~*llC;h;T!85N8MLAT35hiVWzWGM%SCPMBGm6;2xMZ3*3? T7a6|6970LOVIdE}e)8tOF${%r delta 1085 zcmYLHO=}ZT6rDR?nNE^P8k06^t4WP*#>U1^v|1E2R4iE3YSBT_F>k6<(o|nkKgtvr zinx<{7j9hCl@c1?<1bL}o3wU@cjlh+&b{;AeQ&w+yWct+kDC%b zFYxG<`L0Fl4(wTc_%LBH^(nA!mc6e!2~WYzuYB9!oxei?s8x^XySKQ;=m8$X-9c*Hmf zc|@ZG!}!s-8ZFS4`Bnj2@LM#CV;u=Ngic2Q%lM;X5=L>zZ0Py6;klWIaVj&jDvU&P zaE9vi;(T;0x=pwSS8ENxd8(7gZ0wvS@@>2j$>Rr8)9UVw=TezId>`9{(MT8mNm@zf zHJW9w&OBbBh!5cD_84k&`ZHd=Ig5jx1(?B; zodNCfYv%|w&`j;UtCClzag;{mGQm}80Rm}SS^@^opdwuyTabNeK?&p~naR&!S_#%- zbwmnvrLD77uB~vL=3z+-Xda{+$pGlwBIEO!q4M~sSN7{uXmrMoIBLBzcfF;tNm{LA zOu99nxy);+H%WFh;D_Mf9z2#jle#0ekR*`k%#$>- z_&Qm_!>QB5yGfi+SEwU7=H;sYn{pt>chQtB^I`h%ZV@YC|M)&3?8h&u96Z2Zsk4A{nuC S5!2iLYL-xRD~@k6xBdZZ+xLF} diff --git a/database_utils.py b/database_utils.py new file mode 100644 index 0000000..5aca36f --- /dev/null +++ b/database_utils.py @@ -0,0 +1,180 @@ +from Database import Database +import os +from NotaFiscal import NotaFiscal + +def create_db(database_str : str) -> Database: + db = Database(database_str) + + sql_create_emitente_table = """ CREATE TABLE IF NOT EXISTS emitente ( + emitente_id text PRIMARY KEY, + nome text NOT NULL + ); """ + + sql_create_destinador_table = """ CREATE TABLE IF NOT EXISTS destinador ( + destinador_id text PRIMARY KEY, + nome text NOT NULL + ); """ + + sql_create_endereco_destinador_table = """ CREATE TABLE IF NOT EXISTS endereco_destinador ( + destinador_endereco_id text PRIMARY KEY, + destinador_id text, + logradouro text NOT NULL, + numero text NOT NULL, + bairro text NOT NULL, + municipio text NOT NULL, + estado text NOT NULL, + cep text NOT NULL, + telefone text NOT NULL, + FOREIGN KEY (destinador_id) REFERENCES destinador (destinador_id) + ); """ + + sql_create_nota_fiscal_table = """ CREATE TABLE IF NOT EXISTS nota_fiscal ( + nota_fiscal_id text PRIMARY KEY, + emitente_id text NOT NULL, + destinador_id text NOT NULL, + valor_total text NOT NULL, + FOREIGN KEY (emitente_id) REFERENCES emitente (emitente_id), + FOREIGN KEY (destinador_id) REFERENCES destinador (destinador_id) + ); """ + + sql_create_duplicata_table = """ CREATE TABLE IF NOT EXISTS duplicata ( + duplicata_id text PRIMARY KEY, + nota_fiscal_id text NOT NULL, + data_vencimento text NOT NULL, + valor_pago text NOT NULL, + FOREIGN KEY (nota_fiscal_id) REFERENCES nota_fiscal (nota_fiscal_id) + ); """ + + + # create tables + if db.conn is not None: + db.create_table(sql_create_emitente_table) + db.create_table(sql_create_destinador_table) + db.create_table(sql_create_endereco_destinador_table) + db.create_table(sql_create_nota_fiscal_table) + db.create_table(sql_create_duplicata_table) + + else: + print("Error! cannot create the Database connection.") + + return db + +def delete_db(db_name : str): + os.remove(db_name) + +def save_nota_fiscal_on_db(test_db : Database, nota_fiscal : NotaFiscal): + + # Emitente + emitente = check_if_emitente_exists_in_bd(test_db, nota_fiscal) + if emitente: + test_db.create_emitente(emitente) + + # Destinador + destinador = check_if_destinador_exists_in_bd(test_db, nota_fiscal) + if destinador: + test_db.create_destinador(destinador) + + # Endereço do destinador + endereco_destinador = nota_fiscal.get_dest_enderDest() + test_db.create_endereco_destinador(endereco_destinador) + + # Nota fiscal + nota_fiscal_dict = check_if_nota_fiscal_exists_in_bd(test_db, nota_fiscal) + if nota_fiscal_dict: + test_db.create_nota_fiscal(nota_fiscal_dict) + + # Duplicata é parte da fatura pois a mesma pode ter mais de uma + # parcela. + for duplicata in nota_fiscal.get_faturas(): + test_db.create_duplicata(duplicata) + +def check_if_emitente_exists_in_bd(test_db : Database, nota_fiscal : NotaFiscal) -> dict: + emitente_dict = {'emitente_id' : nota_fiscal.get_emit_identifier(), + 'nome' : nota_fiscal.get_emit_name()} + + test_db.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", + (emitente_dict['emitente_id'],)) + + data=test_db.cursor.fetchone() + if data is None: + # print('There is no component named %s', emitente_dict['emitente_id']) + return emitente_dict + else: + print('Emitente com identificador %s já existe no sistema'%(emitente_dict['emitente_id'])) + return None + +def check_if_destinador_exists_in_bd(test_db : Database, nota_fiscal : NotaFiscal) -> dict: + destinador_dict = {'destinador_id' : nota_fiscal.get_dest_identifier(), + 'nome' : nota_fiscal.get_dest_name()} + + test_db.cursor.execute("SELECT nome FROM destinador WHERE destinador_id = ?", + (destinador_dict['destinador_id'],)) + data=test_db.cursor.fetchone() + if data is None: + # print('There is no component named %s', destinador_dict['emitente_id']) + return destinador_dict + else: + print('Destinador com identificador %s já existe no sistema'%(destinador_dict['destinador_id'])) + return None + +def check_if_nota_fiscal_exists_in_bd(test_db : Database, nota_fiscal : NotaFiscal) -> dict: + nota_fiscal_dict = {'nota_fiscal_id' : nota_fiscal.get_nota_fiscal_id(), + 'emitente_id' : nota_fiscal.get_emit_identifier(), + 'destinador_id' : nota_fiscal.get_dest_identifier(), + 'valor_total' : nota_fiscal.get_nota_fiscal_valor_total()} + + test_db.cursor.execute("SELECT nota_fiscal_id FROM nota_fiscal WHERE nota_fiscal_id = ?", + (nota_fiscal_dict['nota_fiscal_id'],)) + + data=test_db.cursor.fetchone() + if data is None: + return nota_fiscal_dict + else: + print('Nota fiscal com identificador %s já existe no sistema'%(nota_fiscal_dict['nota_fiscal_id'])) + return None + +def consulta_boletos_de_um_emitente(test_db : Database, identificador_emitente : str): + test_db.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", + (identificador_emitente,)) + nome_emitente = test_db.cursor.fetchone()[0] + print("---------------------------------------------------------") + print("Consulta notas fiscais do emitente %s de identificador %s"%(nome_emitente, identificador_emitente)) + test_db.cursor.execute("SELECT * FROM nota_fiscal WHERE emitente_id = ?", + (identificador_emitente,)) + notas_fiscais=test_db.cursor.fetchall() + + for nota_fiscal in notas_fiscais: + print('\n--------- Nota fiscal ---------') + print('Código: ', nota_fiscal[0], ' ') + print('Valor total da nota: ', nota_fiscal[3]) + test_db.cursor.execute("SELECT * FROM duplicata WHERE nota_fiscal_id = ?", + (nota_fiscal[0],)) + duplicatas=test_db.cursor.fetchall() + if duplicatas != None: + print('\n--------- Parcelas da fatura ---------') + for dup in duplicatas: + print('Boleto: ', dup[0].split('NFe')[0]) + print('Data de vencimento: ', dup[2]) + print('Valor a ser pago: ', dup[3]) + + print('\n\n') + +def consulta_clientes_de_um_emitente(test_db : Database, identificador_emitente : str): + test_db.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", + (identificador_emitente,)) + nome_emitente = notas_fiscais=test_db.cursor.fetchone()[0] + print("---------------------------------------------------------") + print("Consulta clientes do emitente %s de identificador %s"%(nome_emitente, identificador_emitente)) + test_db.cursor.execute("SELECT * FROM nota_fiscal WHERE emitente_id = ?", + (identificador_emitente,)) + notas_fiscais=test_db.cursor.fetchall() + + for nota_fiscal in notas_fiscais: + test_db.cursor.execute("SELECT * FROM destinador WHERE destinador_id = ?", + (nota_fiscal[2],)) + destinadores=test_db.cursor.fetchall() + if destinadores != None: + print('\n--------- Clientes ---------') + for dest in destinadores: + print('Nome: ', dest[1], 'Identificador: ', dest[0]) + diff --git a/notasFiscais/32210605570714000825550010109071851235294293.xml b/notasFiscais/32210605570714000825550010109071851235294293.xml new file mode 100644 index 0000000..d8cf596 --- /dev/null +++ b/notasFiscais/32210605570714000825550010109071851235294293.xml @@ -0,0 +1,205 @@ + + + + + + 32 + 23529429 + VENDA PARA CONSUMIDOR FINAL + 55 + 1 + 10907185 + 2021-06-04T00:00:00-02:00 + 2021-06-04T06:56:05-02:00 + 1 + 1 + 3205101 + 1 + 1 + 3 + 1 + 1 + 1 + 2 + 0 + MIGRATEGNFe + + + 06273476000182 + KABUM COMERCIO ELETRONICO S.A + KABUM! + + ROD BR-262 + 222 + GALPAO 2 ARMZ 3 4 E 5 + VILA BETHANIA + 3205101 + VIANA + ES + 29136010 + 1058 + BRASIL + 1921144444 + + 083078665 + 3 + + + 15004584737 + LUCAS MORAES + + RUA CARLOS FIRMO + 75 + 2 ANDAR + CENTRO + 3201100 + BOM JESUS DO NORTE + ES + 29460000 + 1058 + BRASIL + 28999927700 + + 9 + + + + 119072 + + FONE DE OUVIDO BLUETOOTH EDIFIER TWS X3, RECARREGAVEL, RESISTENTE A AGUA, PRETO - TOT TRIB. 52.32 + 85183000 + 0105700 + 5102 + UN + 1.0000 + 159.9000000000 + 159.90 + + UN + 1.0000 + 159.9000000000 + 28.23 + 1 + + + + + 0 + 00 + 3 + 188.13 + 17.0000 + 31.98 + + + + + 01 + 156.15 + 1.6500 + 2.58 + + + + + 01 + 156.15 + 7.6000 + 11.87 + + + + GARANTIA 12 MESES - N.SERIE OU IMEI 310100325872 + + + + 188.13 + 31.98 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 159.90 + 28.23 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 2.58 + 11.87 + 0.00 + 188.13 + + + + 0 + + 34028316710151 + CORREIOS + + + 1 + 1 + 0.091 + 0.091 + + + + + 03 + 188.13 + + + + PEDIDO 23529429 - OBSERVACAO DO CLIENTE - NENHUMA VALOR APROXIMADO DOS TRIBUTOS 44.47 REAIS - 27.81 POR CENTO - FONTE IBPT + + ECT_SEDEX + + + 23529429 + + + + 23529429 + + + + + + + + + + + + + 2yKVkW9JSljwXzcaV0/KMHV2HZM= + + + 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 + + + + + + + 1 + SVRS202103291658 + 32210605570714000825550010109071851235294293 + 2021-06-04T06:57:08-03:00 + 332210035696612 + 2yKVkW9JSljwXzcaV0/KMHV2HZM= + 100 + Autorizado o uso da NF-e + + + diff --git a/parser.py b/parser.py index ac9c60d..1e77a22 100644 --- a/parser.py +++ b/parser.py @@ -1,45 +1,52 @@ -from ast import Try -from warnings import catch_warnings from NotaFiscal import NotaFiscal from typing import List -from pprint import pprint import os - -print("Bem vindo!") -print("Este progarma irá ler diversas notas fiscais em formato xml guardadas em uma pasta.") -print("Por favor informe o nome da pasta:") - -# Entrada da linha de comando -# Pasta que contem as notas fiscais -path = input() - -try: - # Diretório para ser percorrido em busca - # de novos arquivos - os.chdir(path) -except: - print("Pasta não encontrada.") - exit(1) - -# vetor das notas fiscais lidas na entrada -vet_nota_fiscal : List[NotaFiscal] = [] - -indetifier = input() - -# Percorre os arquivos de uma dada pasta -# e cria um objeto NotaFiscal para armazenar -# e percorrer os dados do arquivo XML da entrada -for file in os.listdir(): - if file.endswith('xml'): - print(file) - nota_fiscal = NotaFiscal(file) - vet_nota_fiscal.append(nota_fiscal) - -# Percorre as notas fiscais guardadas -for nota_fiscal in vet_nota_fiscal: - # Caso uma nota fiscal possua o identificador - # dado como entrada o mesmo deve ser printado - if nota_fiscal.get_emit_identifier() == indetifier: - pprint(nota_fiscal.get_faturas()) - pprint(nota_fiscal.get_dest_identifier()) - pprint(nota_fiscal.get_dest_enderDest()) \ No newline at end of file +from database_utils import * +from Database import Database + +def main(): + print("Bem vindo!") + print("Este progarma irá ler diversas notas fiscais em formato xml guardadas em uma pasta.") + print("Por favor informe o nome da pasta:") + + # Entrada da linha de comando + # Pasta que contem as notas fiscais + path = 'notasFiscais' + + try: + # Diretório para ser percorrido em busca + # de novos arquivos + os.chdir(path) + except: + print("Pasta não encontrada.") + exit(1) + + db_path = '../test.db' + # delete_db(db_path) + test_db : Database = create_db('../test.db') + + # vetor das notas fiscais lidas na entrada + vet_nota_fiscal : List[NotaFiscal] = [] + + idetifier = '07872718000117' + + # Percorre os arquivos de uma dada pasta + # e cria um objeto NotaFiscal para armazenar + # e percorrer os dados do arquivo XML da entrada + for file in os.listdir(): + if file.endswith('.xml'): + # print(file) + nota_fiscal = NotaFiscal(file) + vet_nota_fiscal.append(nota_fiscal) + + # Percorre as notas fiscais guardadas + for nota_fiscal in vet_nota_fiscal: + save_nota_fiscal_on_db(test_db, nota_fiscal) + + print("\n\nResultado") + consulta_boletos_de_um_emitente(test_db, idetifier) + consulta_clientes_de_um_emitente(test_db, idetifier) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/test.db b/test.db new file mode 100644 index 0000000000000000000000000000000000000000..c41188217cf873ce6499668a1b65aa603a91c748 GIT binary patch literal 45056 zcmeI)&uiOe7zc34O5(;P(Xuj3Rzluj3iX&Xy^>|wr%hFq)U9nTma~$r;3>9JOdLCL zoUAZ*C>`ry$1!^8y~kblClm%N8|+fp2D|stTgQ%j6~{l+CDiglVa->>u`IvuE4?2* zlI{1gY_H~OZI^5|TiZ^XDBK$y&vPFT!g1UMc012*-D#Z7jCCKddwyX4q}dDH;`_f% ziGOpE@kiYBQ}M^CU#5SEd^~k8{Cgxe{wVzLq>5M$0SG_<0xuW1`{`sjIzP|f6Wh*4 z-L3BL)N2)|?eu0MM$yzuCMoGxawh35CYK{*$f;MST&t3{d%I0OEN1h1ah+T@*WVqw znMSkils9X86{p^7s9=>yVJ(*%zLhHLTlv6kRBGF9quuOmPw-|AoO-iW-f?b?+`_U| zG_xxO&wyO^_bpC}=CWBd3x;Wvfv5geZYaArjZ8$%d7i5^s_yN*-8y^CE<5|}=HcUV zfA7%V?D;R3!{KNw#(!-eM#aE349uSMMaIAr0b*mIR&S?{6dmq1>sEvHtQ%v&_i5GL zYu6f1mF?Kk8|ef_o5gB<)Y$Sx#z4P(VbNVqE_dhHM#qOg4ty)|_1w3b{xjrqf8JZw zaIvSJn}}v(C&k|2-lqc(Cck=TJRDUN{+rJa6Cz15Fjdte*_O9}r_s(*P-9q96PW+Yq z!vp~cKmY;|fB*y_009U<00Izzz$+I}LPC61($bo&(X=E>}8#)?N+ zuR`JZYx*%>Syas%cG0YhG)r zdNo(FiCI`N3s?1GRwpJgtb$!Ct{E1)EYbVMfS3Ol#K)ZYCmR8HcG?|8dk}yC1Rwwb z2tWV=5P$##AOHafoU(wI@AnTT2%-?<2Sy7H^Z))4g2Vj(^k1C#KwM>am>>WF2tWV= z5P$##AOHafKmY=-k-)kTiN`O^T%4boi}^n?`yUn8bYinK{54Crl9_BtH?miB!%L+b zS%anA?(yq^TH z?W|1|Iho5YWesy}!)?`_Mz!YTSCn*;ts+g8q$10Tnn|TP`Tr-J_*8s?{Qqkd;^+zl zAOHafKmY;|fB*y_009V`0fA$_3NR*c{E7Mh=bZRZEKEN?12pI&1Rwwb2tWV=5P$## zAOHafoE?E1!uVD^ezCCZvNSlQvj11|RCakiJxs+@O-s|Xrm+%|r20$wzbHVdl3J9N z8=>*Ncx?8lVJRi4D!a6wCY`~-q|8AAxk!q%j>t^h*>o$LSabK*Tw zoW6gmJx5~@fB*y_009U<00Izz00bZaftLv!2;;k33$rY(9q_Yrz~Ztb%LytcWLZtI zJiB}lI$AFc*igXY-Sx8H==au3KjXdiUSwZ9@EQv6`8{B9S)!SQq$Vhv2J-(mIq@g) zTk+=0b_K!j9bcQW|+!9T?; B?G^w4 literal 0 HcmV?d00001 From 77dbe0681a7bd8559e7bb9d2b9bc30ee64e31d7f Mon Sep 17 00:00:00 2001 From: Lucas_Moraes_Wize Date: Thu, 31 Mar 2022 20:44:37 -0300 Subject: [PATCH 3/7] =?UTF-8?q?Fix:=20c=C3=B3digo=20simplificado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Database.py | 115 +++++++++++++++++++++++++++++++++++++++++----- NotaFiscal.py | 1 - database_utils.py | 114 --------------------------------------------- parser.py | 14 +++--- 4 files changed, 110 insertions(+), 134 deletions(-) diff --git a/Database.py b/Database.py index b2439a0..f4db522 100644 --- a/Database.py +++ b/Database.py @@ -1,6 +1,7 @@ from multiprocessing.connection import Connection import sqlite3 from sqlite3 import Error +from NotaFiscal import NotaFiscal ''' Utilização do banco de dados: @@ -34,14 +35,19 @@ def create_connection(self) -> Connection: return conn - def create_table(self, create_table_sql) -> None: + def create_table(self, create_table_sql : str, args : str = None) -> None: """ create a table from the create_table_sql statement :param conn: Connection object :param create_table_sql: a CREATE TABLE statement :return: """ + # print(args) try: - self.cursor.execute(create_table_sql) + if args == None: + self.cursor.execute(create_table_sql) + else: + self.cursor.execute(create_table_sql, args) + self.conn.commit() except Error as e: print(e) @@ -55,17 +61,15 @@ def create_emitente(self, emitente) -> None: sql = ''' INSERT INTO emitente(emitente_id, nome) VALUES(?,?) ''' - self.cursor.execute(sql, (emitente['emitente_id'], + self.create_table(sql, (emitente['emitente_id'], emitente['nome'])) - self.conn.commit() def create_destinador(self, destinador) -> None: sql = ''' INSERT INTO destinador(destinador_id, nome) VALUES(?,?) ''' - self.cursor.execute(sql, (destinador['destinador_id'], + self.create_table(sql, (destinador['destinador_id'], destinador['nome'])) - self.conn.commit() def create_endereco_destinador(self, endereco) -> None: sql = ''' INSERT INTO endereco_destinador(destinador_endereco_id, @@ -78,7 +82,7 @@ def create_endereco_destinador(self, endereco) -> None: cep, telefone) VALUES(?,?,?,?,?,?,?,?,?) ''' - self.cursor.execute(sql, (endereco['destinador_endereco_id'], + self.create_table(sql, (endereco['destinador_endereco_id'], endereco['destinador_id'], endereco['xLgr'], endereco['nro'], @@ -88,7 +92,6 @@ def create_endereco_destinador(self, endereco) -> None: endereco['CEP'], endereco['fone'] )) - self.conn.commit() def create_nota_fiscal(self, nota_fiscal): # print(nota_fiscal) @@ -98,11 +101,10 @@ def create_nota_fiscal(self, nota_fiscal): valor_total) VALUES(?,?,?,?) ''' - self.cursor.execute(sql, (nota_fiscal['nota_fiscal_id'], + self.create_table(sql, (nota_fiscal['nota_fiscal_id'], nota_fiscal['emitente_id'], nota_fiscal['destinador_id'], nota_fiscal['valor_total'])) - self.conn.commit() def create_duplicata(self, duplicata): sql = ''' INSERT INTO duplicata(duplicata_id, @@ -110,8 +112,97 @@ def create_duplicata(self, duplicata): data_vencimento, valor_pago) VALUES(?,?,?,?) ''' - self.cursor.execute(sql, (duplicata['duplicata_id'], + self.create_table(sql, (duplicata['duplicata_id'], duplicata['nota_fiscal_id'], duplicata['data_vencimento'], duplicata['valor_pago'])) - self.conn.commit() \ No newline at end of file + + def check_if_exists_in_bd(self, table : str, identifier : str) -> bool: + sql = "SELECT * FROM "+ table + " WHERE "+ table +"_id = ?" + self.cursor.execute(sql, (identifier,)) + + data = self.cursor.fetchone() + if data is None: + # print('There is no component named %s', emitente_dict['emitente_id']) + return True + else: + print('Emitente com identificador %s já existe no sistema'%(identifier)) + return False + + def consulta_boletos_de_um_emitente(self, identificador_emitente : str): + self.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", + (identificador_emitente,)) + nome_emitente = self.cursor.fetchone()[0] + print("---------------------------------------------------------") + print("Consulta notas fiscais do emitente %s de identificador %s"%(nome_emitente, identificador_emitente)) + self.cursor.execute("SELECT * FROM nota_fiscal WHERE emitente_id = ?", + (identificador_emitente,)) + notas_fiscais=self.cursor.fetchall() + + for nota_fiscal in notas_fiscais: + print('\n--------- Nota fiscal ---------') + print('Código: ', nota_fiscal[0], ' ') + print('Valor total da nota: ', nota_fiscal[3]) + self.cursor.execute("SELECT * FROM duplicata WHERE nota_fiscal_id = ?", + (nota_fiscal[0],)) + duplicatas=self.cursor.fetchall() + if duplicatas != None: + print('\n--------- Parcelas da fatura ---------') + for dup in duplicatas: + print('Boleto: ', dup[0].split('NFe')[0]) + print('Data de vencimento: ', dup[2]) + print('Valor a ser pago: ', dup[3]) + + print('\n\n') + + def consulta_clientes_de_um_emitente(self, identificador_emitente : str): + self.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", + (identificador_emitente,)) + nome_emitente = notas_fiscais=self.cursor.fetchone()[0] + print("---------------------------------------------------------") + print("Consulta clientes do emitente %s de identificador %s"%(nome_emitente, identificador_emitente)) + self.cursor.execute("SELECT * FROM nota_fiscal WHERE emitente_id = ?", + (identificador_emitente,)) + notas_fiscais=self.cursor.fetchall() + + for nota_fiscal in notas_fiscais: + self.cursor.execute("SELECT * FROM destinador WHERE destinador_id = ?", + (nota_fiscal[2],)) + destinadores=self.cursor.fetchall() + if destinadores != None: + print('\n--------- Clientes ---------') + for dest in destinadores: + print('Nome: ', dest[1], 'Identificador: ', dest[0]) + + def save_nota_fiscal_on_db(self, nota_fiscal : NotaFiscal): + + # Emitente + emitente_dict = {'emitente_id' : nota_fiscal.get_emit_identifier(), + 'nome' : nota_fiscal.get_emit_name()} + if self.check_if_exists_in_bd('emitente',emitente_dict['emitente_id']): + self.create_emitente(emitente_dict) + + # Destinador + destinador_dict = {'destinador_id' : nota_fiscal.get_dest_identifier(), + 'nome' : nota_fiscal.get_dest_name()} + + if self.check_if_exists_in_bd("destinador",destinador_dict['destinador_id']): + self.create_destinador(destinador_dict) + + # Endereço do destinador + endereco_destinador = nota_fiscal.get_dest_enderDest() + self.create_endereco_destinador(endereco_destinador) + + # Nota fiscal + nota_fiscal_dict = {'nota_fiscal_id' : nota_fiscal.get_nota_fiscal_id(), + 'emitente_id' : nota_fiscal.get_emit_identifier(), + 'destinador_id' : nota_fiscal.get_dest_identifier(), + 'valor_total' : nota_fiscal.get_nota_fiscal_valor_total()} + + if self.check_if_exists_in_bd("nota_fiscal",nota_fiscal_dict['nota_fiscal_id']): + self.create_nota_fiscal(nota_fiscal_dict) + + # Duplicata é parte da fatura pois a mesma pode ter mais de uma + # parcela. + for duplicata in nota_fiscal.get_faturas(): + self.create_duplicata(duplicata) \ No newline at end of file diff --git a/NotaFiscal.py b/NotaFiscal.py index 342210e..75d0030 100644 --- a/NotaFiscal.py +++ b/NotaFiscal.py @@ -1,5 +1,4 @@ # Biblioteca para trabalhar com XML -from cmath import exp import xml.etree.ElementTree as ET class NotaFiscal: diff --git a/database_utils.py b/database_utils.py index 5aca36f..9428982 100644 --- a/database_utils.py +++ b/database_utils.py @@ -62,119 +62,5 @@ def create_db(database_str : str) -> Database: def delete_db(db_name : str): os.remove(db_name) -def save_nota_fiscal_on_db(test_db : Database, nota_fiscal : NotaFiscal): - - # Emitente - emitente = check_if_emitente_exists_in_bd(test_db, nota_fiscal) - if emitente: - test_db.create_emitente(emitente) - - # Destinador - destinador = check_if_destinador_exists_in_bd(test_db, nota_fiscal) - if destinador: - test_db.create_destinador(destinador) - # Endereço do destinador - endereco_destinador = nota_fiscal.get_dest_enderDest() - test_db.create_endereco_destinador(endereco_destinador) - - # Nota fiscal - nota_fiscal_dict = check_if_nota_fiscal_exists_in_bd(test_db, nota_fiscal) - if nota_fiscal_dict: - test_db.create_nota_fiscal(nota_fiscal_dict) - - # Duplicata é parte da fatura pois a mesma pode ter mais de uma - # parcela. - for duplicata in nota_fiscal.get_faturas(): - test_db.create_duplicata(duplicata) - -def check_if_emitente_exists_in_bd(test_db : Database, nota_fiscal : NotaFiscal) -> dict: - emitente_dict = {'emitente_id' : nota_fiscal.get_emit_identifier(), - 'nome' : nota_fiscal.get_emit_name()} - - test_db.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", - (emitente_dict['emitente_id'],)) - - data=test_db.cursor.fetchone() - if data is None: - # print('There is no component named %s', emitente_dict['emitente_id']) - return emitente_dict - else: - print('Emitente com identificador %s já existe no sistema'%(emitente_dict['emitente_id'])) - return None - -def check_if_destinador_exists_in_bd(test_db : Database, nota_fiscal : NotaFiscal) -> dict: - destinador_dict = {'destinador_id' : nota_fiscal.get_dest_identifier(), - 'nome' : nota_fiscal.get_dest_name()} - - test_db.cursor.execute("SELECT nome FROM destinador WHERE destinador_id = ?", - (destinador_dict['destinador_id'],)) - data=test_db.cursor.fetchone() - if data is None: - # print('There is no component named %s', destinador_dict['emitente_id']) - return destinador_dict - else: - print('Destinador com identificador %s já existe no sistema'%(destinador_dict['destinador_id'])) - return None - -def check_if_nota_fiscal_exists_in_bd(test_db : Database, nota_fiscal : NotaFiscal) -> dict: - nota_fiscal_dict = {'nota_fiscal_id' : nota_fiscal.get_nota_fiscal_id(), - 'emitente_id' : nota_fiscal.get_emit_identifier(), - 'destinador_id' : nota_fiscal.get_dest_identifier(), - 'valor_total' : nota_fiscal.get_nota_fiscal_valor_total()} - - test_db.cursor.execute("SELECT nota_fiscal_id FROM nota_fiscal WHERE nota_fiscal_id = ?", - (nota_fiscal_dict['nota_fiscal_id'],)) - - data=test_db.cursor.fetchone() - if data is None: - return nota_fiscal_dict - else: - print('Nota fiscal com identificador %s já existe no sistema'%(nota_fiscal_dict['nota_fiscal_id'])) - return None - -def consulta_boletos_de_um_emitente(test_db : Database, identificador_emitente : str): - test_db.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", - (identificador_emitente,)) - nome_emitente = test_db.cursor.fetchone()[0] - print("---------------------------------------------------------") - print("Consulta notas fiscais do emitente %s de identificador %s"%(nome_emitente, identificador_emitente)) - test_db.cursor.execute("SELECT * FROM nota_fiscal WHERE emitente_id = ?", - (identificador_emitente,)) - notas_fiscais=test_db.cursor.fetchall() - - for nota_fiscal in notas_fiscais: - print('\n--------- Nota fiscal ---------') - print('Código: ', nota_fiscal[0], ' ') - print('Valor total da nota: ', nota_fiscal[3]) - test_db.cursor.execute("SELECT * FROM duplicata WHERE nota_fiscal_id = ?", - (nota_fiscal[0],)) - duplicatas=test_db.cursor.fetchall() - if duplicatas != None: - print('\n--------- Parcelas da fatura ---------') - for dup in duplicatas: - print('Boleto: ', dup[0].split('NFe')[0]) - print('Data de vencimento: ', dup[2]) - print('Valor a ser pago: ', dup[3]) - - print('\n\n') - -def consulta_clientes_de_um_emitente(test_db : Database, identificador_emitente : str): - test_db.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", - (identificador_emitente,)) - nome_emitente = notas_fiscais=test_db.cursor.fetchone()[0] - print("---------------------------------------------------------") - print("Consulta clientes do emitente %s de identificador %s"%(nome_emitente, identificador_emitente)) - test_db.cursor.execute("SELECT * FROM nota_fiscal WHERE emitente_id = ?", - (identificador_emitente,)) - notas_fiscais=test_db.cursor.fetchall() - - for nota_fiscal in notas_fiscais: - test_db.cursor.execute("SELECT * FROM destinador WHERE destinador_id = ?", - (nota_fiscal[2],)) - destinadores=test_db.cursor.fetchall() - if destinadores != None: - print('\n--------- Clientes ---------') - for dest in destinadores: - print('Nome: ', dest[1], 'Identificador: ', dest[0]) diff --git a/parser.py b/parser.py index 1e77a22..62172de 100644 --- a/parser.py +++ b/parser.py @@ -1,8 +1,8 @@ +from database_utils import create_db, delete_db from NotaFiscal import NotaFiscal +from Database import Database from typing import List import os -from database_utils import * -from Database import Database def main(): print("Bem vindo!") @@ -22,7 +22,7 @@ def main(): exit(1) db_path = '../test.db' - # delete_db(db_path) + delete_db(db_path) test_db : Database = create_db('../test.db') # vetor das notas fiscais lidas na entrada @@ -41,11 +41,11 @@ def main(): # Percorre as notas fiscais guardadas for nota_fiscal in vet_nota_fiscal: - save_nota_fiscal_on_db(test_db, nota_fiscal) + test_db.save_nota_fiscal_on_db(nota_fiscal) - print("\n\nResultado") - consulta_boletos_de_um_emitente(test_db, idetifier) - consulta_clientes_de_um_emitente(test_db, idetifier) + # print("\n\nResultado") + # test_db.consulta_boletos_de_um_emitente(idetifier) + # test_db.consulta_clientes_de_um_emitente(idetifier) if __name__ == '__main__': From ee92db4178dcc664e343426d6682cabeca09595f Mon Sep 17 00:00:00 2001 From: Lucas_Moraes_Wize Date: Fri, 1 Apr 2022 19:54:22 -0300 Subject: [PATCH 4/7] =?UTF-8?q?Feature:=20Servi=C3=A7o=20flask.=20Feature:?= =?UTF-8?q?=20P=C3=A1gina=20web=20iterativa=20onde=20o=20usu=C3=A1rio=20po?= =?UTF-8?q?de=20arrastar=20arquivos=20at=C3=A9=20a=20p=C3=A1gina=20para=20?= =?UTF-8?q?salvar.=20Feature:=20Busca=20atraves=20de=20um=20mecanismo=20de?= =?UTF-8?q?=20busca=20na=20p=C3=A1gina=20web.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- Database.py | 83 +++-- NotaFiscal.py | 4 - __pycache__/NotaFiscal.cpython-38.pyc | Bin 5673 -> 5640 bytes __pycache__/Nota_fiscal.cpython-38.pyc | Bin 960 -> 0 bytes app.py | 104 ++++++ test.db => database.db | Bin 45056 -> 53248 bytes database_utils.py | 66 ---- parser.py | 52 --- schema.sql | 49 +++ static/css/style.css | 6 + templates/base.html | 42 +++ templates/index.html | 80 +++++ ...2718000117550010000217781877120005-nfe.xml | 277 ++++++++++++++++ uploads/NFe-002-3103.xml | 311 ++++++++++++++++++ 15 files changed, 925 insertions(+), 151 deletions(-) delete mode 100644 __pycache__/Nota_fiscal.cpython-38.pyc create mode 100644 app.py rename test.db => database.db (78%) delete mode 100644 database_utils.py delete mode 100644 parser.py create mode 100644 schema.sql create mode 100644 static/css/style.css create mode 100644 templates/base.html create mode 100644 templates/index.html create mode 100644 uploads/32211207872718000117550010000217781877120005-nfe.xml create mode 100644 uploads/NFe-002-3103.xml diff --git a/.gitignore b/.gitignore index 9fcd3f4..f20b403 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ bin env *png -__pycache__ \ No newline at end of file +__pycache__ diff --git a/Database.py b/Database.py index f4db522..a35759f 100644 --- a/Database.py +++ b/Database.py @@ -15,8 +15,9 @@ ''' class Database(): - def __init__(self, input_path: str): + def __init__(self, input_path: str, schema_path: str): self.db_path : str = input_path + self.schema_path : str = schema_path self.conn : Connection = self.create_connection() self.cursor = self.conn.cursor() @@ -28,7 +29,9 @@ def create_connection(self) -> Connection: """ conn : Connection = None try: - conn= sqlite3.connect(self.db_path) + conn = sqlite3.connect(self.db_path) + with open(self.schema_path) as f: + conn.executescript(f.read()) return conn except Error as e: print(e) @@ -129,50 +132,74 @@ def check_if_exists_in_bd(self, table : str, identifier : str) -> bool: print('Emitente com identificador %s já existe no sistema'%(identifier)) return False - def consulta_boletos_de_um_emitente(self, identificador_emitente : str): - self.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", - (identificador_emitente,)) - nome_emitente = self.cursor.fetchone()[0] - print("---------------------------------------------------------") - print("Consulta notas fiscais do emitente %s de identificador %s"%(nome_emitente, identificador_emitente)) + def consulta_boletos_de_um_emitente(self, identificador_emitente : str) -> dict: + self.cursor.execute("SELECT * FROM nota_fiscal WHERE emitente_id = ?", (identificador_emitente,)) notas_fiscais=self.cursor.fetchall() - + if notas_fiscais == None: + return None + + # print("Notas fiscais") + # print(notas_fiscais[0][0]) + notas_fiscais_dict = [] for nota_fiscal in notas_fiscais: - print('\n--------- Nota fiscal ---------') - print('Código: ', nota_fiscal[0], ' ') - print('Valor total da nota: ', nota_fiscal[3]) + nota_fiscal_dict = {} + # print('\n--------- Nota fiscal ---------') + + # print('Código: ', nota_fiscal[0], ' ') + nota_fiscal_dict['nota_fical_id'] = nota_fiscal[0] + # print('Valor total da nota: ', nota_fiscal[3]) + nota_fiscal_dict['valor_total'] = nota_fiscal[3] + self.cursor.execute("SELECT * FROM duplicata WHERE nota_fiscal_id = ?", (nota_fiscal[0],)) duplicatas=self.cursor.fetchall() - if duplicatas != None: - print('\n--------- Parcelas da fatura ---------') + duplicatas_dict = [] + # if duplicatas != None: + # print('\n--------- Parcelas da fatura ---------') for dup in duplicatas: - print('Boleto: ', dup[0].split('NFe')[0]) - print('Data de vencimento: ', dup[2]) - print('Valor a ser pago: ', dup[3]) - - print('\n\n') + duplicata_dict = {} + # print('Boleto: ', dup[0].split('NFe')[0]) + duplicata_dict['duplicata_id'] = dup[0].split('NFe')[0] + # print('Data de vencimento: ', dup[2]) + duplicata_dict['data_vencimento'] = dup[2] + # print('Valor a ser pago: ', dup[3]) + duplicata_dict['valor_pago'] = dup[3] + duplicatas_dict.append(duplicata_dict) + nota_fiscal_dict['duplicatas'] = duplicatas_dict + notas_fiscais_dict.append(nota_fiscal_dict) + + # print('\n\n') + # pprint(notas_fiscais_dict) + return notas_fiscais_dict + - def consulta_clientes_de_um_emitente(self, identificador_emitente : str): - self.cursor.execute("SELECT nome FROM emitente WHERE emitente_id = ?", - (identificador_emitente,)) - nome_emitente = notas_fiscais=self.cursor.fetchone()[0] - print("---------------------------------------------------------") - print("Consulta clientes do emitente %s de identificador %s"%(nome_emitente, identificador_emitente)) + def consulta_clientes_de_um_emitente(self, identificador_emitente : str) -> dict: + self.cursor.execute("SELECT * FROM nota_fiscal WHERE emitente_id = ?", (identificador_emitente,)) notas_fiscais=self.cursor.fetchall() + if notas_fiscais == None: + return None + + destinadores_dict = [] + for nota_fiscal in notas_fiscais: self.cursor.execute("SELECT * FROM destinador WHERE destinador_id = ?", (nota_fiscal[2],)) destinadores=self.cursor.fetchall() - if destinadores != None: - print('\n--------- Clientes ---------') + # if destinadores != None: + # print('\n--------- Clientes ---------') for dest in destinadores: - print('Nome: ', dest[1], 'Identificador: ', dest[0]) + # print('Nome: ', dest[1], 'Identificador: ', dest[0]) + destinador_dict = {'destinador_id' : dest[0], 'nome':dest[1]} + destinadores_dict.append(destinador_dict) + + # pprint(destinadores_dict) + return destinadores_dict + def save_nota_fiscal_on_db(self, nota_fiscal : NotaFiscal): diff --git a/NotaFiscal.py b/NotaFiscal.py index 75d0030..6c10edc 100644 --- a/NotaFiscal.py +++ b/NotaFiscal.py @@ -177,7 +177,3 @@ def get_dict_from_xml_tree_element(self, tree_path: str) -> dict: for chield in xml_tree_element: result_dict[chield.tag] = chield.text return result_dict - - - - \ No newline at end of file diff --git a/__pycache__/NotaFiscal.cpython-38.pyc b/__pycache__/NotaFiscal.cpython-38.pyc index adf26a7dcd9254c1f9fc24fddcf3a3a48009431d..256f5aed9971339aae483933e525b9bd153eea93 100644 GIT binary patch delta 1705 zcmZ`(&u<%55Z+&2|J=rLQjs*VNJvn+t!rAM5?azYZByk^p#lv;ds(*LmteGBTjNbA z0jUKdwGx+>kvLJLN(ht-QpJrE9Fgchum>cLh%5FE^7q$j@-s)rn&fbS2 zpJiQ_PF=Tv_w_lGIl;mw`c9_IR;(G9OpXN|JI3TBv!)mzOJ@~)Y&290|27_|F+!#> zJ;9zChDinvv~yAhOySea=_9F5kk>Shn(vw>2U*xMYc+#IRp66BA#$CT@iN)Z;P2)m zTh?lXUR$JmVrxr8u4uO+m#vHVN1=*8WZyYEN3r|;COJkk?0)>>K(=0xfmd=j>Kr%_ z<><}sW;(7kOi0EC{+9c2R+giIO_6Yl;Uq)iui)kUgt~@K{_!GL;^al>3%EwAlU`(r zD?|37%XO?5dM8=dbG#fO8{msxN1sgCx-3!SC-zH@ieA@Nn*EnYn+pw2m7J1P=Dqt2TN+0yayvmM=BA*q*e`AZpyn?@$zG>9hm+22W+wZ^{$xc(q4oHcz1MCvw z*VboCa{P_WR_Mp37txitH6V-2x7&dmfe@|;L|cT%#-CjUJ$?{mt{oab_8$m()7Ar5@s8a$M?&prc(_l^8efPqHXYcU*dP= zJLePg1Q)mssfaO-@V&@$cSP81vHZ>hyfOOuN+QxJ?|4B6+^7?Ifg2L0X-1eP;q)yQ zD)*d=lyG-^jo4>=G1D9-xHtoEl8G9)%98kI+j{>hukb;GAtkibrB~>nxJUSJWr<#g zxv|x^4+JbRtTJ3?xWaIiVP2Ufl#_qhNx9-z8Z-g}?;c k=)6hmI3thZV&Y6zBMB0v51HfKa=YVi2V#YZdkhure;2%MdH?_b delta 1694 zcmZ`(-D@0G6rVd^yUFaX*=%F8F_9*frqjly*wjdyH0ejogVcgGAfqsu&fHB#W@fi{ zCo$4Mg%(r#DY&H4^>1E^vyS)#K*G#fscIebME>5&hMQ2 z@yX2IOnJ3j9#ruAdh+#~zwMSMuAaf4KnYl+#LQugd^J*IO;wl@>yE*c6(!ID{hku& zcU8v>)EkOz{7D=(>uP+v{ieTLt^bhz#fmxx_Y`5lEp>&N@U!~Syi-hDom7O$x){LK zt{HH@6>wV>B%`b0ny}F8nG(ecu8UFEwO~^_ZW5=czD|C2Iuh)q+ z#~_LrtHI~`BCEjf`WNgUaE-f_KovB; z3b(A$3#4I(?IsD;*TW#U*%HT$_}wsNy6d zg-vFfOlFs$F)+%OVP)Xkv($w%z>|QBWmKHa!jbt2sy~4m3nS7?D$^fhQSALx$@zNoK0Rf{82f^ZvXhWVl!J7El^P} zio`2Krl)*66|>};Ub~H3W9woNt_+@~PEJhu2M(&C&h zQZc&2w${6}^AuPhlOrp&@x9rXeIFhT&*3{TR9m_r&xIy$z8r)&pP{=P42#NRiW{ zmseIGxc(U)|g2JBAE7RwgEUkQC3V(k;%%tza|a O7m2n*?|X?2tN#If8e?Pt diff --git a/__pycache__/Nota_fiscal.cpython-38.pyc b/__pycache__/Nota_fiscal.cpython-38.pyc deleted file mode 100644 index 6a4b035bdd5c23de904f310af7f9f3ab42dd1e31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 960 zcmZ`&y>8S%5T04vcg}?bbcCd#q_G4!+DHhYKty*LM9pyA&Y;~4Hy@!yK;y4lA;DAYLLQ28oy(}AhcUA*2!f| zXg%G(1liLmp|1J$aqV(-GHr^y%+L>}v-!fQdG00!4R9xHbE~&>nr%`owxFPeD{S$a zZK2^1Zg8AMGW}AO0m47BCf92Aw}p>wUAs*9xH094Wyl+_DSdwJjV5(vM&+W&n~^rn zCs)r$))aL$AAL5nNj}eQ9{l4`hxG3Jt521h&ZbT&25MqbfIYm}>X!W}DUj2*!u|gl z%ke;PjY}HqN?gNIwBisfLuQc|2S+j?8jX?tQ{%!YQ5ZtT&KhHTR2QaMsWo;JQX6y{ zP67@v#fzt1X7_jWe}>NpKr=TugLm+8i`Zc+&Tt1viyc_v`Jm<3BF3Kh20A`+`Kj#X z&e`cP#rlNdqsCd86q9MG@6q*rr6{S?km?%VCtysZhj{V0OZv8Iob`G8v%E4&`GHbZ ztrsQR50pAzZ9Tk?v?~ECSWu>^8Y$ldtSx-KpSG7w^H)i*s qG?kgTBeG=@LUO$mv+H!j3v0sFPK(fy`}p+Lis)+w4=-jIrQ$arj?k+B diff --git a/app.py b/app.py new file mode 100644 index 0000000..6a7f730 --- /dev/null +++ b/app.py @@ -0,0 +1,104 @@ +from flask import Flask, render_template, request, url_for, flash, redirect, jsonify +from flask_dropzone import Dropzone +import sqlite3 +from werkzeug.exceptions import abort +import os +# Biblioteca para trabalhar com XML +import xml.etree.ElementTree as ET +from typing import List +from NotaFiscal import NotaFiscal +from Database import Database + +test_db : Database = None + +def get_db_connection(): + conn = sqlite3.connect('database.db') + conn.row_factory = sqlite3.Row + return conn + +def get_post(post_id): + conn = get_db_connection() + post = conn.execute('SELECT * FROM posts WHERE id = ?', + (post_id,)).fetchone() + conn.close() + if post is None: + abort(404) + return post + + +app = Flask(__name__) +app.config['SECRET_KEY'] = 'your secret key' +basedir = os.path.abspath(os.path.dirname(__file__)) +app.config.update( + UPLOADED_PATH=os.path.join(basedir, 'uploads'), + # Flask-Dropzone config: + DROPZONE_ALLOWED_FILE_CUSTOM = True, + DROPZONE_ALLOWED_FILE_TYPE='.xml', + DROPZONE_MAX_FILE_SIZE=3, + DROPZONE_MAX_FILES=30, +) +app.run(debug=True) +dropzone = Dropzone(app) + +@app.route('/') +def index(): + # os.remove('database.db') + test_db : Database = Database('database.db', 'schema.sql') + + return render_template('index.html') + +@app.route('/search', methods=['GET', 'POST']) +def search(): + + idetifier = request.args.get('identificador') + if(idetifier == ''): + return render_template('index.html') + + # os.remove('database.db') + test_db : Database = Database('database.db', 'schema.sql') + + # vetor das notas fiscais lidas na entrada + vet_nota_fiscal : List[NotaFiscal] = [] + + + # Lê arquivos xml e guarda eles em objetos + # do tipo NotaFiscal + for file in os.listdir("uploads"): + if file.endswith(".xml"): + # print(file) + nota_fiscal = NotaFiscal("uploads/" + file) + vet_nota_fiscal.append(nota_fiscal) + + emitente_dict_list = [] + for nota_fiscal in vet_nota_fiscal: + emitente_dict = {} + emitente_dict['emitente_id'] = nota_fiscal.get_emit_identifier() + emitente_dict['nome'] = nota_fiscal.get_emit_name() + emitente_dict_list.append(emitente_dict) + + # Percorre as notas fiscais guardadas + for nota_fiscal in vet_nota_fiscal: + test_db.save_nota_fiscal_on_db(nota_fiscal) + + # print("\n\nResultado") + notas_fiscais_de_um_emitente = test_db.consulta_boletos_de_um_emitente(idetifier) + if notas_fiscais_de_um_emitente == None: + return render_template('index.html') + + clientes_de_um_emitente = test_db.consulta_clientes_de_um_emitente(idetifier) + if clientes_de_um_emitente == None: + return render_template('index.html') + + return render_template('index.html', notas_fiscais_de_um_emitente=notas_fiscais_de_um_emitente, clientes_de_um_emitente = clientes_de_um_emitente) + +@app.route('/', methods=['POST', 'GET']) +def upload(): + if request.method == 'POST': + f = request.files.get('file') + file_path = os.path.join(app.config['UPLOADED_PATH'], f.filename) + f.save(file_path) + + return render_template('index.html') + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/test.db b/database.db similarity index 78% rename from test.db rename to database.db index c41188217cf873ce6499668a1b65aa603a91c748..2268f2ccf8476c05fde0101db5269c010d4b3a65 100644 GIT binary patch delta 840 zcmZuw&rcIU6zO>-~eWU6{~HjbsKFwG)s5XP1s6W6{e>JLv)JoKnP)fx4J@=_J$x5^DEF4x7wz^~BsUU%3OrA<*5 zP&CSImEemXjRfcOx@PFu(B{%Qwwm>dT{fwSM&Ug!r+>X+rMh#;V3l6zJLOB&-u*p^1%yL5@6&%mtA!y`H3bDC8G zb-B;CY}%_WL##F(yKL8OSdn}Eq(M!qWx<;uf`i~->nLwR7vZ_GFdKO67f>w5ZA`lt zw^+38m{x7|*y2x$)QMm!!K6Am;MA%FQ}Tr3?2>`Ag>+gSvo3gap@ z$V!tqWpc{(p1As{%~8j!l5vJiY%C}OLWtXZ=yKL;4cc&ru4DWfD-d_BT^zQBQ&~e_ z)blu(Pi3@x5#Q2_SSuJysVswK^sF)NmQi_?n3P!9NM-aphL*{7bixbzb*+##@O&Yk yXYr*@$X_J2X@y`zzsF>~*w(hqS!41!w7u7n-TfNjy>7f8+S#7uPr9$eyMF)@YVOAX delta 1426 zcma*n%}X0W7zXg2B%8_3&Tf#1V~H`dE>)vOiNSO6V}*zawVtYns@a2}5p+F?5Q)?j zp;X^Pub!$$MgIgr1o5sQcoFnuy?OA^p&%aL9awf*emp$PJ4|&yTD^<>N;jl5O*7T= zw)EYeqLb2kKV4hN7mev>n*EqOx326{_SM>^H_X+~=)v*sh|X%?3@Wl&vYmvdgdhy4 zk&)N}X>?#l!m!bfBR@=1-Dty;{urfhR4I@vu(_Y z&2AEhTN6J8d%S>G%JUW+dAzL?RSHzrmVEfkn@|fIycI{kxzmLz1^m@uw!93_yb;xK z#nU*t=ctjOhKbKW<>b6Lj9DY|baOsRh2xM~LohqH=$BRPg^DV^^8OVYp7aK%JUKNu zH15gw|FVfTM9y!OTR{{f>*?{@$I diff --git a/database_utils.py b/database_utils.py deleted file mode 100644 index 9428982..0000000 --- a/database_utils.py +++ /dev/null @@ -1,66 +0,0 @@ -from Database import Database -import os -from NotaFiscal import NotaFiscal - -def create_db(database_str : str) -> Database: - db = Database(database_str) - - sql_create_emitente_table = """ CREATE TABLE IF NOT EXISTS emitente ( - emitente_id text PRIMARY KEY, - nome text NOT NULL - ); """ - - sql_create_destinador_table = """ CREATE TABLE IF NOT EXISTS destinador ( - destinador_id text PRIMARY KEY, - nome text NOT NULL - ); """ - - sql_create_endereco_destinador_table = """ CREATE TABLE IF NOT EXISTS endereco_destinador ( - destinador_endereco_id text PRIMARY KEY, - destinador_id text, - logradouro text NOT NULL, - numero text NOT NULL, - bairro text NOT NULL, - municipio text NOT NULL, - estado text NOT NULL, - cep text NOT NULL, - telefone text NOT NULL, - FOREIGN KEY (destinador_id) REFERENCES destinador (destinador_id) - ); """ - - sql_create_nota_fiscal_table = """ CREATE TABLE IF NOT EXISTS nota_fiscal ( - nota_fiscal_id text PRIMARY KEY, - emitente_id text NOT NULL, - destinador_id text NOT NULL, - valor_total text NOT NULL, - FOREIGN KEY (emitente_id) REFERENCES emitente (emitente_id), - FOREIGN KEY (destinador_id) REFERENCES destinador (destinador_id) - ); """ - - sql_create_duplicata_table = """ CREATE TABLE IF NOT EXISTS duplicata ( - duplicata_id text PRIMARY KEY, - nota_fiscal_id text NOT NULL, - data_vencimento text NOT NULL, - valor_pago text NOT NULL, - FOREIGN KEY (nota_fiscal_id) REFERENCES nota_fiscal (nota_fiscal_id) - ); """ - - - # create tables - if db.conn is not None: - db.create_table(sql_create_emitente_table) - db.create_table(sql_create_destinador_table) - db.create_table(sql_create_endereco_destinador_table) - db.create_table(sql_create_nota_fiscal_table) - db.create_table(sql_create_duplicata_table) - - else: - print("Error! cannot create the Database connection.") - - return db - -def delete_db(db_name : str): - os.remove(db_name) - - - diff --git a/parser.py b/parser.py deleted file mode 100644 index 62172de..0000000 --- a/parser.py +++ /dev/null @@ -1,52 +0,0 @@ -from database_utils import create_db, delete_db -from NotaFiscal import NotaFiscal -from Database import Database -from typing import List -import os - -def main(): - print("Bem vindo!") - print("Este progarma irá ler diversas notas fiscais em formato xml guardadas em uma pasta.") - print("Por favor informe o nome da pasta:") - - # Entrada da linha de comando - # Pasta que contem as notas fiscais - path = 'notasFiscais' - - try: - # Diretório para ser percorrido em busca - # de novos arquivos - os.chdir(path) - except: - print("Pasta não encontrada.") - exit(1) - - db_path = '../test.db' - delete_db(db_path) - test_db : Database = create_db('../test.db') - - # vetor das notas fiscais lidas na entrada - vet_nota_fiscal : List[NotaFiscal] = [] - - idetifier = '07872718000117' - - # Percorre os arquivos de uma dada pasta - # e cria um objeto NotaFiscal para armazenar - # e percorrer os dados do arquivo XML da entrada - for file in os.listdir(): - if file.endswith('.xml'): - # print(file) - nota_fiscal = NotaFiscal(file) - vet_nota_fiscal.append(nota_fiscal) - - # Percorre as notas fiscais guardadas - for nota_fiscal in vet_nota_fiscal: - test_db.save_nota_fiscal_on_db(nota_fiscal) - - # print("\n\nResultado") - # test_db.consulta_boletos_de_um_emitente(idetifier) - # test_db.consulta_clientes_de_um_emitente(idetifier) - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/schema.sql b/schema.sql new file mode 100644 index 0000000..bfd6fec --- /dev/null +++ b/schema.sql @@ -0,0 +1,49 @@ +DROP TABLE IF EXISTS posts; + +CREATE TABLE posts ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + title TEXT NOT NULL, + content TEXT NOT NULL +); + + +CREATE TABLE IF NOT EXISTS emitente ( + emitente_id text PRIMARY KEY, + nome text NOT NULL +); + +CREATE TABLE IF NOT EXISTS destinador ( + destinador_id text PRIMARY KEY, + nome text NOT NULL +); + +CREATE TABLE IF NOT EXISTS endereco_destinador ( + destinador_endereco_id text PRIMARY KEY, + destinador_id text, + logradouro text NOT NULL, + numero text NOT NULL, + bairro text NOT NULL, + municipio text NOT NULL, + estado text NOT NULL, + cep text NOT NULL, + telefone text NOT NULL, + FOREIGN KEY (destinador_id) REFERENCES destinador (destinador_id) +); + +CREATE TABLE IF NOT EXISTS nota_fiscal ( + nota_fiscal_id text PRIMARY KEY, + emitente_id text NOT NULL, + destinador_id text NOT NULL, + valor_total text NOT NULL, + FOREIGN KEY (emitente_id) REFERENCES emitente (emitente_id), + FOREIGN KEY (destinador_id) REFERENCES destinador (destinador_id) +); + +CREATE TABLE IF NOT EXISTS duplicata ( + duplicata_id text PRIMARY KEY, + nota_fiscal_id text NOT NULL, + data_vencimento text NOT NULL, + valor_pago text NOT NULL, + FOREIGN KEY (nota_fiscal_id) REFERENCES nota_fiscal (nota_fiscal_id) +); \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..110b3ef --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,6 @@ +h1 { + border: 2px #eee solid; + color: brown; + text-align: center; + padding: 10px; +} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..d3c4251 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,42 @@ + + + + + + + + + + {{ dropzone.load_css() }} + {{ dropzone.style('border: 2px dashed #0087F7; margin: 3%; min-height: 100px;') }} + {% block title %} {% endblock %} + + + +
+ {% for message in get_flashed_messages() %} +
{{ message }}
+ {% endfor %} + {% block content %} {% endblock %} +
+ + + + + + + + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..0479e8c --- /dev/null +++ b/templates/index.html @@ -0,0 +1,80 @@ +{% extends 'base.html' %} + +{% block content %} +

{% block title %} Bem vindo ao leitor de notas fiscais {% endblock %}

+ +

+ Este site busca boletos e clientes baseado no identificador (CPF ou CNPJ) de um fornecedor. +

+ +

+
Digite o identificador de um forncedor:
+ + +
+ +
+

Clientes:

+
+ + + + + + + + + + {% for cliente in clientes_de_um_emitente %} + + + + + + {% endfor %} + +
#destinador_idnome
1{{ cliente.destinador_id }}{{ cliente.nome }}
+
+
+ +
+ +

Notas fiscais:

+ {% for nota_fiscal in notas_fiscais_de_um_emitente %} +
+
{{'infNFe: ' + nota_fiscal.nota_fical_id + ' Valor total a pagar: ' + nota_fiscal.valor_total}}
+ {% if nota_fiscal.duplicatas == []%} +
Esta nota fiscal não possui boletos.
+ {% else %} + + + + + + + + + + {% for duplicata in nota_fiscal.duplicatas %} + + + + + + {% endfor %} + +
Boleto n°data_vencimentovalor_pago
1{{ duplicata.data_vencimento }}{{ duplicata.valor_pago }}
+ {% endif %} +
+ {% endfor %} +
+ + {{ dropzone.create(action='upload') }} + {{ dropzone.load_js() }} + {{ dropzone.config() }} + {# You can get the success response from server like this: #} + {#{ dropzone.config(custom_options="success: function(file, response){console.log(response);}") }#} + + +{% endblock %} diff --git a/uploads/32211207872718000117550010000217781877120005-nfe.xml b/uploads/32211207872718000117550010000217781877120005-nfe.xml new file mode 100644 index 0000000..a9d9335 --- /dev/null +++ b/uploads/32211207872718000117550010000217781877120005-nfe.xml @@ -0,0 +1,277 @@ + + + + + + 32 + 87712000 + VENDA MERCAD.ADQ.TERCEIROS + 55 + 1 + 21778 + 2021-12-01T19:03:21-03:00 + 2021-12-01T19:03:21-03:00 + 1 + 1 + 3201308 + 1 + 1 + 5 + 1 + 1 + 0 + 1 + 0 + MeLinux 6.3 + + + 07872718000117 + COMERCIAL S.R.DE ALIMENTOS LTDA-ME + SR ALIMENTOS + + R.ODONIA DA COSTA MACHADO TOLEDO + 56 + QUADRA 1 LOTE 5 + TIRADENTES + 3201308 + CARIACICA + ES + 29143529 + 1058 + BRASIL + 2733363026 + + 082384975 + 3 + + + 17197072000173 + JEFERSON SIMAO DE OLIVEIRA - ME + + RUA SAO JOAO + 49 + ITACIBA + 3201308 + CARIACICA + ES + 29150230 + 1058 + BRASIL + 27996502121 + + 1 + 082917825 + + + + 001378 + SEM GTIN + FILE MERLUZA ARGENTINA INTERF.CX 18 c/ 18 KG + 03047400 + 5102 + CX + 1 + 503.82 + 503.82 + SEM GTIN + CX + 18 + 27.99 + 1 + + + + + 2 + 20 + 3 + 58.82 + 207.46 + 17.00 + 35.27 + + + + 999 + + 53 + + + + + 01 + 503.82 + 0.65 + 3.27 + + + + + 01 + 503.82 + 3.00 + 15.11 + + + + + + + 000195 + 7896481907388 + CUPIM MAGRO FRISA CX -+ 18KG + 02013000 + 1708400 + 5405 + KG + 21.71 + 29.12989406 + 632.41 + 7896481907388 + KG + 21.71 + 29.12989406 + 1 + + + + + 0 + 60 + + + + 999 + + 53 + + + + + 01 + 632.41 + 0.65 + 4.11 + + + + + 01 + 632.41 + 3.00 + 18.97 + + + + + + + 207.46 + 35.27 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 1136.23 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 7.38 + 34.08 + 0.00 + 1136.23 + + + + 9 + + 07872718000117 + COMERCIAL S.R.DE ALIMENTOS LTDA-ME + 082384975 + RUA ODONIA DA COSTA MACHADO TOLEDO, 41 QD 1 LOTE 5 TIRADENTE + CARIACICA + ES + + + 23 + DIVERSAS + DIVERSAS + 40.106 + + + + + 021778 + 1136.23 + 0.00 + 1136.23 + + + 001 + 2022-12-15 + 568.11 + + + 002 + 2022-12-22 + 568.12 + + + + + 15 + 1136.23 + + + + Cod.Dest: 7452 Fantasia: REST.ESPA.GRILL Faturista: IGOR REIS # Forma Pag: BOLETO # Vendedor: TACIANI (27)99735-5228 Num.Ped: 102667 # Doc.emitido por ME/EPP optante do SIMPLES NACIONAL; nao gera credito fiscal de IPI e ISS # RUA DA FEIRA # sem email cadastrado para envio do XML # # Confira no ato da entrega, evite reclamacoes posteriores + + + 19495981000113 + OTMA SOLUCOES LTDA + contato@otmasolucoes.com.br + 2721417943 + + + + + + + + + + + + + yU29u4Sva8be/dmxDzD7eyMIOaY= + + + O3P2ebus27f8wlWBnyncdvcBVPvwWMqPMdMFehYZcjUxeY8Bir1ZPlf3ERQoBf3OQjlhQSlOL9MhDM2xVJ3tFKaqPSaDufIUGfuPSVgPOjtij6aCERyngmGJ+gSAVGLdEXB/a0/FJSEFF4qQCFeuQQVLC2fdKIEUEhCMgt/vqHHoyGuR9F+9x6Z7iZlUhltt7mmL/I0fCt3LFKLuXuVZUqURYRUhFU5EZF4jL0J7e4gl8CSN9DcLJH5I4IGDBzjcwVbqaSQ8mYWUx/bxCWzKGLYmmGcLwEOeZMJQcC7Q6O/Gy28kf1GFXHVtL7Yue3RkXS8BfxOVXN8LO5Yp6noBog== + + + MIIHRzCCBS+gAwIBAgIIXjohEAZBCBIwDQYJKoZIhvcNAQELBQAwWTELMAkGA1UEBhMCQlIxEzARBgNVBAoTCklDUC1CcmFzaWwxFTATBgNVBAsTDEFDIFNPTFVUSSB2NTEeMBwGA1UEAxMVQUMgQ0VSVElGSUNBIE1JTkFTIHY1MB4XDTIxMTAwNjE0MzUwMFoXDTIyMTAwNjE0MzUwMFowgeYxCzAJBgNVBAYTAkJSMRMwEQYDVQQKEwpJQ1AtQnJhc2lsMQswCQYDVQQIEwJFUzESMBAGA1UEBxMJQ2FyaWFjaWNhMR4wHAYDVQQLExVBQyBDRVJUSUZJQ0EgTUlOQVMgdjUxFzAVBgNVBAsTDjI4MjM0NTI4MDAwMTQ0MRMwEQYDVQQLEwpQcmVzZW5jaWFsMRowGAYDVQQLExFDZXJ0aWZpY2FkbyBQSiBBMTE3MDUGA1UEAxMuQ09NRVJDSUFMIFMgUiBERSBBTElNRU5UT1MgTFREQTowNzg3MjcxODAwMDExNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJFLgZuS99JDIlEh144LxoP7DrhZMhnABZHUU0Cfn9DBmDcG26upjzRnJCiazgza9+LGvUnd9uTkvCTOwpuADX1N2eRN5bWtpvL9oaT750B0VzGcuoeZHTAIh/VuAU/QBs1i/ADxqe3saiNzh320NxzCZwiqY7I/2oKGxd5ZrMwmrV3lbSsq3v+sjKSqhI1FF990D/9waqQuarg4jDz/ChV0PcZVwAJgOPC7P2dkDe3p9nz/D8pqpuCqJ8ODtyrFUW5CfxVwluoqPc3VhmywNROns7aXTPACVzkAkvlO7+2mLK29ooYI7m5vzlqPmzAUhk+uHkAhzcWrMvJvL7j/xaECAwEAAaOCAoMwggJ/MB8GA1UdIwQYMBaAFD/TXKkZTdeIFi2YDK8K3uFPJBawMFkGCCsGAQUFBwEBBE0wSzBJBggrBgEFBQcwAoY9aHR0cDovL2NjZC5hY3NvbHV0aS5jb20uYnIvbGNyL2FjLWNlcnRpZmljYW1pbmFzLXNtaW1lLXY1LnA3YjCBtQYDVR0RBIGtMIGqgRdzcmFsaW1lbnRvczExQGdtYWlsLmNvbaAbBgVgTAEDAqASExBTT0xJVkFOIERBIENVTkhBoBkGBWBMAQMDoBATDjA3ODcyNzE4MDAwMTE3oD4GBWBMAQMEoDUTMzE1MDQxOTU1OTA2ODAwNDk4MDAwMDAwMDAwMDAwMDAwMDY1Ni40MTIgLSBFU1NFU1BFU6AXBgVgTAEDB6AOEwwwMDAwMDAwMDAwMDAwYgYDVR0gBFswWTBXBgZgTAECAWAwTTBLBggrBgEFBQcCARY/aHR0cDovL2NjZC5hY3NvbHV0aS5jb20uYnIvZG9jcy9kcGMtYWMtY2VydGlmaWNhbWluYXMtc21pbWUucGRmMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDCBlgYDVR0fBIGOMIGLMEOgQaA/hj1odHRwOi8vY2NkLmFjc29sdXRpLmNvbS5ici9sY3IvYWMtY2VydGlmaWNhbWluYXMtc21pbWUtdjUuY3JsMESgQqBAhj5odHRwOi8vY2NkMi5hY3NvbHV0aS5jb20uYnIvbGNyL2FjLWNlcnRpZmljYW1pbmFzLXNtaW1lLXY1LmNybDAdBgNVHQ4EFgQUgjYXha8mHLX9hIucnUK7C22g8SswDgYDVR0PAQH/BAQDAgXgMA0GCSqGSIb3DQEBCwUAA4ICAQAtmAnla1kBFaW7QdeDhwGTsevT3bNYoiDQUptg+J6zOt68/UPR1zCy0EjdlzTkB7yQf3UTY2syhnYsYevl00iJJQbxU9Jruu8NzzRsGKK+R/b9U1Bfw/3KZ7Dc4Yv9r7nCj33ox1Cj6YzmibtDGdRhZ2jk64mhcXt3dcYc7rjpbWkt9Am1N2joxuYB2TC1HIVbNp/apU8EwGy9HtOlLLVSpCXg+8XiFvDNnWDOVONE+UKTn2FY/gmvhElPpYrrS7Fkwbw6AqxPfU+m8afz6QmTmJ1kQipBO0YYbp/MKMUE7yzHW3mvOu33jGOJnprN0vZgGy06HNBcW5bgZ4+kYNA1vPTAdKYR5hHR5OPefSSRgoda5zXoqit5EzdQIElTDIvjVZnLrj3vcHcD4WzEyf+VeGgh7U/+zFTuf8tvWig14FoyVqHO9WaiojVgLbGKYlcg3BWdvqNdfJFDKRbyv1G6wVtXBhE0bem0UZFAc00/9DBGpkm3Wm942zDsHCjlMH7jlCR+iVa98wsKmZBXXUvSV9K8N6uBxJdpxlInht1KsgFrQDoije7N85xbAj0sXEaH+1wgoVz+Sv/v+g9xZN+TgkEi+7xjc3uC0syF2tCzvJV+73vRmpJpWsy4s01xK6QGyh9+sxTuhG2mfVD52PokTdR8oB0GYBsRzSfju2f8Bg== + + + + + + + 1 + SVRS202111190951 + 32211207872718000117550010000217781877120005 + 2021-12-01T19:03:22-03:00 + 332210083442441 + yU29u4Sva8be/dmxDzD7eyMIOaY= + 100 + Autorizado o uso da NF-e + + + \ No newline at end of file diff --git a/uploads/NFe-002-3103.xml b/uploads/NFe-002-3103.xml new file mode 100644 index 0000000..ec2ae56 --- /dev/null +++ b/uploads/NFe-002-3103.xml @@ -0,0 +1,311 @@ + + + + + + 31 + 00464032 + Vendas a prazo + 55 + 2 + 3103 + 2019-04-10T17:24:03-02:00 + 2019-04-11T17:17:30-02:00 + 1 + 1 + 3170206 + 1 + 1 + 7 + 1 + 1 + 0 + 1 + 0 + 001 + + + 06273476000182 + MECA Office Mobil. Eireli-ME + MECA Office Mobil. Eireli-ME + + AV. MARCOS DE FREITAS COSTA + 1055 + DANIEL FOSECA + 3170206 + Uberlandia + MG + 38400328 + 1058 + BRASIL + 3432385585 + + 7022916720058 + 1 + + + 25587387000155 + HLTS ENGENHARIA E CONSTRUCOES LTDA + + RUA MACHADO DE ASSIS + 1324 + LIDICE + 3170206 + Uberlandia + MG + 38400081 + 1058 + BRASIL + 3432235966 + + 1 + 7021771340054 + + + + 00331 + SEM GTIN + CADEIRA GIRATORIA S/ BRACO ALMOFADADA PRETO + 94019090 + 5102 + UN + 2 + 165.00000 + 330.00 + SEM GTIN + UN + 2 + 165.00000 + 1 + + + 77.68 + + + 0 + 102 + + + + + 08 + + + + + 08 + + + + IMOBILIZADO IMOB - 2317 CADEIRA GIRATORIA S/ BRACO ALMOFADADA PRETO - IMOBILIZADO EQUIP. MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO. + + + + 01228 + SEM GTIN + CADEIRA GIRATORIA C/ BRACO ALMOFADADA PRETO + 94019090 + 5102 + UN + 1 + 215.00000 + 215.00 + SEM GTIN + UN + 1 + 215.00000 + 1 + + + 50.61 + + + 0 + 102 + + + + + 08 + + + + + 08 + + + + IMOBILIZADO EQUIP/MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO + + + + 01324 + SEM GTIN + BANQUETA ALTA 70CM PARA BALCAO ASSENTO 30 OU + 94019090 + 5102 + PC + 1 + 90.00000 + 90.00 + SEM GTIN + PC + 1 + 90.00000 + 1 + + + 21.19 + + + 0 + 102 + + + + + 08 + + + + + 08 + + + + 40CM NA COR PRETA - IMOBILIZADO EQUIP./MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO + + + + 01644 + SEM GTIN + ESTANTE ACO C/ 06 PRATELEIRAS 0,93X040X1,98M + 94069020 + 5102 + PC + 2 + 234.00000 + 468.00 + SEM GTIN + PC + 2 + 234.00000 + 1 + + + 45.87 + + + 0 + 102 + + + + + 08 + + + + + 08 + + + + (REFORCADA) AMAPA - IMOBILIZADO. + + + + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 1103.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 1103.00 + 195.35 + + + + 0 + + 6 + VOLUME + VARIAS + 0.000 + 0.000 + + + + + 000003103 + 1103.00 + 0.00 + 1103.00 + + + 001 + 2019-05-11 + 1103.00 + + + + + 14 + 1103.00 + + 0.00 + + + ORDEM DE FORNECIMENTO 36994 - 28DD - INFORMACOES COMPLEMENTARES a seguinte informacao. EMPRESA ENQUADRADA NO SIMPLES NACIONAL. NAO GERA CREDITO DE IPI/ISS. GERA CREDITO DE ICMS. Trib aprox R$: 54,84 Federal 140,51 Estadual Fonte: IBPT empresometro.com.br S3A6R4 + + + + + + + + + + + + + ngqVwH6QNCAHyRuI529RIAr7Nyk= + + + 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 + + + + + + + 1 + 14.2.26 + 31190406273476000182550020000031031004640327 + 2019-04-10T17:23:27-03:00 + 131193257591884 + ngqVwH6QNCAHyRuI529RIAr7Nyk= + 100 + Autorizado o uso da NF-e + + + \ No newline at end of file From 063115aa7ba5a64ed287dd41c9c02564d1231fac Mon Sep 17 00:00:00 2001 From: Lucas_Moraes_Wize Date: Fri, 1 Apr 2022 23:19:41 -0300 Subject: [PATCH 5/7] =?UTF-8?q?Fix:=20C=C3=B3digo=20simplificado=20no=20ar?= =?UTF-8?q?quivo=20app.=20Comtarios=20foram=20acrescentados.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Database.py | 59 ++-- README.md | 77 ++--- app.py | 67 ++-- database.db | Bin 53248 -> 0 bytes makefile | 19 ++ ...05570714000825550010109071851235294293.xml | 205 ------------ ...2718000117550010000217781877120005-nfe.xml | 277 ---------------- notasFiscais/NFe-002-3103.xml | 311 ------------------ requirements.txt | 9 + templates/base.html | 11 +- templates/index.html | 6 +- ...2718000117550010000217781877120005-nfe.xml | 277 ---------------- uploads/NFe-002-3103.xml | 311 ------------------ 13 files changed, 123 insertions(+), 1506 deletions(-) delete mode 100644 database.db create mode 100644 makefile delete mode 100644 notasFiscais/32210605570714000825550010109071851235294293.xml delete mode 100644 notasFiscais/32211207872718000117550010000217781877120005-nfe.xml delete mode 100644 notasFiscais/NFe-002-3103.xml create mode 100644 requirements.txt delete mode 100644 uploads/32211207872718000117550010000217781877120005-nfe.xml delete mode 100644 uploads/NFe-002-3103.xml diff --git a/Database.py b/Database.py index a35759f..4cc4c1d 100644 --- a/Database.py +++ b/Database.py @@ -21,12 +21,9 @@ def __init__(self, input_path: str, schema_path: str): self.conn : Connection = self.create_connection() self.cursor = self.conn.cursor() + # Cria conexão com um banco de dados já existente ou cria + # um novo banco de dados atraves do esquema passado def create_connection(self) -> Connection: - """ create a Database connection to the SQLite Database - specified by db_file - :param db_file: Database file - :return: Connection object or None - """ conn : Connection = None try: conn = sqlite3.connect(self.db_path) @@ -38,13 +35,9 @@ def create_connection(self) -> Connection: return conn + # Cria tabela no banco de dados ou caso sejam passos argumentos + # os mesmos são usados para prencher uma tabela existente. def create_table(self, create_table_sql : str, args : str = None) -> None: - """ create a table from the create_table_sql statement - :param conn: Connection object - :param create_table_sql: a CREATE TABLE statement - :return: - """ - # print(args) try: if args == None: self.cursor.execute(create_table_sql) @@ -55,12 +48,7 @@ def create_table(self, create_table_sql : str, args : str = None) -> None: print(e) def create_emitente(self, emitente) -> None: - """ - Create a new project into the projects table - :param conn: - :param project: - :return: project id - """ + sql = ''' INSERT INTO emitente(emitente_id, nome) VALUES(?,?) ''' @@ -97,7 +85,6 @@ def create_endereco_destinador(self, endereco) -> None: )) def create_nota_fiscal(self, nota_fiscal): - # print(nota_fiscal) sql = ''' INSERT INTO nota_fiscal(nota_fiscal_id, emitente_id, destinador_id, @@ -120,19 +107,20 @@ def create_duplicata(self, duplicata): duplicata['data_vencimento'], duplicata['valor_pago'])) + # Checa se um dado identificador existe em uma dada tabela def check_if_exists_in_bd(self, table : str, identifier : str) -> bool: sql = "SELECT * FROM "+ table + " WHERE "+ table +"_id = ?" self.cursor.execute(sql, (identifier,)) data = self.cursor.fetchone() if data is None: - # print('There is no component named %s', emitente_dict['emitente_id']) return True else: print('Emitente com identificador %s já existe no sistema'%(identifier)) return False - def consulta_boletos_de_um_emitente(self, identificador_emitente : str) -> dict: + # Consulta nota fiscal de duplicatas de um dado emitente. + def consulta_nota_fiscal_e_duplicatas_de_um_emitente(self, identificador_emitente : str) -> dict: self.cursor.execute("SELECT * FROM nota_fiscal WHERE emitente_id = ?", (identificador_emitente,)) @@ -140,38 +128,27 @@ def consulta_boletos_de_um_emitente(self, identificador_emitente : str) -> dict: if notas_fiscais == None: return None - # print("Notas fiscais") - # print(notas_fiscais[0][0]) notas_fiscais_dict = [] for nota_fiscal in notas_fiscais: nota_fiscal_dict = {} - # print('\n--------- Nota fiscal ---------') - # print('Código: ', nota_fiscal[0], ' ') nota_fiscal_dict['nota_fical_id'] = nota_fiscal[0] - # print('Valor total da nota: ', nota_fiscal[3]) nota_fiscal_dict['valor_total'] = nota_fiscal[3] self.cursor.execute("SELECT * FROM duplicata WHERE nota_fiscal_id = ?", (nota_fiscal[0],)) duplicatas=self.cursor.fetchall() duplicatas_dict = [] - # if duplicatas != None: - # print('\n--------- Parcelas da fatura ---------') + for dup in duplicatas: duplicata_dict = {} - # print('Boleto: ', dup[0].split('NFe')[0]) duplicata_dict['duplicata_id'] = dup[0].split('NFe')[0] - # print('Data de vencimento: ', dup[2]) duplicata_dict['data_vencimento'] = dup[2] - # print('Valor a ser pago: ', dup[3]) duplicata_dict['valor_pago'] = dup[3] duplicatas_dict.append(duplicata_dict) nota_fiscal_dict['duplicatas'] = duplicatas_dict notas_fiscais_dict.append(nota_fiscal_dict) - # print('\n\n') - # pprint(notas_fiscais_dict) return notas_fiscais_dict @@ -190,26 +167,28 @@ def consulta_clientes_de_um_emitente(self, identificador_emitente : str) -> dict self.cursor.execute("SELECT * FROM destinador WHERE destinador_id = ?", (nota_fiscal[2],)) destinadores=self.cursor.fetchall() - # if destinadores != None: - # print('\n--------- Clientes ---------') + for dest in destinadores: - # print('Nome: ', dest[1], 'Identificador: ', dest[0]) + destinador_dict = {'destinador_id' : dest[0], 'nome':dest[1]} destinadores_dict.append(destinador_dict) - # pprint(destinadores_dict) return destinadores_dict - + # Salva nota fiscal no banco de dados def save_nota_fiscal_on_db(self, nota_fiscal : NotaFiscal): # Emitente + # Salva novo emitente (fornecedor) no banco de dados caso o mesmo + # não exista. emitente_dict = {'emitente_id' : nota_fiscal.get_emit_identifier(), 'nome' : nota_fiscal.get_emit_name()} if self.check_if_exists_in_bd('emitente',emitente_dict['emitente_id']): self.create_emitente(emitente_dict) # Destinador + # Salva novo destinador (cliente) no banco de dados caso o mesmo + # não exista destinador_dict = {'destinador_id' : nota_fiscal.get_dest_identifier(), 'nome' : nota_fiscal.get_dest_name()} @@ -217,10 +196,12 @@ def save_nota_fiscal_on_db(self, nota_fiscal : NotaFiscal): self.create_destinador(destinador_dict) # Endereço do destinador + # Salva endereço relacionado a um novo destinador. endereco_destinador = nota_fiscal.get_dest_enderDest() self.create_endereco_destinador(endereco_destinador) # Nota fiscal + # Salva uma nova nota fiscal no banco caso a mesma não exista nota_fiscal_dict = {'nota_fiscal_id' : nota_fiscal.get_nota_fiscal_id(), 'emitente_id' : nota_fiscal.get_emit_identifier(), 'destinador_id' : nota_fiscal.get_dest_identifier(), @@ -229,7 +210,9 @@ def save_nota_fiscal_on_db(self, nota_fiscal : NotaFiscal): if self.check_if_exists_in_bd("nota_fiscal",nota_fiscal_dict['nota_fiscal_id']): self.create_nota_fiscal(nota_fiscal_dict) + # Salva as duplicatas relacionadas a uma nota fiscal. # Duplicata é parte da fatura pois a mesma pode ter mais de uma - # parcela. + # parcela. Duplicata também é chamada de boleto no contexto em + # que esse programa se aplica for duplicata in nota_fiscal.get_faturas(): self.create_duplicata(duplicata) \ No newline at end of file diff --git a/README.md b/README.md index 817b8c7..10e5be7 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,51 @@ # Venha para Recomb -O desafio é desenvolver um programa que permita realizar as seguintes buscas: +## Documentação da solução -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. +### Solução -**Escolha as tecnologias que você vai usar e tente montar uma solução completa para rodar a aplicação.** +A solução implementada recebe um ou mais arquivos .xml de notas fiscais em um página web. -Para enviar o resultado, basta realiazar um Fork deste repositório e abra um Pull Request, com seu nome. +Através de um serviço Flask, esses arquivos são enviado da página web para ter suas informações extraidas e salvas em um banco de dados. -É importante comentar que deve ser enviado apenas o código fonte. Não aceitaremos códigos compilados. +Por fim, é possível realizar consultas aos clientes e boletos de um dado fornecedor. +### Módulos -Por fim, o candidato deve atualizar o Readme.md com as seguintes informações: - - 1) Documentação da solução; - 2) Lista dos diferenciais implementados +A implentação da solução foi dividida em módulos: +- [Database](./Database.py): Classe que realiza comunicação com o banco. +- [NotaFiscal](./NotaFiscal.py): Classe que extrai e armazena em memória as informações de um arquivo XML. +- [App](./app.py): Arquivo com funções que criam interfaces entre as classes chave do sistema e os componentes HTML que exibem os resultados. +- [Schema](./schema.sql): Arquivo com schema do banco de dados. -## Avaliação +### Pastas +- [Static](./static): Pasta que contem os estilos CSS das páginas do sistema. +- [Templates](./templates/): Pasta que contem os arquivos HTML da página web. +- [Uploads](./uploads/): Pasta que armazena os quivos XML enviados pelo usuário do sistema. -O programa será avaliado levando em conta os seguintes critérios: -|Critério| Valor| -|-------|--------| -|Legibilidade do Código |10| -|Organização do Código|10| -|Documentação do código |10| -|Documentação da solução |10| -|Tratamento de Erros |10| -|Total| 50| +### Execução +Para preparar o ambiente execute o comando: +``` +make init_env +``` -A pontuação do candidato será a soma dos valores obtidos nos critérios acima. +Para executar o código após a preparação do ambiente execute: +``` +make all +``` -## Diferenciais +Durante a execução do algorítimo os dados utilizados serão guardados assim, caso o usuário deseje apagar todos os dados salvos basta rodar o comando: +``` +make clean_db_uploads +``` + +## Lista dos diferenciais implementados -O candidato pode aumentar a sua pontuação na seleção implementando um ou mais dos itens abaixo: |Item | Pontos Ganhos| |-----|--------------| |Criar um serviço com o problema |30| |Utilizar banco de dados |30| -|Implementar Clean Code |20| -|Implementar o padrão de programação da tecnologia escolhida |20| -|Qualidade de Código com SonarQube| 15| -|Implementar testes unitários |15| -|Implementar testes comportamentais | 15| -|Implementar integração com Travis |10| -|Implementar integração com Travis + SonarQube |10| -|Implementar usando Docker |5| -|Total | 170| - -A nota final do candidato será acrescido dos pontos referente ao item implementado corretamente. - -## Penalizações - -O candidato será desclassifiado nas seguintes situações: - -1) Submeter um solução que não funcione; -2) Não cumprir os critérios presentes no seção Avaliação; -3) Plágio; - - +|Total | 60| +## Desafio +Descrito no [repositório original](https://github.com/recombX/venhapararecomb#readme) do desafio. \ No newline at end of file diff --git a/app.py b/app.py index 6a7f730..62a1f4c 100644 --- a/app.py +++ b/app.py @@ -1,13 +1,11 @@ from flask import Flask, render_template, request, url_for, flash, redirect, jsonify from flask_dropzone import Dropzone -import sqlite3 from werkzeug.exceptions import abort -import os -# Biblioteca para trabalhar com XML -import xml.etree.ElementTree as ET from typing import List from NotaFiscal import NotaFiscal from Database import Database +import os +import sqlite3 test_db : Database = None @@ -31,72 +29,71 @@ def get_post(post_id): basedir = os.path.abspath(os.path.dirname(__file__)) app.config.update( UPLOADED_PATH=os.path.join(basedir, 'uploads'), - # Flask-Dropzone config: DROPZONE_ALLOWED_FILE_CUSTOM = True, DROPZONE_ALLOWED_FILE_TYPE='.xml', DROPZONE_MAX_FILE_SIZE=3, DROPZONE_MAX_FILES=30, ) + app.run(debug=True) dropzone = Dropzone(app) @app.route('/') def index(): - # os.remove('database.db') - test_db : Database = Database('database.db', 'schema.sql') return render_template('index.html') +# Busca no banco de d @app.route('/search', methods=['GET', 'POST']) def search(): + # Recebe da página web o valor de um indentificador (CPF/CNPJ) idetifier = request.args.get('identificador') + # Caso não receba nada não haverá busca alguma if(idetifier == ''): return render_template('index.html') # os.remove('database.db') + # Cria conexão com banco existente ou cria um novo banco + # Baseado no schema contido no aquivo schema.sql test_db : Database = Database('database.db', 'schema.sql') - # vetor das notas fiscais lidas na entrada - vet_nota_fiscal : List[NotaFiscal] = [] - - - # Lê arquivos xml e guarda eles em objetos - # do tipo NotaFiscal - for file in os.listdir("uploads"): - if file.endswith(".xml"): - # print(file) - nota_fiscal = NotaFiscal("uploads/" + file) - vet_nota_fiscal.append(nota_fiscal) - - emitente_dict_list = [] - for nota_fiscal in vet_nota_fiscal: - emitente_dict = {} - emitente_dict['emitente_id'] = nota_fiscal.get_emit_identifier() - emitente_dict['nome'] = nota_fiscal.get_emit_name() - emitente_dict_list.append(emitente_dict) - - # Percorre as notas fiscais guardadas - for nota_fiscal in vet_nota_fiscal: - test_db.save_nota_fiscal_on_db(nota_fiscal) - - # print("\n\nResultado") - notas_fiscais_de_um_emitente = test_db.consulta_boletos_de_um_emitente(idetifier) + # Consulta as notas fiscais e boletos de um dado emitente (fornecedor) + notas_fiscais_de_um_emitente = test_db.consulta_nota_fiscal_e_duplicatas_de_um_emitente(idetifier) + # Caso não encontre nenhuma nota fiscal não há o que procurar if notas_fiscais_de_um_emitente == None: return render_template('index.html') + # Consulta todos os destinadores (clientes) de um fornecedor clientes_de_um_emitente = test_db.consulta_clientes_de_um_emitente(idetifier) - if clientes_de_um_emitente == None: - return render_template('index.html') return render_template('index.html', notas_fiscais_de_um_emitente=notas_fiscais_de_um_emitente, clientes_de_um_emitente = clientes_de_um_emitente) +# Permite que os arquivos colocados na área de upload sejam salvos na pasta uploads @app.route('/', methods=['POST', 'GET']) -def upload(): +def upload_xml_files(): if request.method == 'POST': f = request.files.get('file') file_path = os.path.join(app.config['UPLOADED_PATH'], f.filename) f.save(file_path) + + # os.remove('database.db') + test_db : Database = Database('database.db', 'schema.sql') + + # vetor das notas fiscais lidas na entrada + vet_nota_fiscal : List[NotaFiscal] = [] + + # Lê arquivos xml e guarda eles em objetos + # do tipo NotaFiscal + for file in os.listdir("uploads"): + if file.endswith(".xml"): + nota_fiscal = NotaFiscal("uploads/" + file) + vet_nota_fiscal.append(nota_fiscal) + + # Percorre as notas fiscais guardadas + for nota_fiscal in vet_nota_fiscal: + # Salva uma nota fiscal no banco de dados + test_db.save_nota_fiscal_on_db(nota_fiscal) return render_template('index.html') diff --git a/database.db b/database.db deleted file mode 100644 index 2268f2ccf8476c05fde0101db5269c010d4b3a65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 zcmeI*%WvC89tUtzj9*G@#tSTjY~W-JqkxIlUJfaW(qXa7(6qx;5)+cz)Mx>Lmgs

XhLjVF0fB*y_0D=Eo z;MwBUh1~7i{QLDdIB12<)8kgu2;yKga?Nxt!?%cU+$mdRG@EQ@2^&V!^{7eW@V%Ja zckPPd?vppI{Wtna+MPJ4A4a`K&>AJGIzFk^%H=_dCM&Q0By2aLqp%%!2Kl6uJPBHz zZv8lTG^e#`1U}bB z;}VCBFtBNL9(7sMoOY+~yzSGYaQc#iAnHzEa&+2`8qskyHA7ZqR@$^yZiL6vX2)SG zJnXc?Y0EC5U9H9W+`f8IyN*~V^yrkCOYhDt3+}axdln!>vvrq5vb8{tC)8X8+dJZRtJJGa5 z>iJs!`O19GT)U{2qde(wY>s_pEGAzY_cQak*I(!N`xQMq?DfKvQ+7NKpPLj?)qZZ_ zW;-|v-(YJ>Pj{9Va=9G;>`_0@<4!N`^V$^)cuClc% zR@EPTm>S(Mh{GoF?TY33M&&*k9tp{gwQJPMJ~3-9JK+2EQIf%$aTK>g;#+UA@1E56 zPou*QtnE0xC@b|(@RKup3=n_-1Rwwb2tWV=5P$##AOHafytD#1|9@$l78?cu2tWV= z5P$##AOHafKmY;|7zrfj{~7UPPW&%>!2kgWKmY;|fB*y_009U<00Izzz;7;~W(4Vh ztQU1fr$t$oDb-D?PZtqycD6?Axs=niqvcF?&Rje&ukSw{N=xSasBr6q_ zie(zaIXsLSA*pl@qSiLCqHfrVSn@2}s*LzGC;rG@FhBqT5P$##AOHafKmY;|fB*y_ z@Ou;ZgCOzg-h<4lAT6c)29o%{ApV0BzYsrTZx|o|0SG_<0uX=z1Rwwb2tWV=5V&js zSrDW*sZL9}tSd>ZURUoW4|4UKD)HD8W*zplKjM__zgxCzkS$WN{*)0mUZa{U=e1&9 zSM_quG(1vqT*LBI7WsdmXj)NMi+Ylqrrj<39R`sso+6J+R=~O-6t(gvcQfzX? zKob8K#4kAU8`cBx<7ICk@`C^bAOHafKmY;|fB*y_009U<;F1NBcz?PxK@f!vexkRa zAOBDH5cK2!E5C5!$KnI_h5-T)fB*y_009U<00Izz00bcL5((@JSxI_r_2%u>wT<*C zb9&0H8N_2@_cv!3b|)_HIM8#?BDdczLjK^Pj1(jm12nviq0bV2Ry5# z_QxCRt844&v-b21D(R=>Y3%lT z+7HE3T`$t2uCo-ftff<>FBG6uEo>|5!^~Vy+PHC+v0RWfjosQ$^Fgn9m;~Ng+`gYV zl}l`PQKKvf&jSBSNlibMZ{nJLS}bl;^&vm1F{LFrpH7}+np9DiRhsL5dRN2@k{YTF?e-$0c3T8;>t&ty5-0W0uX=z1Rwwb2tWV=5P$##An+oA zC&Jvx5Li8n0#0+dq#g!E`66z%Du@h zJV-K{;rxBZkP*5p diff --git a/makefile b/makefile new file mode 100644 index 0000000..173b016 --- /dev/null +++ b/makefile @@ -0,0 +1,19 @@ +export FLASK_ENV := development + +all: + echo FLASK_ENV: $$FLASK_ENV + flask run + +clean_db_uploads: + rm -rf database.db uploads/* + +init_env: + python3 -m venv env + . env/bin/activate + pip install -r requirements.txt + + + + + + diff --git a/notasFiscais/32210605570714000825550010109071851235294293.xml b/notasFiscais/32210605570714000825550010109071851235294293.xml deleted file mode 100644 index d8cf596..0000000 --- a/notasFiscais/32210605570714000825550010109071851235294293.xml +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - 32 - 23529429 - VENDA PARA CONSUMIDOR FINAL - 55 - 1 - 10907185 - 2021-06-04T00:00:00-02:00 - 2021-06-04T06:56:05-02:00 - 1 - 1 - 3205101 - 1 - 1 - 3 - 1 - 1 - 1 - 2 - 0 - MIGRATEGNFe - - - 06273476000182 - KABUM COMERCIO ELETRONICO S.A - KABUM! - - ROD BR-262 - 222 - GALPAO 2 ARMZ 3 4 E 5 - VILA BETHANIA - 3205101 - VIANA - ES - 29136010 - 1058 - BRASIL - 1921144444 - - 083078665 - 3 - - - 15004584737 - LUCAS MORAES - - RUA CARLOS FIRMO - 75 - 2 ANDAR - CENTRO - 3201100 - BOM JESUS DO NORTE - ES - 29460000 - 1058 - BRASIL - 28999927700 - - 9 - - - - 119072 - - FONE DE OUVIDO BLUETOOTH EDIFIER TWS X3, RECARREGAVEL, RESISTENTE A AGUA, PRETO - TOT TRIB. 52.32 - 85183000 - 0105700 - 5102 - UN - 1.0000 - 159.9000000000 - 159.90 - - UN - 1.0000 - 159.9000000000 - 28.23 - 1 - - - - - 0 - 00 - 3 - 188.13 - 17.0000 - 31.98 - - - - - 01 - 156.15 - 1.6500 - 2.58 - - - - - 01 - 156.15 - 7.6000 - 11.87 - - - - GARANTIA 12 MESES - N.SERIE OU IMEI 310100325872 - - - - 188.13 - 31.98 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 159.90 - 28.23 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 2.58 - 11.87 - 0.00 - 188.13 - - - - 0 - - 34028316710151 - CORREIOS - - - 1 - 1 - 0.091 - 0.091 - - - - - 03 - 188.13 - - - - PEDIDO 23529429 - OBSERVACAO DO CLIENTE - NENHUMA VALOR APROXIMADO DOS TRIBUTOS 44.47 REAIS - 27.81 POR CENTO - FONTE IBPT - - ECT_SEDEX - - - 23529429 - - - - 23529429 - - - - - - - - - - - - - 2yKVkW9JSljwXzcaV0/KMHV2HZM= - - - 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 - - - - - - - 1 - SVRS202103291658 - 32210605570714000825550010109071851235294293 - 2021-06-04T06:57:08-03:00 - 332210035696612 - 2yKVkW9JSljwXzcaV0/KMHV2HZM= - 100 - Autorizado o uso da NF-e - - - diff --git a/notasFiscais/32211207872718000117550010000217781877120005-nfe.xml b/notasFiscais/32211207872718000117550010000217781877120005-nfe.xml deleted file mode 100644 index a9d9335..0000000 --- a/notasFiscais/32211207872718000117550010000217781877120005-nfe.xml +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - 32 - 87712000 - VENDA MERCAD.ADQ.TERCEIROS - 55 - 1 - 21778 - 2021-12-01T19:03:21-03:00 - 2021-12-01T19:03:21-03:00 - 1 - 1 - 3201308 - 1 - 1 - 5 - 1 - 1 - 0 - 1 - 0 - MeLinux 6.3 - - - 07872718000117 - COMERCIAL S.R.DE ALIMENTOS LTDA-ME - SR ALIMENTOS - - R.ODONIA DA COSTA MACHADO TOLEDO - 56 - QUADRA 1 LOTE 5 - TIRADENTES - 3201308 - CARIACICA - ES - 29143529 - 1058 - BRASIL - 2733363026 - - 082384975 - 3 - - - 17197072000173 - JEFERSON SIMAO DE OLIVEIRA - ME - - RUA SAO JOAO - 49 - ITACIBA - 3201308 - CARIACICA - ES - 29150230 - 1058 - BRASIL - 27996502121 - - 1 - 082917825 - - - - 001378 - SEM GTIN - FILE MERLUZA ARGENTINA INTERF.CX 18 c/ 18 KG - 03047400 - 5102 - CX - 1 - 503.82 - 503.82 - SEM GTIN - CX - 18 - 27.99 - 1 - - - - - 2 - 20 - 3 - 58.82 - 207.46 - 17.00 - 35.27 - - - - 999 - - 53 - - - - - 01 - 503.82 - 0.65 - 3.27 - - - - - 01 - 503.82 - 3.00 - 15.11 - - - - - - - 000195 - 7896481907388 - CUPIM MAGRO FRISA CX -+ 18KG - 02013000 - 1708400 - 5405 - KG - 21.71 - 29.12989406 - 632.41 - 7896481907388 - KG - 21.71 - 29.12989406 - 1 - - - - - 0 - 60 - - - - 999 - - 53 - - - - - 01 - 632.41 - 0.65 - 4.11 - - - - - 01 - 632.41 - 3.00 - 18.97 - - - - - - - 207.46 - 35.27 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 1136.23 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 7.38 - 34.08 - 0.00 - 1136.23 - - - - 9 - - 07872718000117 - COMERCIAL S.R.DE ALIMENTOS LTDA-ME - 082384975 - RUA ODONIA DA COSTA MACHADO TOLEDO, 41 QD 1 LOTE 5 TIRADENTE - CARIACICA - ES - - - 23 - DIVERSAS - DIVERSAS - 40.106 - - - - - 021778 - 1136.23 - 0.00 - 1136.23 - - - 001 - 2022-12-15 - 568.11 - - - 002 - 2022-12-22 - 568.12 - - - - - 15 - 1136.23 - - - - Cod.Dest: 7452 Fantasia: REST.ESPA.GRILL Faturista: IGOR REIS # Forma Pag: BOLETO # Vendedor: TACIANI (27)99735-5228 Num.Ped: 102667 # Doc.emitido por ME/EPP optante do SIMPLES NACIONAL; nao gera credito fiscal de IPI e ISS # RUA DA FEIRA # sem email cadastrado para envio do XML # # Confira no ato da entrega, evite reclamacoes posteriores - - - 19495981000113 - OTMA SOLUCOES LTDA - contato@otmasolucoes.com.br - 2721417943 - - - - - - - - - - - - - yU29u4Sva8be/dmxDzD7eyMIOaY= - - - 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 - - - - - - - 1 - SVRS202111190951 - 32211207872718000117550010000217781877120005 - 2021-12-01T19:03:22-03:00 - 332210083442441 - yU29u4Sva8be/dmxDzD7eyMIOaY= - 100 - Autorizado o uso da NF-e - - - \ No newline at end of file diff --git a/notasFiscais/NFe-002-3103.xml b/notasFiscais/NFe-002-3103.xml deleted file mode 100644 index ec2ae56..0000000 --- a/notasFiscais/NFe-002-3103.xml +++ /dev/null @@ -1,311 +0,0 @@ - - - - - - 31 - 00464032 - Vendas a prazo - 55 - 2 - 3103 - 2019-04-10T17:24:03-02:00 - 2019-04-11T17:17:30-02:00 - 1 - 1 - 3170206 - 1 - 1 - 7 - 1 - 1 - 0 - 1 - 0 - 001 - - - 06273476000182 - MECA Office Mobil. Eireli-ME - MECA Office Mobil. Eireli-ME - - AV. MARCOS DE FREITAS COSTA - 1055 - DANIEL FOSECA - 3170206 - Uberlandia - MG - 38400328 - 1058 - BRASIL - 3432385585 - - 7022916720058 - 1 - - - 25587387000155 - HLTS ENGENHARIA E CONSTRUCOES LTDA - - RUA MACHADO DE ASSIS - 1324 - LIDICE - 3170206 - Uberlandia - MG - 38400081 - 1058 - BRASIL - 3432235966 - - 1 - 7021771340054 - - - - 00331 - SEM GTIN - CADEIRA GIRATORIA S/ BRACO ALMOFADADA PRETO - 94019090 - 5102 - UN - 2 - 165.00000 - 330.00 - SEM GTIN - UN - 2 - 165.00000 - 1 - - - 77.68 - - - 0 - 102 - - - - - 08 - - - - - 08 - - - - IMOBILIZADO IMOB - 2317 CADEIRA GIRATORIA S/ BRACO ALMOFADADA PRETO - IMOBILIZADO EQUIP. MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO. - - - - 01228 - SEM GTIN - CADEIRA GIRATORIA C/ BRACO ALMOFADADA PRETO - 94019090 - 5102 - UN - 1 - 215.00000 - 215.00 - SEM GTIN - UN - 1 - 215.00000 - 1 - - - 50.61 - - - 0 - 102 - - - - - 08 - - - - - 08 - - - - IMOBILIZADO EQUIP/MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO - - - - 01324 - SEM GTIN - BANQUETA ALTA 70CM PARA BALCAO ASSENTO 30 OU - 94019090 - 5102 - PC - 1 - 90.00000 - 90.00 - SEM GTIN - PC - 1 - 90.00000 - 1 - - - 21.19 - - - 0 - 102 - - - - - 08 - - - - - 08 - - - - 40CM NA COR PRETA - IMOBILIZADO EQUIP./MOVEIS P/ CANTEIRO MATERIAIS INSTALACAO DE CANTEIRO - - - - 01644 - SEM GTIN - ESTANTE ACO C/ 06 PRATELEIRAS 0,93X040X1,98M - 94069020 - 5102 - PC - 2 - 234.00000 - 468.00 - SEM GTIN - PC - 2 - 234.00000 - 1 - - - 45.87 - - - 0 - 102 - - - - - 08 - - - - - 08 - - - - (REFORCADA) AMAPA - IMOBILIZADO. - - - - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 1103.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 0.00 - 1103.00 - 195.35 - - - - 0 - - 6 - VOLUME - VARIAS - 0.000 - 0.000 - - - - - 000003103 - 1103.00 - 0.00 - 1103.00 - - - 001 - 2019-05-11 - 1103.00 - - - - - 14 - 1103.00 - - 0.00 - - - ORDEM DE FORNECIMENTO 36994 - 28DD - INFORMACOES COMPLEMENTARES a seguinte informacao. EMPRESA ENQUADRADA NO SIMPLES NACIONAL. NAO GERA CREDITO DE IPI/ISS. GERA CREDITO DE ICMS. Trib aprox R$: 54,84 Federal 140,51 Estadual Fonte: IBPT empresometro.com.br S3A6R4 - - - - - - - - - - - - - ngqVwH6QNCAHyRuI529RIAr7Nyk= - - - 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 - - - - - - - 1 - 14.2.26 - 31190406273476000182550020000031031004640327 - 2019-04-10T17:23:27-03:00 - 131193257591884 - ngqVwH6QNCAHyRuI529RIAr7Nyk= - 100 - Autorizado o uso da NF-e - - - \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..287aaf7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +click==8.1.2 +Flask==2.1.1 +Flask-Dropzone==1.6.0 +importlib-metadata==4.11.3 +itsdangerous==2.1.2 +Jinja2==3.1.1 +MarkupSafe==2.1.1 +Werkzeug==2.1.0 +zipp==3.7.0 \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index d3c4251..abbb1ee 100644 --- a/templates/base.html +++ b/templates/base.html @@ -6,22 +6,21 @@ - + {{ dropzone.load_css() }} {{ dropzone.style('border: 2px dashed #0087F7; margin: 3%; min-height: 100px;') }} {% block title %} {% endblock %}