Browse Source

Implantação de cancelarNfse

pull/7/head
Junior Tada 10 years ago
parent
commit
259583461d
  1. 40
      pynfe/processamento/assinatura.py
  2. 16
      pynfe/processamento/comunicacao.py
  3. 27
      pynfe/processamento/serializacao.py

40
pynfe/processamento/assinatura.py

@ -142,3 +142,43 @@ class AssinaturaA1(Assinatura):
return xml return xml
except Exception as e: except Exception as e:
raise e raise e
def assinarCancelar(self, xml, retorna_string=False):
try:
xml = etree.fromstring(xml)
# No raiz do XML de saida
tag = 'InfPedidoCancelamento' # tag que será assinada
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')
# Tenta achar a tag infNFe
# TODO a proxima linha nao eh encontrada pq precisa colocar o namespace, GerarNfseEnvio.
ref = etree.SubElement(siginfo, 'Reference', URI='#' +
xml.xpath('/CancelarNfseEnvio/ns1:Pedido/ns1:InfPedidoCancelamento', namespaces={'ns1': 'http://www.betha.com.br/e-nota-contribuinte-ws'})[0].attrib['Id'])
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')
rps = xml.xpath('/CancelarNfseEnvio/ns1:Pedido', namespaces={'ns1': 'http://www.betha.com.br/e-nota-contribuinte-ws'})[0]
rps.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('ns1:', '').replace(':ns1', '')))
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)
else:
return xml
except Exception as e:
raise e

16
pynfe/processamento/comunicacao.py

@ -385,8 +385,16 @@ class ComunicacaoNfse(Comunicacao):
# comunica via wsdl # comunica via wsdl
return self._post2(url, xml, 'consultaRps') return self._post2(url, xml, 'consultaRps')
def cancelar(self, autorizador):
pass
def cancelar(self, autorizador, nota):
if autorizador.upper() == 'BETHA':
self._namespace = NAMESPACE_BETHA
self._versao = '2.02'
# url do serviço
url = self._get_url(autorizador)
# xml
xml = etree.tostring(nota, encoding='unicode', pretty_print=False)
# comunica via wsdl
return self._post2(url, xml, 'cancelar')
def _cabecalho(self, retorna_string=True): def _cabecalho(self, retorna_string=True):
u"""Monta o XML do cabeçalho da requisição wsdl""" u"""Monta o XML do cabeçalho da requisição wsdl"""
@ -394,7 +402,7 @@ class ComunicacaoNfse(Comunicacao):
xml_declaration='<?xml version="1.0" encoding="UTF-8"?>' xml_declaration='<?xml version="1.0" encoding="UTF-8"?>'
# cabecalho # cabecalho
raiz = etree.Element('cabecalho', xmlns='http://www.betha.com.br/e-nota-contribuinte-ws', versao='2.02')
raiz = etree.Element('cabecalho', xmlns=self._namespace, versao=self._versao)
etree.SubElement(raiz, 'versaoDados').text = '2.02' etree.SubElement(raiz, 'versaoDados').text = '2.02'
if retorna_string: if retorna_string:
@ -471,7 +479,7 @@ class ComunicacaoNfse(Comunicacao):
elif metodo == 'consultaRps': elif metodo == 'consultaRps':
return cliente.service.ConsultarNfsePorRps(cabecalho, xml) return cliente.service.ConsultarNfsePorRps(cabecalho, xml)
elif metodo == 'cancelar': elif metodo == 'cancelar':
pass
return cliente.service.CancelarNfse(cabecalho, xml)
# TODO outros metodos # TODO outros metodos
else: else:
pass pass

27
pynfe/processamento/serializacao.py

@ -696,9 +696,32 @@ class SerializacaoNfse(Serializacao):
return consulta.toxml(element_name='ConsultarNfseRpsEnvio') return consulta.toxml(element_name='ConsultarNfseRpsEnvio')
def cancelar(self, dados):
pass
def cancelar(self, nfse):
"""Retorna string de um XML gerado a partir do
XML Schema (XSD). Binding gerado pelo modulo PyXB."""
# id nfse
id_nfse = nfse_schema.tcIdentificacaoNfse()
id_nfse.Numero = nfse.identificador
id_nfse.CpfCnpj = nfse.emitente.cnpj
id_nfse.InscricaoMunicipal = nfse.emitente.inscricao_municipal
id_nfse.CodigoMunicipio = nfse.emitente.endereco_cod_municipio
# Info Pedido de cancelamento
info_pedido = nfse_schema.tcInfPedidoCancelamento()
info_pedido.Id = '1'
info_pedido.IdentificacaoNfse = id_nfse
#pedido.CodigoCancelamento =
# Pedido
pedido = nfse_schema.tcPedidoCancelamento()
pedido.InfPedidoCancelamento = info_pedido
# Cancelamento
cancelar = nfse_schema.CancelarNfseEnvio()
cancelar.Pedido = pedido
return cancelar.toxml(element_name='CancelarNfseEnvio')
def _serializar_lote_sincrono(self, nfse): def _serializar_lote_sincrono(self, nfse):
"""Retorna string de um XML gerado a partir do """Retorna string de um XML gerado a partir do

Loading…
Cancel
Save