Browse Source

merge

pull/1/head
leotada 11 years ago
parent
commit
71c5f6d946
  1. 7
      pynfe/__init__.py
  2. 5
      pynfe/processamento/__init__.py
  3. 119
      pynfe/processamento/comunicacao.py
  4. 2
      pynfe/utils/flags.py
  5. 467
      pynfe/utils/webservices.py
  6. 2
      setup.py
  7. 4
      test.py
  8. 4
      texte.xml

7
pynfe/__init__.py

@ -1,8 +1,7 @@
def get_version(): def get_version():
return '0.1'
return '0.2'
__version__ = get_version() __version__ = get_version()
__author__ = 'Marinho Brandao'
__author__ = 'Marinho Brandao, Junior Tada, Leonardo Tada'
__license__ = 'GNU Lesser General Public License (LGPL)' __license__ = 'GNU Lesser General Public License (LGPL)'
__url__ = 'http://github.com/marinho/PyNFe'
__url__ = 'https://github.com/leotada/PyNFe'

5
pynfe/processamento/__init__.py

@ -1,6 +1,5 @@
from .serializacao import SerializacaoXML from .serializacao import SerializacaoXML
from .validacao import Validacao from .validacao import Validacao
#from assinatura import AssinaturaA1
#from comunicacao import ComunicacaoSefaz
from .assinatura import AssinaturaA1
from .comunicacao import ComunicacaoSefaz
from .danfe import DANFE from .danfe import DANFE

119
pynfe/processamento/comunicacao.py

@ -1,28 +1,25 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import datetime import datetime
from httplib import HTTPSConnection, HTTPResponse
from pynfe.utils import etree, StringIO, so_numeros
from pynfe.utils.flags import NAMESPACE_NFE, NAMESPACE_SOAP, VERSAO_PADRAO
from pynfe.utils.flags import CODIGOS_ESTADOS, VERSAO_PADRAO
from assinatura import AssinaturaA1
import requests
from pynfe.utils import etree, so_numeros
from pynfe.utils.flags import NAMESPACE_NFE, NAMESPACE_SOAP, VERSAO_PADRAO, CODIGOS_ESTADOS
from pynfe.utils.webservices import NFCE, NFE
from .assinatura import AssinaturaA1
class Comunicacao(object): class Comunicacao(object):
u"""Classe abstrata responsavel por definir os metodos e logica das classes u"""Classe abstrata responsavel por definir os metodos e logica das classes
de comunicação com os webservices da NF-e.""" de comunicação com os webservices da NF-e."""
_ambiente = 1 # 1 = Produção, 2 = Homologação _ambiente = 1 # 1 = Produção, 2 = Homologação
servidor = None
porta = 80
uf = None
certificado = None certificado = None
certificado_senha = None certificado_senha = None
def __init__(self, servidor, porta, certificado, certificado_senha, homologacao=False):
self.servidor = servidor
self.porta = porta
def __init__(self, uf, certificado, certificado_senha, homologacao=False):
self.uf = uf
self.certificado = certificado self.certificado = certificado
self.certificado_senha = certificado_senha self.certificado_senha = certificado_senha
self._ambiente = homologacao and 2 or 1
self._ambiente = 2 if homologacao else 1
class ComunicacaoSefaz(Comunicacao): class ComunicacaoSefaz(Comunicacao):
u"""Classe de comunicação que segue o padrão definido para as SEFAZ dos Estados.""" u"""Classe de comunicação que segue o padrão definido para as SEFAZ dos Estados."""
@ -30,7 +27,7 @@ class ComunicacaoSefaz(Comunicacao):
_versao = VERSAO_PADRAO _versao = VERSAO_PADRAO
_assinatura = AssinaturaA1 _assinatura = AssinaturaA1
def transmitir(self, nota_fiscal):
def autorizacao(self, nota_fiscal):
pass pass
def cancelar(self, nota_fiscal): def cancelar(self, nota_fiscal):
@ -39,28 +36,36 @@ class ComunicacaoSefaz(Comunicacao):
def situacao_nfe(self, nota_fiscal): def situacao_nfe(self, nota_fiscal):
pass pass
def status_servico(self):
post = '/nfeweb/services/nfestatusservico.asmx'
# Monta XML do corpo da requisição # FIXME
raiz = etree.Element('teste')
dados = etree.tostring(raiz)
def status_servico(self, tipo):
""" Verifica status do servidor da receita. """
""" tipo é a string com tipo de serviço que deseja consultar
Ex: nfe ou nfce
"""
if self._ambiente == 1:
ambiente = 'https://'
else:
ambiente = 'https://homologacao.'
if tipo == 'nfe':
# nfe Ex: https://nfe.fazenda.pr.gov.br/nfe/NFeStatusServico3
url = ambiente + NFE[self.uf.upper()]['STATUS']
elif tipo == 'nfce':
# nfce Ex: https://homologacao.nfce.fazenda.pr.gov.br/nfce/NFeStatusServico3
url = ambiente + NFCE[self.uf.upper()]['STATUS']
else:
# TODO implementar outros tipos de notas como NFS-e
pass
# Monta XML do corpo da requisição
raiz = etree.Element('consStatServ', versao='3.10', xmlns=NAMESPACE_NFE)
etree.SubElement(raiz, 'tpAmb').text = str(self._ambiente)
etree.SubElement(raiz, 'cUF').text = CODIGOS_ESTADOS[self.uf.upper()]
etree.SubElement(raiz, 'xServ').text = 'STATUS'
dados = etree.tostring(raiz, encoding='UTF-8')
# Monta XML para envio da requisição # Monta XML para envio da requisição
xml = self._construir_xml_soap(
metodo='nfeRecepcao2', # FIXME
tag_metodo='nfeStatusServicoNF2', # FIXME
cabecalho=self._cabecalho_soap(),
dados=dados,
)
xml = self._construir_xml_soap(cabecalho=self._cabecalho_soap(), dados=dados, url=url)
# Chama método que efetua a requisição POST no servidor SOAP # Chama método que efetua a requisição POST no servidor SOAP
retorno = self._post(post, xml, self._post_header())
# Transforma o retorno em etree
#retorno = etree.parse(StringIO(retorno))
return bool(retorno)
return self._post(url, xml, self._post_header())
def consultar_cadastro(self, instancia): def consultar_cadastro(self, instancia):
#post = '/nfeweb/services/cadconsultacadastro.asmx' #post = '/nfeweb/services/cadconsultacadastro.asmx'
@ -125,50 +130,48 @@ class ComunicacaoSefaz(Comunicacao):
def _cabecalho_soap(self): def _cabecalho_soap(self):
u"""Monta o XML do cabeçalho da requisição SOAP""" u"""Monta o XML do cabeçalho da requisição SOAP"""
raiz = etree.Element('cabecMsg', xmlns=NAMESPACE_NFE, versao="1.02")
etree.SubElement(raiz, 'versaoDados').text = self._versao
raiz = etree.Element('nfeCabecMsg')
etree.SubElement(raiz, 'cUF').text = str(41)
etree.SubElement(raiz, 'versaoDados').text = VERSAO_PADRAO
return etree.tostring(raiz, encoding='utf-8', xml_declaration=True)
return etree.tostring(raiz, encoding='UTF-8')
def _construir_xml_soap(self, metodo, tag_metodo, cabecalho, dados):
def _construir_xml_soap(self, cabecalho, dados, url):
u"""Mota o XML para o envio via SOAP""" u"""Mota o XML para o envio via SOAP"""
raiz = etree.Element('{%s}Envelope'%NAMESPACE_SOAP, nsmap={'soap': NAMESPACE_SOAP})
raiz = etree.Element('{%s}Envelope'%NAMESPACE_SOAP, nsmap={'soap': NAMESPACE_SOAP}, xmlns=url)
etree.SubElement(raiz, '{%s}Header'%NAMESPACE_SOAP).text = cabecalho
body = etree.SubElement(raiz, '{%s}Body'%NAMESPACE_SOAP) body = etree.SubElement(raiz, '{%s}Body'%NAMESPACE_SOAP)
met = etree.SubElement(
body, tag_metodo, xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/%s"%metodo,
)
etree.SubElement(body, 'nfeDadosMsg').text = dados
etree.SubElement(met, 'nfeCabecMsg').text = cabecalho
etree.SubElement(met, 'nfeDadosMsg').text = dados
return etree.tostring(raiz, encoding='utf-8', xml_declaration=True)
return etree.tostring(raiz, encoding='UTF-8', xml_declaration=True)
def _post_header(self): def _post_header(self):
u"""Retorna um dicionário com os atributos para o cabeçalho da requisição HTTP""" u"""Retorna um dicionário com os atributos para o cabeçalho da requisição HTTP"""
return { return {
u'content-type': u'application/soap+xml; charset=utf-8', u'content-type': u'application/soap+xml; charset=utf-8',
#u'content-type': u'text/xml; charset=utf-8',
#u'Accept': u'text/xml; charset=utf-8',
u'Accept': u'application/soap+xml; charset=utf-8', u'Accept': u'application/soap+xml; charset=utf-8',
} }
def _post(self, post, xml, header): def _post(self, post, xml, header):
# Separa arquivos de certificado para chave e certificado (sozinho) # Separa arquivos de certificado para chave e certificado (sozinho)
caminho_chave, caminho_cert = self.certificado.separar_arquivo(senha=self.certificado_senha)
#caminho_chave, caminho_cert = self.certificado.separar_arquivo(senha=self.certificado_senha)
caminho_chave = '/home/junior/Documentos/Certificados/key.pem'
caminho_cert = '/home/junior/Documentos/Certificados/cert.pem'
# Abre a conexão HTTPS # Abre a conexão HTTPS
con = HTTPSConnection(self.servidor, self.porta, key_file=caminho_chave, cert_file=caminho_cert)
cert = (caminho_cert, caminho_chave)
s = str(xml, 'utf-8').replace('&lt;', '<').replace('&gt;', '>').replace('\'', '"').replace('\n', '')
#headers = {'content-type': 'text/xml'}
try: try:
#con.set_debuglevel(100)
con.request(u'POST', post, xml, header)
resp = con.getresponse()
# Tudo certo!
if resp.status == 200:
return resp.read()
r = requests.post(post, s, headers=self._post_header(), cert=cert, verify=False)
print (r.content)
if r == 200:
return r.text
except Exception as e:
pass
finally: finally:
con.close()
pass

2
pynfe/utils/flags.py

@ -196,5 +196,3 @@ CODIGOS_ESTADOS = {
'GO': '52', 'GO': '52',
'DF': '53', 'DF': '53',
} }

467
pynfe/utils/webservices.py

@ -0,0 +1,467 @@
# Nfc-e
NFCE = {
'RO': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'AC': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'AM': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'RR': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'PA': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'AP': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'TO': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'MA': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'PI': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'CE': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'RN': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'PB': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'PE': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'AL': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'SE': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'BA': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'MG': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'ES': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'RJ': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'SP': {
'STATUS': 'nfce.fazenda.sp.gov.br/ws/nfestatusservico2.asmx',
'AUTORIZACAO': 'nfce.fazenda.sp.gov.br/ws/nfeautorizacao.asmx',
'RECIBO': 'nfce.fazenda.sp.gov.br/ws/nferetautorizacao.asmx',
'CHAVE': 'nfce.fazenda.sp.gov.br/ws/nfeconsulta2.asmx',
'INUTILIZACAO': 'nfce.fazenda.sp.gov.br/ws/nfeinutilizacao2.asmx',
'EVENTOS': 'nfce.fazenda.sp.gov.br/ws/recepcaoevento.asmx'
},
'PR': {
'STATUS': 'nfce.fazenda.pr.gov.br/nfce/NFeStatusServico3',
'AUTORIZACAO': 'nfce.fazenda.pr.gov.br/nfce/NFeAutorizacao3',
'RECIBO': 'nfce.fazenda.pr.gov.br/nfce/NFeRetAutorizacao3',
'CHAVE': 'nfce.fazenda.pr.gov.br/nfce/NFeConsulta3',
'INUTILIZACAO': 'nfce.fazenda.pr.gov.br/nfce/NFeInutilizacao3',
'EVENTOS': 'nfce.fazenda.pr.gov.br/nfce/NFeRecepcaoEvento'
},
'SC': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'RS': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'MS': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'MT': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'GO': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
'DF': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': ''
},
}
# Nfe
NFE = {
'RO': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'AC': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'AM': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'RR': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'PA': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'AP': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'TO': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'MA': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'PI': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'CE': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'RN': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'PB': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'PE': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'AL': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'SE': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'BA': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'MG': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'ES': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'RJ': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'SP': {
'STATUS': 'nfe.fazenda.sp.gov.br/ws/nfestatusservico2.asmx',
'AUTORIZACAO': 'nfe.fazenda.sp.gov.br/ws/nfeautorizacao.asmx',
'RECIBO': 'nfe.fazenda.sp.gov.br/ws/nferetautorizacao.asmx',
'CHAVE': 'nfe.fazenda.sp.gov.br/ws/nfeconsulta2.asmx',
'INUTILIZACAO': 'nfe.fazenda.sp.gov.br/ws/nfeinutilizacao2.asmx',
'EVENTOS': 'nfe.fazenda.sp.gov.br/ws/nfestatusservico2.asmx',
'CADASTRO': 'nfe.fazenda.sp.gov.br/ws/cadconsultacadastro2.asmx'
},
'PR': {
'STATUS': 'nfe.fazenda.pr.gov.br/nfe/NFeStatusServico3', # CONSULTA STATUS DO SERVIÇO
'AUTORIZACAO': 'nfe.fazenda.pr.gov.br/nfe/NFeAutorizacao3', # AUTORIZACAO
'RECIBO': 'nfe.fazenda.pr.gov.br/nfe/NFeRetAutorizacao3', # CONSULTA RECIBO
'CHAVE': 'nfe.fazenda.pr.gov.br/nfe/NFeConsulta3', # CONSULTA CHAVE DE ACESSO
'INUTILIZACAO': 'nfe.fazenda.pr.gov.br/nfe/NFeInutilizacao3', # INUTILIZAÇAO
'EVENTOS': 'nfe.fazenda.pr.gov.br/nfe/NFeRecepcaoEvento', # REGISTRO DE EVENTOS
'CADASTRO': 'nfe.fazenda.pr.gov.br/nfe/CadConsultaCadastro2' # CONSULTA CADASTRO
},
'SC': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'RS': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'MS': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'MT': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'GO': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
'DF': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'CADASTRO': ''
},
}

2
setup.py

@ -5,7 +5,7 @@ from setuptools import setup, find_packages
setup( setup(
name='PyNFe', name='PyNFe',
version='0.1-custom',
version='0.2',
packages=find_packages(), packages=find_packages(),
package_data={ package_data={
'pynfe': ['data/**/*.txt'], 'pynfe': ['data/**/*.txt'],

4
test.py

@ -100,8 +100,6 @@ nota_fiscal.adicionar_produto_servico(codigo='000328', # id do produto (000328 e
cofins_aliquota_percentual=Decimal('3.00'), cofins_aliquota_percentual=Decimal('3.00'),
cofins_valor=Decimal('3.51')) cofins_valor=Decimal('3.51'))
#_fonte_dados.adicionar_objeto(nota_fiscal)
serializador = SerializacaoXML(_fonte_dados, homologacao=True) serializador = SerializacaoXML(_fonte_dados, homologacao=True)
xml = serializador.exportar(retorna_string=True) xml = serializador.exportar(retorna_string=True)
certificado = "JC.pfx" certificado = "JC.pfx"
@ -112,5 +110,3 @@ xml = a1.assinar_nfe(xml)
# escreve # escreve
with open('teste.xml', 'wb') as arquivo: with open('teste.xml', 'wb') as arquivo:
arquivo.write(xml) arquivo.write(xml)
#print serializador._serializar_nota_fiscal(nota_fiscal)

4
texte.xml

@ -8,8 +8,8 @@
<mod>55</mod> <mod>55</mod>
<serie>1</serie> <serie>1</serie>
<nNF>1</nNF> <nNF>1</nNF>
<dhEmi>2015-07-14T00:03:20-03:00</dhEmi>
<dhSaiEnt>2015-07-14T00:03:20-03:00</dhSaiEnt>
<dhEmi>2015-07-14T16:50:11-03:00</dhEmi>
<dhSaiEnt>2015-07-14T16:50:11-03:00</dhSaiEnt>
<tpNF>1</tpNF> <tpNF>1</tpNF>
<idDest>1</idDest> <idDest>1</idDest>
<cMunFG>4118402</cMunFG> <cMunFG>4118402</cMunFG>

Loading…
Cancel
Save