From 084edf02785e0d4745120b19b252518f5a7cc2c9 Mon Sep 17 00:00:00 2001 From: Leonardo Gregianin Date: Sun, 19 Jun 2022 22:12:10 -0400 Subject: [PATCH 1/6] =?UTF-8?q?Typo=20destinat=C3=A1rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/processamento/serializacao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index d0fede4e..968e6930 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -139,7 +139,7 @@ def _serializar_emitente(self, emitente, tag_raiz='emit', retorna_string=True): def _serializar_cliente(self, cliente, modelo, tag_raiz='dest', retorna_string=True): raiz = etree.Element(tag_raiz) - # Dados do cliente (distinatario) + # Dados do cliente (destinatário) etree.SubElement(raiz, cliente.tipo_documento).text = so_numeros(cliente.numero_documento) if not self._so_cpf: if cliente.razao_social: From 0ed653e49b222531dd8d50cab0777c0598954bb9 Mon Sep 17 00:00:00 2001 From: Leonardo Gregianin Date: Sun, 19 Jun 2022 22:13:16 -0400 Subject: [PATCH 2/6] Adiciona teste para NFCe sem cliente --- tests/test_nfce_serializacao_sem_cliente.py | 354 ++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 tests/test_nfce_serializacao_sem_cliente.py diff --git a/tests/test_nfce_serializacao_sem_cliente.py b/tests/test_nfce_serializacao_sem_cliente.py new file mode 100644 index 00000000..ec1ea4ff --- /dev/null +++ b/tests/test_nfce_serializacao_sem_cliente.py @@ -0,0 +1,354 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_notafiscal_produto(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=None, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=65, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('1.01'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='00', + icms_origem=0, + icms_csosn='', + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('0.00'), + pis_aliquota_percentual=Decimal('0.00'), + pis_valor=Decimal('0.00'), + cofins_valor_base_calculo=Decimal('0.00'), + cofins_aliquota_percentual=Decimal('0.00'), + cofins_valor=Decimal('0.00'), + valor_tributos_aprox='1.01', + informacoes_adicionais='Informações adicionais', + ) + + self.notafiscal.adicionar_responsavel_tecnico( + cnpj='99999999000199', + contato='Teste PyNFe', + email='pynfe@pynfe.io', + fone='11912341234' + ) + + def serializa_nfe(self): + serializador = SerializacaoXML( + fonte_dados=_fonte_dados, + homologacao=self.homologacao, + so_cpf=True + ) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def grupo_ide_test(self): + uf = self.xml_assinado.xpath('//ns:ide/ns:cUF', namespaces=self.ns)[0].text + natureza_operacao = self.xml_assinado.xpath('//ns:ide/ns:natOp', namespaces=self.ns)[0].text + modelo = self.xml_assinado.xpath('//ns:ide/ns:mod', namespaces=self.ns)[0].text + serie = self.xml_assinado.xpath('//ns:ide/ns:serie', namespaces=self.ns)[0].text + numero_nf = self.xml_assinado.xpath('//ns:ide/ns:nNF', namespaces=self.ns)[0].text + data_emissao = self.xml_assinado.xpath('//ns:ide/ns:dhEmi', namespaces=self.ns)[0].text + tipo_documento = self.xml_assinado.xpath('//ns:ide/ns:tpNF', namespaces=self.ns)[0].text + indicador_destino = self.xml_assinado.xpath('//ns:ide/ns:idDest', namespaces=self.ns)[0].text + municipio = self.xml_assinado.xpath('//ns:ide/ns:cMunFG', namespaces=self.ns)[0].text + tipo_impressao_danfe = self.xml_assinado.xpath('//ns:ide/ns:tpImp', namespaces=self.ns)[0].text + forma_emissao = self.xml_assinado.xpath('//ns:ide/ns:tpEmis', namespaces=self.ns)[0].text + tipo_ambiente = self.xml_assinado.xpath('//ns:ide/ns:tpAmb', namespaces=self.ns)[0].text + finalidade_emissao = self.xml_assinado.xpath('//ns:ide/ns:finNFe', namespaces=self.ns)[0].text + cliente_final = self.xml_assinado.xpath('//ns:ide/ns:indFinal', namespaces=self.ns)[0].text + indicador_presencial = self.xml_assinado.xpath('//ns:ide/ns:indPres', namespaces=self.ns)[0].text + processo_emissao = self.xml_assinado.xpath('//ns:ide/ns:procEmi', namespaces=self.ns)[0].text + + self.assertEqual(uf, '41') + self.assertEqual(natureza_operacao, 'VENDA') + self.assertEqual(modelo, '65') + self.assertEqual(serie, '1') + self.assertEqual(numero_nf, '111') + self.assertEqual(data_emissao, '2021-01-14T12:00:00+00:00') + self.assertEqual(tipo_documento, '1') + self.assertEqual(indicador_destino, '1') + self.assertEqual(municipio, '4118402') + self.assertEqual(tipo_impressao_danfe, '1') + self.assertEqual(forma_emissao, '1') + self.assertEqual(tipo_ambiente, '2') + self.assertEqual(finalidade_emissao, '1') + self.assertEqual(cliente_final, '1') + self.assertEqual(indicador_presencial, '1') + self.assertEqual(processo_emissao, '0') + + def dados_emitente_test(self): + razao_social = self.xml_assinado.xpath('//ns:emit/ns:xNome', namespaces=self.ns)[0].text + nome_fantasia = self.xml_assinado.xpath('//ns:emit/ns:xFant', namespaces=self.ns)[0].text + cnpj = self.xml_assinado.xpath('//ns:emit/ns:CNPJ', namespaces=self.ns)[0].text + codigo_de_regime_tributario = self.xml_assinado.xpath('//ns:emit/ns:CRT', namespaces=self.ns)[0].text + inscricao_estadual = self.xml_assinado.xpath('//ns:emit/ns:IE', namespaces=self.ns)[0].text + inscricao_municipal = self.xml_assinado.xpath('//ns:emit/ns:IM', namespaces=self.ns)[0].text + cnae_fiscal = self.xml_assinado.xpath('//ns:emit/ns:CNAE', namespaces=self.ns)[0].text + endereco_logradouro = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:xLgr', namespaces=self.ns)[0].text + endereco_numero = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:nro', namespaces=self.ns)[0].text + endereco_bairro = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:xBairro', namespaces=self.ns)[0].text + endereco_municipio = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:xMun', namespaces=self.ns)[0].text + endereco_uf = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:UF', namespaces=self.ns)[0].text + endereco_cep = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:CEP', namespaces=self.ns)[0].text + endereco_pais = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:xPais', namespaces=self.ns)[0].text + + self.assertEqual(razao_social, 'NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL') + self.assertEqual(nome_fantasia, 'Nome Fantasia da Empresa') + self.assertEqual(cnpj, '99999999000199') + self.assertEqual(codigo_de_regime_tributario, '3') + self.assertEqual(inscricao_estadual, '9999999999') + self.assertEqual(inscricao_municipal, '12345') + self.assertEqual(cnae_fiscal, '9999999') + self.assertEqual(endereco_logradouro, 'Rua da Paz') + self.assertEqual(endereco_numero, '666') + self.assertEqual(endereco_bairro, 'Sossego') + self.assertEqual(endereco_municipio, 'Paranavai') + self.assertEqual(endereco_uf, 'PR') + self.assertEqual(endereco_cep, '87704000') + self.assertEqual(endereco_pais, 'Brasil') + + def sem_grupo_destinatario_test(self): + expected = [] + tag_dest = self.xml_assinado.xpath('//ns:dest', namespaces=self.ns) + self.assertEqual(tag_dest, expected) + + def total_e_produto_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:orig', namespaces=self.ns)[0].text + CST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:CST', namespaces=self.ns)[0].text + modBC = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:modBC', namespaces=self.ns)[0].text + vBC = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:vBC', namespaces=self.ns)[0].text + pICMS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:pICMS', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:vICMS', namespaces=self.ns)[0].text + pFCP = None + vFCP = None + + self.assertEqual(orig, '0') + self.assertEqual(CST, '00') + self.assertEqual(modBC, '0') + self.assertEqual(vBC, '0') + self.assertEqual(pICMS, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(pFCP, None) + self.assertEqual(vFCP, None) + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '0.00') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.00') + self.assertEqual(vCOFINS, '0.00') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '117.00') + self.assertEqual(vTotTrib, '1.01') + + def test_notafiscal_produto_cst00(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.notafiscal = self.preenche_notafiscal_produto() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.grupo_ide_test() + self.dados_emitente_test() + self.sem_grupo_destinatario_test() + self.total_e_produto_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() From f14eed0b679ae517b598839978da9559bbabb747 Mon Sep 17 00:00:00 2001 From: Leonardo Gregianin Date: Sun, 19 Jun 2022 22:13:42 -0400 Subject: [PATCH 3/6] Adiciona teste para NFCe somente com CPF --- tests/test_nfce_serializacao_somente_cpf.py | 366 ++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 tests/test_nfce_serializacao_somente_cpf.py diff --git a/tests/test_nfce_serializacao_somente_cpf.py b/tests/test_nfce_serializacao_somente_cpf.py new file mode 100644 index 00000000..a3b9e3af --- /dev/null +++ b/tests/test_nfce_serializacao_somente_cpf.py @@ -0,0 +1,366 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + indicador_ie=9, + tipo_documento='CPF', # CPF ou CNPJ + numero_documento='12345678900' # numero do cpf ou cnpj + ) + return self.cliente + + def preenche_notafiscal_produto(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=65, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('1.01'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='00', + icms_origem=0, + icms_csosn='', + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('0.00'), + pis_aliquota_percentual=Decimal('0.00'), + pis_valor=Decimal('0.00'), + cofins_valor_base_calculo=Decimal('0.00'), + cofins_aliquota_percentual=Decimal('0.00'), + cofins_valor=Decimal('0.00'), + valor_tributos_aprox='1.01', + informacoes_adicionais='Informações adicionais', + ) + + self.notafiscal.adicionar_responsavel_tecnico( + cnpj='99999999000199', + contato='Teste PyNFe', + email='pynfe@pynfe.io', + fone='11912341234' + ) + + def serializa_nfe(self): + serializador = SerializacaoXML( + fonte_dados=_fonte_dados, + homologacao=self.homologacao, + so_cpf=True + ) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def grupo_ide_test(self): + uf = self.xml_assinado.xpath('//ns:ide/ns:cUF', namespaces=self.ns)[0].text + natureza_operacao = self.xml_assinado.xpath('//ns:ide/ns:natOp', namespaces=self.ns)[0].text + modelo = self.xml_assinado.xpath('//ns:ide/ns:mod', namespaces=self.ns)[0].text + serie = self.xml_assinado.xpath('//ns:ide/ns:serie', namespaces=self.ns)[0].text + numero_nf = self.xml_assinado.xpath('//ns:ide/ns:nNF', namespaces=self.ns)[0].text + data_emissao = self.xml_assinado.xpath('//ns:ide/ns:dhEmi', namespaces=self.ns)[0].text + tipo_documento = self.xml_assinado.xpath('//ns:ide/ns:tpNF', namespaces=self.ns)[0].text + indicador_destino = self.xml_assinado.xpath('//ns:ide/ns:idDest', namespaces=self.ns)[0].text + municipio = self.xml_assinado.xpath('//ns:ide/ns:cMunFG', namespaces=self.ns)[0].text + tipo_impressao_danfe = self.xml_assinado.xpath('//ns:ide/ns:tpImp', namespaces=self.ns)[0].text + forma_emissao = self.xml_assinado.xpath('//ns:ide/ns:tpEmis', namespaces=self.ns)[0].text + tipo_ambiente = self.xml_assinado.xpath('//ns:ide/ns:tpAmb', namespaces=self.ns)[0].text + finalidade_emissao = self.xml_assinado.xpath('//ns:ide/ns:finNFe', namespaces=self.ns)[0].text + cliente_final = self.xml_assinado.xpath('//ns:ide/ns:indFinal', namespaces=self.ns)[0].text + indicador_presencial = self.xml_assinado.xpath('//ns:ide/ns:indPres', namespaces=self.ns)[0].text + processo_emissao = self.xml_assinado.xpath('//ns:ide/ns:procEmi', namespaces=self.ns)[0].text + + self.assertEqual(uf, '41') + self.assertEqual(natureza_operacao, 'VENDA') + self.assertEqual(modelo, '65') + self.assertEqual(serie, '1') + self.assertEqual(numero_nf, '111') + self.assertEqual(data_emissao, '2021-01-14T12:00:00+00:00') + self.assertEqual(tipo_documento, '1') + self.assertEqual(indicador_destino, '1') + self.assertEqual(municipio, '4118402') + self.assertEqual(tipo_impressao_danfe, '1') + self.assertEqual(forma_emissao, '1') + self.assertEqual(tipo_ambiente, '2') + self.assertEqual(finalidade_emissao, '1') + self.assertEqual(cliente_final, '1') + self.assertEqual(indicador_presencial, '1') + self.assertEqual(processo_emissao, '0') + + def dados_emitente_test(self): + razao_social = self.xml_assinado.xpath('//ns:emit/ns:xNome', namespaces=self.ns)[0].text + nome_fantasia = self.xml_assinado.xpath('//ns:emit/ns:xFant', namespaces=self.ns)[0].text + cnpj = self.xml_assinado.xpath('//ns:emit/ns:CNPJ', namespaces=self.ns)[0].text + codigo_de_regime_tributario = self.xml_assinado.xpath('//ns:emit/ns:CRT', namespaces=self.ns)[0].text + inscricao_estadual = self.xml_assinado.xpath('//ns:emit/ns:IE', namespaces=self.ns)[0].text + inscricao_municipal = self.xml_assinado.xpath('//ns:emit/ns:IM', namespaces=self.ns)[0].text + cnae_fiscal = self.xml_assinado.xpath('//ns:emit/ns:CNAE', namespaces=self.ns)[0].text + endereco_logradouro = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:xLgr', namespaces=self.ns)[0].text + endereco_numero = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:nro', namespaces=self.ns)[0].text + endereco_bairro = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:xBairro', namespaces=self.ns)[0].text + endereco_municipio = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:xMun', namespaces=self.ns)[0].text + endereco_uf = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:UF', namespaces=self.ns)[0].text + endereco_cep = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:CEP', namespaces=self.ns)[0].text + endereco_pais = self.xml_assinado.xpath('//ns:emit/ns:enderEmit/ns:xPais', namespaces=self.ns)[0].text + + self.assertEqual(razao_social, 'NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL') + self.assertEqual(nome_fantasia, 'Nome Fantasia da Empresa') + self.assertEqual(cnpj, '99999999000199') + self.assertEqual(codigo_de_regime_tributario, '3') + self.assertEqual(inscricao_estadual, '9999999999') + self.assertEqual(inscricao_municipal, '12345') + self.assertEqual(cnae_fiscal, '9999999') + self.assertEqual(endereco_logradouro, 'Rua da Paz') + self.assertEqual(endereco_numero, '666') + self.assertEqual(endereco_bairro, 'Sossego') + self.assertEqual(endereco_municipio, 'Paranavai') + self.assertEqual(endereco_uf, 'PR') + self.assertEqual(endereco_cep, '87704000') + self.assertEqual(endereco_pais, 'Brasil') + + def dados_destinatario_test(self): + indicador_ie = self.xml_assinado.xpath('//ns:dest/ns:indIEDest', namespaces=self.ns)[0].text + numero_documento = self.xml_assinado.xpath('//ns:dest/ns:CPF', namespaces=self.ns)[0].text + self.assertEqual(indicador_ie, '9') + self.assertEqual(numero_documento, '12345678900') + self.assertNotEqual(numero_documento, '123') + + def total_e_produto_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:orig', namespaces=self.ns)[0].text + CST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:CST', namespaces=self.ns)[0].text + modBC = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:modBC', namespaces=self.ns)[0].text + vBC = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:vBC', namespaces=self.ns)[0].text + pICMS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:pICMS', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMS00/ns:vICMS', namespaces=self.ns)[0].text + pFCP = None + vFCP = None + + self.assertEqual(orig, '0') + self.assertEqual(CST, '00') + self.assertEqual(modBC, '0') + self.assertEqual(vBC, '0') + self.assertEqual(pICMS, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(pFCP, None) + self.assertEqual(vFCP, None) + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '0.00') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.00') + self.assertEqual(vCOFINS, '0.00') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '117.00') + self.assertEqual(vTotTrib, '1.01') + + def test_notafiscal_produto_cst00(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.grupo_ide_test() + self.dados_emitente_test() + self.dados_destinatario_test() + self.total_e_produto_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() From fa7989785b617dd9d52a911b8413c3f73504b45a Mon Sep 17 00:00:00 2001 From: Leonardo Gregianin Date: Sun, 19 Jun 2022 22:14:08 -0400 Subject: [PATCH 4/6] Corrige CRT do teste da NFCe --- tests/test_nfce_serializacao.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_nfce_serializacao.py b/tests/test_nfce_serializacao.py index 254e7503..0806f585 100644 --- a/tests/test_nfce_serializacao.py +++ b/tests/test_nfce_serializacao.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -133,7 +133,7 @@ def preenche_notafiscal_produto(self): ind_total=1, icms_modalidade='00', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='51', cofins_modalidade='51', pis_valor_base_calculo=Decimal('0.00'), @@ -222,7 +222,7 @@ def dados_emitente_test(self): self.assertEqual(razao_social, 'NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL') self.assertEqual(nome_fantasia, 'Nome Fantasia da Empresa') self.assertEqual(cnpj, '99999999000199') - self.assertEqual(codigo_de_regime_tributario, '1') + self.assertEqual(codigo_de_regime_tributario, '3') self.assertEqual(inscricao_estadual, '9999999999') self.assertEqual(inscricao_municipal, '12345') self.assertEqual(cnae_fiscal, '9999999') From 743cd51fc3c5de86f7a162c1e58dfd27c1d1f81f Mon Sep 17 00:00:00 2001 From: Leonardo Gregianin Date: Sun, 19 Jun 2022 22:16:18 -0400 Subject: [PATCH 5/6] Corrige CRT dos testes das NFes com produtos CST --- tests/test_nfe_serializacao_cst_00.py | 17 ++--------------- tests/test_nfe_serializacao_cst_10.py | 4 ++-- tests/test_nfe_serializacao_cst_20.py | 4 ++-- tests/test_nfe_serializacao_cst_30.py | 4 ++-- tests/test_nfe_serializacao_cst_40.py | 4 ++-- tests/test_nfe_serializacao_cst_41.py | 4 ++-- tests/test_nfe_serializacao_cst_50.py | 4 ++-- tests/test_nfe_serializacao_cst_51.py | 4 ++-- tests/test_nfe_serializacao_cst_60.py | 4 ++-- tests/test_nfe_serializacao_cst_70.py | 4 ++-- tests/test_nfe_serializacao_cst_90.py | 4 ++-- tests/test_nfe_serializacao_geral.py | 6 +++--- 12 files changed, 25 insertions(+), 38 deletions(-) diff --git a/tests/test_nfe_serializacao_cst_00.py b/tests/test_nfe_serializacao_cst_00.py index ebbbf2b6..3d1ded64 100644 --- a/tests/test_nfe_serializacao_cst_00.py +++ b/tests/test_nfe_serializacao_cst_00.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst00(self): ind_total=1, icms_modalidade='00', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='51', cofins_modalidade='51', pis_valor_base_calculo=Decimal('117.00'), @@ -153,19 +153,6 @@ def preenche_notafiscal_produto_cst00(self): ipi_valor_ipi_dev=Decimal('10.00'), pdevol=Decimal('1.00'), ) - self.notafiscal.adicionar_nota_fiscal_referenciada( - chave_acesso='12345678901234567890123456789012345678900001' - ) - self.notafiscal.adicionar_nota_fiscal_referenciada( - chave_acesso='12345678901234567890123456789012345678900002' - ) - - self.notafiscal.adicionar_responsavel_tecnico( - cnpj='99999999000199', - contato='Teste PyNFe', - email='pynfe@pynfe.io', - fone='11912341234' - ) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_10.py b/tests/test_nfe_serializacao_cst_10.py index 494fac16..0156078b 100644 --- a/tests/test_nfe_serializacao_cst_10.py +++ b/tests/test_nfe_serializacao_cst_10.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst10(self): ind_total=1, icms_modalidade='10', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='51', cofins_modalidade='51', pis_valor_base_calculo=Decimal('117.00'), diff --git a/tests/test_nfe_serializacao_cst_20.py b/tests/test_nfe_serializacao_cst_20.py index 0d97b099..d4c748f2 100644 --- a/tests/test_nfe_serializacao_cst_20.py +++ b/tests/test_nfe_serializacao_cst_20.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst20(self): ind_total=1, icms_modalidade='20', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='51', cofins_modalidade='51', pis_valor_base_calculo=Decimal('117.00'), diff --git a/tests/test_nfe_serializacao_cst_30.py b/tests/test_nfe_serializacao_cst_30.py index 0e3facbf..a4212b5d 100644 --- a/tests/test_nfe_serializacao_cst_30.py +++ b/tests/test_nfe_serializacao_cst_30.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst30(self): ind_total=1, icms_modalidade='30', icms_origem=0, - icms_csosn='400', + icms_csosn='', icms_st_modalidade_determinacao_bc='0', icms_st_percentual_adicional=0, icms_st_percentual_reducao_bc=0, diff --git a/tests/test_nfe_serializacao_cst_40.py b/tests/test_nfe_serializacao_cst_40.py index 618355e4..5f11bbec 100644 --- a/tests/test_nfe_serializacao_cst_40.py +++ b/tests/test_nfe_serializacao_cst_40.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst40(self): ind_total=1, icms_modalidade='40', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='07', cofins_modalidade='07', valor_tributos_aprox='21.06', diff --git a/tests/test_nfe_serializacao_cst_41.py b/tests/test_nfe_serializacao_cst_41.py index 12040c1f..7c052a23 100644 --- a/tests/test_nfe_serializacao_cst_41.py +++ b/tests/test_nfe_serializacao_cst_41.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst41(self): ind_total=1, icms_modalidade='41', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='07', cofins_modalidade='07', valor_tributos_aprox='21.06', diff --git a/tests/test_nfe_serializacao_cst_50.py b/tests/test_nfe_serializacao_cst_50.py index 41e60cca..5c5b50bd 100644 --- a/tests/test_nfe_serializacao_cst_50.py +++ b/tests/test_nfe_serializacao_cst_50.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst50(self): ind_total=1, icms_modalidade='50', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='07', cofins_modalidade='07', valor_tributos_aprox='21.06', diff --git a/tests/test_nfe_serializacao_cst_51.py b/tests/test_nfe_serializacao_cst_51.py index 2fd12cf6..ff69a8d7 100644 --- a/tests/test_nfe_serializacao_cst_51.py +++ b/tests/test_nfe_serializacao_cst_51.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst51(self): ind_total=1, icms_modalidade='51', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='07', cofins_modalidade='07', valor_tributos_aprox='21.06', diff --git a/tests/test_nfe_serializacao_cst_60.py b/tests/test_nfe_serializacao_cst_60.py index 0208331e..018a3902 100644 --- a/tests/test_nfe_serializacao_cst_60.py +++ b/tests/test_nfe_serializacao_cst_60.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst60(self): ind_total=1, icms_modalidade='60', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='07', cofins_modalidade='07', valor_tributos_aprox='21.06', diff --git a/tests/test_nfe_serializacao_cst_70.py b/tests/test_nfe_serializacao_cst_70.py index 83880dff..35cc72b1 100644 --- a/tests/test_nfe_serializacao_cst_70.py +++ b/tests/test_nfe_serializacao_cst_70.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst70(self): ind_total=1, icms_modalidade='70', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='07', cofins_modalidade='07', valor_tributos_aprox='21.06', diff --git a/tests/test_nfe_serializacao_cst_90.py b/tests/test_nfe_serializacao_cst_90.py index d77ca899..7f827383 100644 --- a/tests/test_nfe_serializacao_cst_90.py +++ b/tests/test_nfe_serializacao_cst_90.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst90(self): ind_total=1, icms_modalidade='90', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='07', cofins_modalidade='07', valor_tributos_aprox='21.06', diff --git a/tests/test_nfe_serializacao_geral.py b/tests/test_nfe_serializacao_geral.py index 9ca8da31..807a74bb 100644 --- a/tests/test_nfe_serializacao_geral.py +++ b/tests/test_nfe_serializacao_geral.py @@ -53,7 +53,7 @@ def preenche_emitente(self): razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', nome_fantasia='Nome Fantasia da Empresa', cnpj='99999999000199', # cnpj apenas números - codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + codigo_de_regime_tributario='3', # 1 para simples nacional ou 3 para normal inscricao_estadual='9999999999', # numero de IE da empresa inscricao_municipal='12345', cnae_fiscal='9999999', # cnae apenas números @@ -136,7 +136,7 @@ def preenche_notafiscal_produto_cst00(self): ind_total=1, icms_modalidade='00', icms_origem=0, - icms_csosn='400', + icms_csosn='', pis_modalidade='51', cofins_modalidade='51', pis_valor_base_calculo=Decimal('117.00'), @@ -238,7 +238,7 @@ def dados_emitente_test(self): self.assertEqual(razao_social, 'NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL') self.assertEqual(nome_fantasia, 'Nome Fantasia da Empresa') self.assertEqual(cnpj, '99999999000199') - self.assertEqual(codigo_de_regime_tributario, '1') + self.assertEqual(codigo_de_regime_tributario, '3') self.assertEqual(inscricao_estadual, '9999999999') self.assertEqual(inscricao_municipal, '12345') self.assertEqual(cnae_fiscal, '9999999') From 9f81c8b833ebc4dd996412441e28da09a95b1b72 Mon Sep 17 00:00:00 2001 From: Leonardo Gregianin Date: Sun, 19 Jun 2022 23:25:59 -0400 Subject: [PATCH 6/6] =?UTF-8?q?Cria=20testes=20para=20NFe=20com=20CSOSN=20?= =?UTF-8?q?e=20corrige=20serializa=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/processamento/serializacao.py | 17 +- tests/test_nfe_serializacao_csosn_101.py | 316 ++++++++++++++++++++ tests/test_nfe_serializacao_csosn_102.py | 312 ++++++++++++++++++++ tests/test_nfe_serializacao_csosn_103.py | 316 ++++++++++++++++++++ tests/test_nfe_serializacao_csosn_201.py | 330 +++++++++++++++++++++ tests/test_nfe_serializacao_csosn_202.py | 324 +++++++++++++++++++++ tests/test_nfe_serializacao_csosn_203.py | 324 +++++++++++++++++++++ tests/test_nfe_serializacao_csosn_300.py | 316 ++++++++++++++++++++ tests/test_nfe_serializacao_csosn_400.py | 316 ++++++++++++++++++++ tests/test_nfe_serializacao_csosn_500.py | 312 ++++++++++++++++++++ tests/test_nfe_serializacao_csosn_900.py | 352 +++++++++++++++++++++++ 11 files changed, 3228 insertions(+), 7 deletions(-) create mode 100644 tests/test_nfe_serializacao_csosn_101.py create mode 100644 tests/test_nfe_serializacao_csosn_102.py create mode 100644 tests/test_nfe_serializacao_csosn_103.py create mode 100644 tests/test_nfe_serializacao_csosn_201.py create mode 100644 tests/test_nfe_serializacao_csosn_202.py create mode 100644 tests/test_nfe_serializacao_csosn_203.py create mode 100644 tests/test_nfe_serializacao_csosn_300.py create mode 100644 tests/test_nfe_serializacao_csosn_400.py create mode 100644 tests/test_nfe_serializacao_csosn_500.py create mode 100644 tests/test_nfe_serializacao_csosn_900.py diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 968e6930..db5b517e 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -547,8 +547,8 @@ def _serializar_imposto_icms(self, produto_servico, tag_raiz='imposto', retorna_ icms_item = etree.SubElement(icms, 'ICMSSN'+produto_servico.icms_modalidade) etree.SubElement(icms_item, 'orig').text = str(produto_servico.icms_origem) etree.SubElement(icms_item, 'CSOSN').text = produto_servico.icms_csosn - etree.SubElement(icms_item, 'pCredSN').text = str(produto_servico.icms_aliquota) # Alíquota aplicável de cálculo do crédito (Simples Nacional). - etree.SubElement(icms_item, 'vCredICMSSN').text = str(produto_servico.icms_credito) # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + etree.SubElement(icms_item, 'pCredSN').text = '{:.2f}'.format(produto_servico.icms_aliquota) # Alíquota aplicável de cálculo do crédito (Simples Nacional). + etree.SubElement(icms_item, 'vCredICMSSN').text = '{:.2f}'.format(produto_servico.icms_credito) # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) # 102=Tributada pelo Simples Nacional sem permissão de crédito # 103=Isenção do ICMS no Simples Nacional para faixa de receita bruta @@ -563,7 +563,10 @@ def _serializar_imposto_icms(self, produto_servico, tag_raiz='imposto', retorna_ # 202=Tributada pelo Simples Nacional sem permissão de crédito e com cobrança do ICMS por substituição tributária # 203=Isenção do ICMS no Simples Nacional para faixa de receita bruta e com cobrança do ICMS por substituição tributária elif produto_servico.icms_modalidade in ('201', '202', '203'): - icms_item = etree.SubElement(icms, 'ICMSSN'+produto_servico.icms_modalidade) + if produto_servico.icms_modalidade == '201': + icms_item = etree.SubElement(icms, 'ICMSSN201') + elif produto_servico.icms_modalidade in ['202', '203']: + icms_item = etree.SubElement(icms, 'ICMSSN202') etree.SubElement(icms_item, 'orig').text = str(produto_servico.icms_origem) etree.SubElement(icms_item, 'CSOSN').text = produto_servico.icms_csosn @@ -580,8 +583,8 @@ def _serializar_imposto_icms(self, produto_servico, tag_raiz='imposto', retorna_ etree.SubElement(icms_item, 'vFCPST').text = '{:.2f}'.format(produto_servico.fcp_st_valor or 0) if produto_servico.icms_modalidade == '201': - etree.SubElement(icms_item, 'pCredSN').text = str(produto_servico.icms_aliquota) # Alíquota aplicável de cálculo do crédito (Simples Nacional). - etree.SubElement(icms_item, 'vCredICMSSN').text = str(produto_servico.icms_credito) # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + etree.SubElement(icms_item, 'pCredSN').text = '{:.2f}'.format(produto_servico.icms_aliquota) # Alíquota aplicável de cálculo do crédito (Simples Nacional). + etree.SubElement(icms_item, 'vCredICMSSN').text = '{:.2f}'.format(produto_servico.icms_credito) # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) # 500=ICMS cobrado anteriormente por substituição tributária (substituído) ou por antecipação elif produto_servico.icms_modalidade == '500': @@ -616,8 +619,8 @@ def _serializar_imposto_icms(self, produto_servico, tag_raiz='imposto', retorna_ etree.SubElement(icms_item, 'vFCPST').text = '{:.2f}'.format(produto_servico.fcp_st_valor or 0) if produto_servico.icms_aliquota > 0: - etree.SubElement(icms_item, 'pCredSN').text = str(produto_servico.icms_aliquota) # Alíquota aplicável de cálculo do crédito (Simples Nacional). - etree.SubElement(icms_item, 'vCredICMSSN').text = str(produto_servico.icms_credito) # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + etree.SubElement(icms_item, 'pCredSN').text = '{:.2f}'.format(produto_servico.icms_aliquota) # Alíquota aplicável de cálculo do crédito (Simples Nacional). + etree.SubElement(icms_item, 'vCredICMSSN').text = '{:.2f}'.format(produto_servico.icms_credito) # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) else: raise NotImplementedError diff --git a/tests/test_nfe_serializacao_csosn_101.py b/tests/test_nfe_serializacao_csosn_101.py new file mode 100644 index 00000000..9697728a --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_101.py @@ -0,0 +1,316 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn101(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='101', + icms_origem=0, + icms_csosn='101', + icms_aliquota=Decimal('3.00'), # Alíquota aplicável de cálculo do crédito (Simples Nacional). + icms_credito=Decimal('10.00'), # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900001' + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900002' + ) + + self.notafiscal.adicionar_responsavel_tecnico( + cnpj='99999999000199', + contato='Teste PyNFe', + email='pynfe@pynfe.io', + fone='11912341234' + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn101_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN101/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN101/ns:CSOSN', namespaces=self.ns)[0].text + pCredSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN101/ns:pCredSN', namespaces=self.ns)[0].text + vCredICMSSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN101/ns:vCredICMSSN', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '101') + self.assertEqual(pCredSN, '3.00') + self.assertEqual(vCredICMSSN, '10.00') + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '0.00') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '117.00') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn101(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn101() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn101_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_nfe_serializacao_csosn_102.py b/tests/test_nfe_serializacao_csosn_102.py new file mode 100644 index 00000000..bb399a2c --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_102.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn102(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='102', + icms_origem=0, + icms_csosn='102', + icms_aliquota=0, # Alíquota aplicável de cálculo do crédito (Simples Nacional). + icms_credito=0, # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900001' + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900002' + ) + + self.notafiscal.adicionar_responsavel_tecnico( + cnpj='99999999000199', + contato='Teste PyNFe', + email='pynfe@pynfe.io', + fone='11912341234' + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn102_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN102/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN102/ns:CSOSN', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '102') + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '0.00') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '117.00') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn102(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn102() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn102_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_nfe_serializacao_csosn_103.py b/tests/test_nfe_serializacao_csosn_103.py new file mode 100644 index 00000000..76cd5ae9 --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_103.py @@ -0,0 +1,316 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn102(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='103', + icms_origem=0, + icms_csosn='103', + icms_aliquota=0, # Alíquota aplicável de cálculo do crédito (Simples Nacional). + icms_credito=0, # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900001' + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900002' + ) + + self.notafiscal.adicionar_responsavel_tecnico( + cnpj='99999999000199', + contato='Teste PyNFe', + email='pynfe@pynfe.io', + fone='11912341234' + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn102_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN102/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN102/ns:CSOSN', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '103') + + # CSOSN 103 gera a tag 102 + CSOSN103 = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN103/ns:CSOSN', namespaces=self.ns) + self.assertEqual(CSOSN103, []) + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '0.00') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '117.00') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn102(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn102() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn102_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_nfe_serializacao_csosn_201.py b/tests/test_nfe_serializacao_csosn_201.py new file mode 100644 index 00000000..7fc114b3 --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_201.py @@ -0,0 +1,330 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn201(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='201', + icms_origem=0, + icms_csosn='201', + icms_aliquota=Decimal('3.00'), # Alíquota aplicável de cálculo do crédito (Simples Nacional). + icms_credito=Decimal('10.00'), # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + icms_st_modalidade_determinacao_bc='0', + icms_st_percentual_adicional=0, + icms_st_percentual_reducao_bc=0, + icms_st_valor_base_calculo=0, + icms_st_aliquota=0, + icms_st_valor=0, + fcp_st_base_calculo=Decimal('117.00'), + fcp_st_percentual=Decimal('0.01'), + fcp_st_valor=Decimal('1.17'), + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn201_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:CSOSN', namespaces=self.ns)[0].text + modBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:modBCST', namespaces=self.ns)[0].text + pMVAST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:pMVAST', namespaces=self.ns)[0].text + pRedBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:pRedBCST', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:vBCST', namespaces=self.ns)[0].text + pICMSST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:pICMSST', namespaces=self.ns)[0].text + vICMSST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:vICMSST', namespaces=self.ns)[0].text + vBCFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:vBCFCPST', namespaces=self.ns)[0].text + pFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:pFCPST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:vFCPST', namespaces=self.ns)[0].text + pCredSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:pCredSN', namespaces=self.ns)[0].text + vCredICMSSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN201/ns:vCredICMSSN', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '201') + self.assertEqual(modBCST, '0') + self.assertEqual(pMVAST, '0.00') + self.assertEqual(pRedBCST, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(pICMSST, '0.00') + self.assertEqual(vICMSST, '0.00') + self.assertEqual(vBCFCPST, '117.00') + self.assertEqual(pFCPST, '0.01') + self.assertEqual(vFCPST, '1.17') + self.assertEqual(pCredSN, '3.00') + self.assertEqual(vCredICMSSN, '10.00') + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '1.17') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '118.17') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn201(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn201() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn201_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_nfe_serializacao_csosn_202.py b/tests/test_nfe_serializacao_csosn_202.py new file mode 100644 index 00000000..83602e22 --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_202.py @@ -0,0 +1,324 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn202(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='202', + icms_origem=0, + icms_csosn='202', + icms_st_modalidade_determinacao_bc='0', + icms_st_percentual_adicional=0, + icms_st_percentual_reducao_bc=0, + icms_st_valor_base_calculo=0, + icms_st_aliquota=0, + icms_st_valor=0, + fcp_st_base_calculo=Decimal('117.00'), + fcp_st_percentual=Decimal('0.01'), + fcp_st_valor=Decimal('1.17'), + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn202_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:CSOSN', namespaces=self.ns)[0].text + modBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:modBCST', namespaces=self.ns)[0].text + pMVAST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:pMVAST', namespaces=self.ns)[0].text + pRedBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:pRedBCST', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:vBCST', namespaces=self.ns)[0].text + pICMSST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:pICMSST', namespaces=self.ns)[0].text + vICMSST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:vICMSST', namespaces=self.ns)[0].text + vBCFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:vBCFCPST', namespaces=self.ns)[0].text + pFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:pFCPST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:vFCPST', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '202') + self.assertEqual(modBCST, '0') + self.assertEqual(pMVAST, '0.00') + self.assertEqual(pRedBCST, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(pICMSST, '0.00') + self.assertEqual(vICMSST, '0.00') + self.assertEqual(vBCFCPST, '117.00') + self.assertEqual(pFCPST, '0.01') + self.assertEqual(vFCPST, '1.17') + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '1.17') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '118.17') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn202(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn202() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn202_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_nfe_serializacao_csosn_203.py b/tests/test_nfe_serializacao_csosn_203.py new file mode 100644 index 00000000..f746551f --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_203.py @@ -0,0 +1,324 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn203(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='203', + icms_origem=0, + icms_csosn='203', + icms_st_modalidade_determinacao_bc='0', + icms_st_percentual_adicional=0, + icms_st_percentual_reducao_bc=0, + icms_st_valor_base_calculo=0, + icms_st_aliquota=0, + icms_st_valor=0, + fcp_st_base_calculo=Decimal('117.00'), + fcp_st_percentual=Decimal('0.01'), + fcp_st_valor=Decimal('1.17'), + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn203_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:CSOSN', namespaces=self.ns)[0].text + modBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:modBCST', namespaces=self.ns)[0].text + pMVAST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:pMVAST', namespaces=self.ns)[0].text + pRedBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:pRedBCST', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:vBCST', namespaces=self.ns)[0].text + pICMSST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:pICMSST', namespaces=self.ns)[0].text + vICMSST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:vICMSST', namespaces=self.ns)[0].text + vBCFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:vBCFCPST', namespaces=self.ns)[0].text + pFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:pFCPST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN202/ns:vFCPST', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '203') + self.assertEqual(modBCST, '0') + self.assertEqual(pMVAST, '0.00') + self.assertEqual(pRedBCST, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(pICMSST, '0.00') + self.assertEqual(vICMSST, '0.00') + self.assertEqual(vBCFCPST, '117.00') + self.assertEqual(pFCPST, '0.01') + self.assertEqual(vFCPST, '1.17') + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '1.17') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '118.17') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn203(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn203() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn203_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_nfe_serializacao_csosn_300.py b/tests/test_nfe_serializacao_csosn_300.py new file mode 100644 index 00000000..3370b250 --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_300.py @@ -0,0 +1,316 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn300(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='300', + icms_origem=0, + icms_csosn='300', + icms_aliquota=0, # Alíquota aplicável de cálculo do crédito (Simples Nacional). + icms_credito=0, # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900001' + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900002' + ) + + self.notafiscal.adicionar_responsavel_tecnico( + cnpj='99999999000199', + contato='Teste PyNFe', + email='pynfe@pynfe.io', + fone='11912341234' + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn300_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN102/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN102/ns:CSOSN', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '300') + + # CSOSN 300 gera a tag 102 + CSOSN300 = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN300/ns:CSOSN', namespaces=self.ns) + self.assertEqual(CSOSN300, []) + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '0.00') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '117.00') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn300(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn300() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn300_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_nfe_serializacao_csosn_400.py b/tests/test_nfe_serializacao_csosn_400.py new file mode 100644 index 00000000..4ed5e1a7 --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_400.py @@ -0,0 +1,316 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn400(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='400', + icms_origem=0, + icms_csosn='400', + icms_aliquota=0, # Alíquota aplicável de cálculo do crédito (Simples Nacional). + icms_credito=0, # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900001' + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900002' + ) + + self.notafiscal.adicionar_responsavel_tecnico( + cnpj='99999999000199', + contato='Teste PyNFe', + email='pynfe@pynfe.io', + fone='11912341234' + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn400_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN102/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN102/ns:CSOSN', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '400') + + # CSOSN 400 gera a tag 102 + CSOSN400 = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN400/ns:CSOSN', namespaces=self.ns) + self.assertEqual(CSOSN400, []) + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '0.00') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '117.00') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn400(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn400() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn400_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_nfe_serializacao_csosn_500.py b/tests/test_nfe_serializacao_csosn_500.py new file mode 100644 index 00000000..1691327b --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_500.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn500(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='500', + icms_origem=0, + icms_csosn='500', + icms_aliquota=0, # Alíquota aplicável de cálculo do crédito (Simples Nacional). + icms_credito=0, # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900001' + ) + self.notafiscal.adicionar_nota_fiscal_referenciada( + chave_acesso='12345678901234567890123456789012345678900002' + ) + + self.notafiscal.adicionar_responsavel_tecnico( + cnpj='99999999000199', + contato='Teste PyNFe', + email='pynfe@pynfe.io', + fone='11912341234' + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn500_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN500/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN500/ns:CSOSN', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '500') + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '0.00') + self.assertEqual(vICMS, '0.00') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '0.00') + self.assertEqual(vST, '0.00') + self.assertEqual(vFCPST, '0.00') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '117.00') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn400(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn500() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn500_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_nfe_serializacao_csosn_900.py b/tests/test_nfe_serializacao_csosn_900.py new file mode 100644 index 00000000..c39b2a45 --- /dev/null +++ b/tests/test_nfe_serializacao_csosn_900.py @@ -0,0 +1,352 @@ +#!/usr/bin/env python +# *-* encoding: utf8 *-* + +import unittest + +from pynfe.entidades.cliente import Cliente +from pynfe.entidades.emitente import Emitente +from pynfe.entidades.notafiscal import NotaFiscal +from pynfe.entidades.fonte_dados import _fonte_dados +from pynfe.processamento.serializacao import SerializacaoXML +from pynfe.processamento.assinatura import AssinaturaA1 +from pynfe.processamento.validacao import Validacao +from pynfe.utils.flags import ( + CODIGO_BRASIL, + NAMESPACE_NFE, + NAMESPACE_SIG, + XSD_FOLDER_NFE, + XSD_NFE, + XSD_NFE_PROCESSADA, +) +from decimal import Decimal +import datetime + + +class SerializacaoNFeTestCase(unittest.TestCase): + """ + Imprimir o XML completo: + print(etree.tostring(self.xml_assinado)) + + """ + + def setUp(self): + self.certificado = "./tests/certificado.pfx" + self.senha = bytes('123456', 'utf-8') + self.uf = 'pr' + self.homologacao = True + + self.ns = {'ns': NAMESPACE_NFE} + self.ns_sig = {'ns': NAMESPACE_SIG} + + self.validacao = Validacao() + self.xsd_procNFe = self.validacao.get_xsd( + xsd_file=XSD_NFE_PROCESSADA, + xsd_folder=XSD_FOLDER_NFE + ) + self.xsd_nfe = self.validacao.get_xsd( + xsd_file=XSD_NFE, + xsd_folder=XSD_FOLDER_NFE + ) + + def preenche_emitente(self): + self.emitente = Emitente( + razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL', + nome_fantasia='Nome Fantasia da Empresa', + cnpj='99999999000199', # cnpj apenas números + codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal + inscricao_estadual='9999999999', # numero de IE da empresa + inscricao_municipal='12345', + cnae_fiscal='9999999', # cnae apenas números + endereco_logradouro='Rua da Paz', + endereco_numero='666', + endereco_bairro='Sossego', + endereco_municipio='Paranavaí', + endereco_uf='PR', + endereco_cep='87704000', + endereco_pais=CODIGO_BRASIL + ) + return self.emitente + + def preenche_destinatario(self): + self.cliente = Cliente( + razao_social='JOSE DA SILVA', + tipo_documento='CPF', # CPF ou CNPJ + email='email@email.com', + numero_documento='12345678900', # numero do cpf ou cnpj + indicador_ie=9, # 9=Não contribuinte + endereco_logradouro='Rua dos Bobos', + endereco_numero='Zero', + endereco_complemento='Ao lado de lugar nenhum', + endereco_bairro='Aquele Mesmo', + endereco_municipio='Brasilia', + endereco_uf='DF', + endereco_cep='12345123', + endereco_pais=CODIGO_BRASIL, + endereco_telefone='11912341234', + ) + return self.cliente + + def preenche_notafiscal_produto_csosn900(self): + + utc = datetime.timezone.utc + data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc) + data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc) + + self.notafiscal = NotaFiscal( + emitente=self.emitente, + cliente=self.cliente, + uf='PR', + natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc + forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. + tipo_pagamento=1, + modelo=55, # 55=NF-e; 65=NFC-e + serie='1', + numero_nf='111', # Número do Documento Fiscal. + data_emissao=data_emissao, + data_saida_entrada=data_saida_entrada, + tipo_documento=1, # 0=entrada; 1=saida + municipio='4118402', # Código IBGE do Município + tipo_impressao_danfe=1, # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e; + forma_emissao='1', # 1=Emissão normal (não em contingência); + cliente_final=1, # 0=Normal;1=Consumidor final; + indicador_destino=1, + indicador_presencial=1, + finalidade_emissao='1', # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria. + processo_emissao='0', # 0=Emissão de NF-e com aplicativo do contribuinte; + transporte_modalidade_frete=1, + informacoes_adicionais_interesse_fisco='Mensagem complementar', + totais_tributos_aproximado=Decimal('21.06'), + ) + + self.notafiscal.adicionar_produto_servico( + codigo='000328', # id do produto + descricao='Produto teste', + ncm='99999999', + # cest='0100100', # NT2015/003 + ean='1234567890121', + cfop='5102', + unidade_comercial='UN', + quantidade_comercial=Decimal('12'), # 12 unidades + valor_unitario_comercial=Decimal('9.75'), # preço unitário + valor_total_bruto=Decimal('117.00'), # preço total + unidade_tributavel='UN', + quantidade_tributavel=Decimal('12'), + valor_unitario_tributavel=Decimal('9.75'), + ean_tributavel='SEM GTIN', + ind_total=1, + icms_modalidade='900', + icms_origem=0, + icms_csosn='900', + icms_modalidade_determinacao_bc=0, + icms_valor_base_calculo=Decimal('18.67'), + icms_percentual_reducao_bc=Decimal('10.00'), + icms_valor=Decimal('3.36'), + icms_aliquota=Decimal('3.00'), # Alíquota aplicável de cálculo do crédito (Simples Nacional). + icms_credito=Decimal('10.00'), # Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional) + icms_st_modalidade_determinacao_bc='0', + icms_st_percentual_adicional=0, + icms_st_percentual_reducao_bc=0, + icms_st_valor_base_calculo=Decimal('117.00'), + icms_st_aliquota=Decimal('0.10'), + icms_st_valor=Decimal('1.17'), + fcp_st_base_calculo=Decimal('117.00'), + fcp_st_percentual=Decimal('0.01'), + fcp_st_valor=Decimal('1.17'), + pis_modalidade='51', + cofins_modalidade='51', + pis_valor_base_calculo=Decimal('117.00'), + pis_aliquota_percentual=Decimal('0.65'), + pis_valor=Decimal('0.76'), + cofins_valor_base_calculo=Decimal('117.00'), + cofins_aliquota_percentual=Decimal('3.00'), + cofins_valor=Decimal('3.51'), + valor_tributos_aprox='21.06', + numero_pedido='12345', + numero_item='1', + nfci='12345678-AAAA-FFFF-1234-000000000000', + informacoes_adicionais='Informações adicionais', + ipi_valor_ipi_dev=Decimal('0.00'), + pdevol=Decimal('0.00'), + ) + + def serializa_nfe(self): + serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) + return serializador.exportar() + + def assina_xml(self): + a1 = AssinaturaA1(self.certificado, self.senha) + return a1.assinar(self.xml) + + def validacao_com_xsd_do_xml_gerado_sem_processar(self): + self.validacao.validar_etree( + xml_doc=self.xml_assinado, + xsd_file=self.xsd_nfe, + use_assert=True + ) + + def total_e_produto_csosn900_test(self): + # Produto + cProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cProd', namespaces=self.ns)[0].text + cEAN = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEAN', namespaces=self.ns)[0].text + xProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xProd', namespaces=self.ns)[0].text + NCM = self.xml_assinado.xpath('//ns:det/ns:prod/ns:NCM', namespaces=self.ns)[0].text + # CEST = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CEST', namespaces=self.ns)[0].text + # indEscala = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indEscala', namespaces=self.ns)[0].text + CEST = None + indEscala = None + CFOP = self.xml_assinado.xpath('//ns:det/ns:prod/ns:CFOP', namespaces=self.ns)[0].text + uCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uCom', namespaces=self.ns)[0].text + qCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qCom', namespaces=self.ns)[0].text + vUnCom = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnCom', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vProd', namespaces=self.ns)[0].text + cEANTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:cEANTrib', namespaces=self.ns)[0].text + uTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:uTrib', namespaces=self.ns)[0].text + qTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:qTrib', namespaces=self.ns)[0].text + vUnTrib = self.xml_assinado.xpath('//ns:det/ns:prod/ns:vUnTrib', namespaces=self.ns)[0].text + indTot = self.xml_assinado.xpath('//ns:det/ns:prod/ns:indTot', namespaces=self.ns)[0].text + xPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:xPed', namespaces=self.ns)[0].text + nItemPed = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nItemPed', namespaces=self.ns)[0].text + nFCI = self.xml_assinado.xpath('//ns:det/ns:prod/ns:nFCI', namespaces=self.ns)[0].text + + self.assertEqual(cProd, '000328') + self.assertEqual(cEAN, '1234567890121') + self.assertEqual(xProd, 'Produto teste') + self.assertEqual(NCM, '99999999') + self.assertEqual(CEST, None) + self.assertEqual(indEscala, None) + self.assertEqual(CFOP, '5102') + self.assertEqual(uCom, 'UN') + self.assertEqual(qCom, '12') + self.assertEqual(vUnCom, '9.7500000000') + self.assertEqual(vProd, '117.00') + self.assertEqual(cEANTrib, 'SEM GTIN') + self.assertEqual(uTrib, 'UN') + self.assertEqual(qTrib, '12') + self.assertEqual(vUnTrib, '9.7500000000') + self.assertEqual(indTot, '1') + self.assertEqual(xPed, '12345') + self.assertEqual(nItemPed, '1') + self.assertEqual(nFCI, '12345678-AAAA-FFFF-1234-000000000000') + + # Impostos + # ICMS + orig = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:orig', namespaces=self.ns)[0].text + CSOSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:CSOSN', namespaces=self.ns)[0].text + + modBC = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:modBC', namespaces=self.ns)[0].text + vBC = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:vBC', namespaces=self.ns)[0].text + pRedBC = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:pRedBC', namespaces=self.ns)[0].text + pICMS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:pICMS', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:vICMS', namespaces=self.ns)[0].text + + modBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:modBCST', namespaces=self.ns)[0].text + pMVAST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:pMVAST', namespaces=self.ns)[0].text + pRedBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:pRedBCST', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:vBCST', namespaces=self.ns)[0].text + pICMSST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:pICMSST', namespaces=self.ns)[0].text + vICMSST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:vICMSST', namespaces=self.ns)[0].text + + vBCFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:vBCFCPST', namespaces=self.ns)[0].text + pFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:pFCPST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:vFCPST', namespaces=self.ns)[0].text + + pCredSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:pCredSN', namespaces=self.ns)[0].text + vCredICMSSN = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:ICMS/ns:ICMSSN900/ns:vCredICMSSN', namespaces=self.ns)[0].text + + self.assertEqual(orig, '0') + self.assertEqual(CSOSN, '900') + + self.assertEqual(modBC, '0') + self.assertEqual(vBC, '18.67') + self.assertEqual(pRedBC, '10.00') + self.assertEqual(pICMS, '3.00') + self.assertEqual(vICMS, '3.36') + + self.assertEqual(modBCST, '0') + self.assertEqual(pMVAST, '0.00') + self.assertEqual(pRedBCST, '0.00') + self.assertEqual(vBCST, '117.00') + self.assertEqual(pICMSST, '0.10') + self.assertEqual(vICMSST, '1.17') + + self.assertEqual(vBCFCPST, '117.00') + self.assertEqual(pFCPST, '0.01') + self.assertEqual(vFCPST, '1.17') + + self.assertEqual(pCredSN, '3.00') + self.assertEqual(vCredICMSSN, '10.00') + + # PIS + CST_PIS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:PIS/ns:PISOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_PIS, '51') + + # COFINS + CST_COFINS = self.xml_assinado.xpath('//ns:det/ns:imposto/ns:COFINS/ns:COFINSOutr/ns:CST', namespaces=self.ns)[0].text + self.assertEqual(CST_COFINS, '51') + + # Informações Adicionais do produto + infAdProd = self.xml_assinado.xpath('//ns:det/ns:infAdProd', namespaces=self.ns)[0].text + self.assertEqual(infAdProd, 'Informacoes adicionais') + + # Totalizadores + vBC = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBC', namespaces=self.ns)[0].text + vICMS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMS', namespaces=self.ns)[0].text + vICMSDeson = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vICMSDeson', namespaces=self.ns)[0].text + vFCP = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCP', namespaces=self.ns)[0].text + vBCST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vBCST', namespaces=self.ns)[0].text + vST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vST', namespaces=self.ns)[0].text + vFCPST = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPST', namespaces=self.ns)[0].text + vFCPSTRet = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFCPSTRet', namespaces=self.ns)[0].text + vProd = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vProd', namespaces=self.ns)[0].text + vFrete = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vFrete', namespaces=self.ns)[0].text + vSeg = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vSeg', namespaces=self.ns)[0].text + vDesc = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vDesc', namespaces=self.ns)[0].text + vII = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vII', namespaces=self.ns)[0].text + vIPI = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPI', namespaces=self.ns)[0].text + vIPIDevol = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vIPIDevol', namespaces=self.ns)[0].text + vPIS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vPIS', namespaces=self.ns)[0].text + vCOFINS = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vCOFINS', namespaces=self.ns)[0].text + vOutro = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vOutro', namespaces=self.ns)[0].text + vNF = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vNF', namespaces=self.ns)[0].text + vTotTrib = self.xml_assinado.xpath('//ns:total/ns:ICMSTot/ns:vTotTrib', namespaces=self.ns)[0].text + + self.assertEqual(vBC, '18.67') + self.assertEqual(vICMS, '3.36') + self.assertEqual(vICMSDeson, '0.00') + self.assertEqual(vFCP, '0.00') + self.assertEqual(vBCST, '117.00') + self.assertEqual(vST, '1.17') + self.assertEqual(vFCPST, '1.17') + self.assertEqual(vFCPSTRet, '0.00') + self.assertEqual(vProd, '117.00') + self.assertEqual(vFrete, '0.00') + self.assertEqual(vSeg, '0.00') + self.assertEqual(vDesc, '0.00') + self.assertEqual(vII, '0.00') + self.assertEqual(vIPI, '0.00') + self.assertEqual(vIPIDevol, '0.00') + self.assertEqual(vPIS, '0.76') + self.assertEqual(vCOFINS, '3.51') + self.assertEqual(vOutro, '0.00') + self.assertEqual(vNF, '119.34') + self.assertEqual(vTotTrib, '21.06') + + def test_notafiscal_produto_csosn900(self): + # Preenche as classes do pynfe + self.emitente = self.preenche_emitente() + self.cliente = self.preenche_destinatario() + self.notafiscal = self.preenche_notafiscal_produto_csosn900() + + # Serializa e assina o XML + self.xml = self.serializa_nfe() + self.xml_assinado = self.assina_xml() + + # Teste do conteúdo das tags do XML + self.total_e_produto_csosn900_test() + + # Testa a validação do XML com os schemas XSD + self.validacao_com_xsd_do_xml_gerado_sem_processar() + + +if __name__ == '__main__': + unittest.main()