From bd7fa52b9616d9400aa8e78ce071535376d33d4b Mon Sep 17 00:00:00 2001 From: Junior Tada Date: Mon, 25 Jan 2016 17:11:28 -0200 Subject: [PATCH] =?UTF-8?q?Corre=C3=A7=C3=A3o=20na=20serializa=C3=A7=C3=A3?= =?UTF-8?q?o=20e=20assinatura=20de=20consultar=20lote=20Ginfes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/processamento/assinatura.py | 37 +++++++++++++++++++++++++++++++++ pynfe/processamento/autorizador_nfse.py | 4 ++-- pynfe/processamento/comunicacao.py | 20 +++++++++++++++++- pynfe/processamento/serializacao.py | 2 +- 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/pynfe/processamento/assinatura.py b/pynfe/processamento/assinatura.py index 1c74bab..e19177a 100644 --- a/pynfe/processamento/assinatura.py +++ b/pynfe/processamento/assinatura.py @@ -263,3 +263,40 @@ class AssinaturaA1(Assinatura): return xml except Exception as e: raise e + + def assinarConsultaLote(self, xml, retorna_string=True): + try: + tag = 'ns1:ConsultarLoteRpsEnvio' + xml = etree.fromstring(xml) + # No raiz do XML de saida + raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') + siginfo = etree.SubElement(raiz, 'SignedInfo') + etree.SubElement(siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') + etree.SubElement(siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') + # Consulta nao tem id + ref = etree.SubElement(siginfo, 'Reference', URI='') + + trans = etree.SubElement(ref, 'Transforms') + etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature') + etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') + etree.SubElement(ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') + etree.SubElement(ref, 'DigestValue') + etree.SubElement(raiz, 'SignatureValue') + keyinfo = etree.SubElement(raiz, 'KeyInfo') + etree.SubElement(keyinfo, 'X509Data') + + xml.append(raiz) + + # Escreve no arquivo depois de remover caracteres especiais e parse string + with open('nfse.xml', 'w') as arquivo: + arquivo.write(remover_acentos(etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n',''))) + + subprocess.call(['xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'nfse.xml']) + xml = etree.parse('funfa.xml').getroot() + + if retorna_string: + return etree.tostring(xml, encoding="unicode", pretty_print=False).replace('\n','') + else: + return xml + except Exception as e: + raise e diff --git a/pynfe/processamento/autorizador_nfse.py b/pynfe/processamento/autorizador_nfse.py index a4c27d4..3465e72 100644 --- a/pynfe/processamento/autorizador_nfse.py +++ b/pynfe/processamento/autorizador_nfse.py @@ -305,7 +305,7 @@ class SerializacaoGinfes(InterfaceAutorizador): consulta.Prestador = id_prestador consulta.Protocolo = str(numero) - return consulta.toxml(element_name='ns1:ConsultarLoteRps') + return consulta.toxml(element_name='ns1:ConsultarLoteRpsEnvio') def consultar_situacao_lote(self, emitente, numero): # Prestador @@ -498,4 +498,4 @@ class SerializacaoGinfes(InterfaceAutorizador): cabecalho = cabecalho_v03.cabecalho() cabecalho.versao = '3' cabecalho.versaoDados = '3' - return cabecalho.toxml(element_name='cabecalho') + return cabecalho.toxml(element_name='ns2:cabecalho') diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index baaa0fa..35817ba 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -486,7 +486,25 @@ class ComunicacaoNfse(Comunicacao): raise Exception('Autorizador não encontrado!') def _cabecalho(self, retorna_string=True): - u"""Monta o XML do cabeçalho da requisição wsdl""" + """ Monta o XML do cabeçalho da requisição wsdl + Namespaces padrão homologação (Ginfes) """ + + xml_declaration='' + # cabecalho = '3' + # cabecalho + raiz = etree.Element('{%s}cabecalho'%self._namespace, nsmap={'ns2':self._namespace, 'xsi':NAMESPACE_XSI}, versao=self._versao) + etree.SubElement(raiz, 'versaoDados').text = self._versao + + if retorna_string: + cabecalho = etree.tostring(raiz, encoding='unicode', pretty_print=False).replace('\n','') + cabecalho = xml_declaration + cabecalho + return cabecalho + else: + return raiz + + def _cabecalho2(self, retorna_string=True): + """ Monta o XML do cabeçalho da requisição wsdl + Namespaces que funcionaram em produção (Ginfes)""" xml_declaration='' diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 4c00210..a4c1313 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -577,7 +577,7 @@ class SerializacaoXML(Serializacao): etree.SubElement(e, 'cOrgao').text = CODIGOS_ESTADOS[evento.uf.upper()] etree.SubElement(e, 'tpAmb').text = str(self._ambiente) etree.SubElement(e, 'CNPJ').text = evento.cnpj # Empresas somente terão CNPJ - #etree.SubElement(evento, 'CPF').text = '' + #etree.SubElement(e, 'CPF').text = '' etree.SubElement(e, 'chNFe').text = evento.chave etree.SubElement(e, 'dhEvento').text = evento.data_emissao.strftime('%Y-%m-%dT%H:%M:%S') + tz etree.SubElement(e, 'tpEvento').text = evento.tp_evento