Browse Source

[ADD] Código inicial para geração de CTE na pytrustnfe

feature/cte
Danimar Ribeiro 7 years ago
parent
commit
83d297d101
  1. 107
      pytrustnfe/cte/__init__.py
  2. 459
      pytrustnfe/cte/dacte.py
  3. 0
      pytrustnfe/cte/templates/CTeDistribuicaoDFe.xml
  4. 0
      pytrustnfe/cte/templates/CTeRecepcaoOS.xml
  5. 0
      pytrustnfe/cte/templates/CteConsultaCadastro.xml
  6. 15
      pytrustnfe/cte/templates/CteConsultaProtocolo.xml
  7. 10
      pytrustnfe/cte/templates/CteInutilizacao.xml
  8. 305
      pytrustnfe/cte/templates/CteRecepcao.xml
  9. 0
      pytrustnfe/cte/templates/CteRecepcaoEvento.xml
  10. 0
      pytrustnfe/cte/templates/CteRetRecepcao.xml
  11. 3
      pytrustnfe/cte/webservices.py

107
pytrustnfe/cte/__init__.py

@ -0,0 +1,107 @@
import os
from lxml import etree
from pytrustnfe.nfe.assinatura import Assinatura
from pytrustnfe.xml import render_xml, sanitize_response
from pytrustnfe.cte.webservices import localizar_url
from pytrustnfe.certificado import extract_cert_and_key_from_pfx, save_cert_key
# Zeep
from requests import Session
from zeep import Client
from zeep.transports import Transport
def _render(certificado, method, sign, reference, **kwargs):
path = os.path.join(os.path.dirname(__file__), 'templates')
xmlElem_send = render_xml(path, '%s.xml' % method, True, **kwargs)
if sign:
signer = Assinatura(certificado.pfx, certificado.password)
xml_send = signer.assina_xml(xmlElem_send, reference)
else:
xml_send = etree.tostring(xmlElem_send, encoding=str)
return xml_send
def _send(certificado, method, **kwargs):
xml_send = kwargs["xml"]
base_url = localizar_url(method, kwargs['estado'], kwargs['ambiente'])
cert, key = extract_cert_and_key_from_pfx(
certificado.pfx, certificado.password)
cert, key = save_cert_key(cert, key)
session = Session()
session.cert = (cert, key)
session.verify = False
transport = Transport(session=session)
parser = etree.XMLParser(strip_cdata=False)
xml = etree.fromstring(xml_send, parser=parser)
client = Client(base_url, transport=transport)
port = next(iter(client.wsdl.port_types))
first_operation = [x for x in iter(
client.wsdl.port_types[port].operations) if "zip" not in x.lower()][0]
namespaceNFe = xml.find(".//{http://www.portalfiscal.inf.br/nfe}NFe")
if namespaceNFe is not None:
namespaceNFe.set('xmlns', 'http://www.portalfiscal.inf.br/nfe')
with client.settings(raw_response=True):
response = client.service[first_operation](xml)
response, obj = sanitize_response(response.text)
return {
'sent_xml': xml_send,
'received_xml': response,
'object': obj.Body.getchildren()[0]
}
def cte_recepcao(certificado, gerar_xml, **kwargs): # Assinar
if gerar_xml:
return _render(certificado, 'CteRecepcao', True, **kwargs)
return _send(certificado, 'CteRecepcao', **kwargs)
def cte_retorno_recepcao(certificado, gerar_xml, **kwargs): # Assinar
if gerar_xml:
return _render(certificado, 'CteRetRecepcao', True, **kwargs)
return _send(certificado, 'CteRetRecepcao', **kwargs)
def cte_inutilizacao(certificado, gerar_xml, **kwargs): # Assinar
if gerar_xml:
return _render(certificado, 'CteInutilizacao', True, **kwargs)
return _send(certificado, 'CteInutilizacao', **kwargs)
def cte_consulta_protocolo(certificado, gerar_xml, **kwargs): # Assinar
if gerar_xml:
return _render(certificado, 'CteConsultaProtocolo', True, **kwargs)
return _send(certificado, 'CteConsultaProtocolo', **kwargs)
def cte_consulta_cadastro(certificado, gerar_xml, **kwargs): # Assinar
if gerar_xml:
return _render(certificado, 'CteConsultaCadastro', True, **kwargs)
return _send(certificado, 'CteConsultaCadastro', **kwargs)
def cte_recepcao_evento(certificado, gerar_xml, **kwargs): # Assinar
if gerar_xml:
return _render(certificado, 'CteRecepcaoEvento', True, **kwargs)
return _send(certificado, 'CteRecepcaoEvento', **kwargs)
def cte_recepcao_os(certificado, gerar_xml, **kwargs): # Assinar
if gerar_xml:
return _render(certificado, 'CTeRecepcaoOS', True, **kwargs)
return _send(certificado, 'CTeRecepcaoOS', **kwargs)
def cte_distribuicao_dfe(certificado, gerar_xml, **kwargs): # Assinar
if gerar_xml:
return _render(certificado, 'CTeDistribuicaoDFe', True, **kwargs)
return _send(certificado, 'CTeDistribuicaoDFe', **kwargs)

459
pytrustnfe/cte/dacte.py

@ -0,0 +1,459 @@
# © 2018 Danimar Ribeiro <danimaribeiro@gmail.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import re
from textwrap import wrap
from io import BytesIO
from reportlab.lib import utils
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm, mm
from reportlab.graphics.barcode import qr
from reportlab.graphics import renderPDF
from reportlab.graphics.shapes import Drawing
from reportlab.platypus import Table, TableStyle, Paragraph, Image
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.styles import ParagraphStyle
def format_cnpj_cpf(value):
if len(value) < 12: # CPF
cValue = '%s.%s.%s-%s' % (value[:-8], value[-8:-5],
value[-5:-2], value[-2:])
else:
cValue = '%s.%s.%s/%s-%s' % (value[:-12], value[-12:-9],
value[-9:-6], value[-6:-2], value[-2:])
return cValue
def getdateUTC(cDateUTC):
cDt = cDateUTC[0:10].split('-')
cDt.reverse()
return '/'.join(cDt), cDateUTC[11:16]
def format_number(cNumber, precision=0, group_sep='.', decimal_sep=','):
if cNumber:
number = float(cNumber)
return ("{:,." + str(precision) + "f}").format(number).\
replace(",", "X").replace(".", ",").replace("X", ".")
return ""
def tagtext(oNode=None, cTag=None):
try:
xpath = ".//{http://www.portalfiscal.inf.br/nfe}%s" % (cTag)
cText = oNode.find(xpath).text
except:
cText = ''
return cText
def get_image(path, width=1 * cm):
img = utils.ImageReader(path)
iw, ih = img.getSize()
aspect = ih / float(iw)
return Image(path, width=width, height=(width * aspect))
def format_telefone(telefone):
telefone = re.sub('[^0-9]', '', telefone)
if len(telefone) == 10:
telefone = '(%s) %s-%s' % (telefone[0:2],
telefone[2:6],
telefone[6:])
elif len(telefone) == 11:
telefone = '(%s) %s-%s' % (telefone[0:2],
telefone[2:7],
telefone[7:])
return telefone
class danfce(object):
def __init__(self, list_xml, logo=None, timezone=None):
self.current_font_size = 7
self.current_font_name = 'NimbusSanL-Regu'
self.max_height = 840
self.min_height = 1
self.min_width = 5
self.max_width = 200
self.current_height = 840
self.oPDF_IO = BytesIO()
self.canvas = canvas.Canvas(self.oPDF_IO, pagesize=(7.2 * cm, 30 * cm))
self.canvas.setTitle('DANFCE')
self.canvas.setLineWidth(.5)
self.canvas.setFont(self.current_font_name, self.current_font_size)
self.list_xml = list_xml
self.logo = logo
self.nfce_generate()
def ide_emit(self, oXML=None):
elem_emit = oXML.find(".//{http://www.portalfiscal.inf.br/nfe}emit")
# Razão Social emitente
nomeEmpresa = tagtext(oNode=elem_emit, cTag='xFant')
self.drawTitle(nomeEmpresa, 10)
if self.logo:
img = get_image(self.logo, width=10 * mm)
img.drawOn(self.canvas, 5, 830)
cEnd = tagtext(oNode=elem_emit, cTag="xNome") + '<br />'
cEnd += "CNPJ: %s " % (format_cnpj_cpf(
tagtext(oNode=elem_emit, cTag='CNPJ')))
cEnd += "IE: %s" % (tagtext(oNode=elem_emit, cTag="IE")) + '<br />'
cEnd += tagtext(oNode=elem_emit, cTag='xLgr') + ', ' + tagtext(
oNode=elem_emit, cTag='nro') + ' - '
cEnd += tagtext(oNode=elem_emit, cTag='xBairro') + '<br />' + tagtext(
oNode=elem_emit, cTag='xMun') + ' - '
cEnd += tagtext(oNode=elem_emit, cTag='UF') + ' - ' + tagtext(
oNode=elem_emit, cTag='CEP') + '<br />'
cEnd += 'Fone: ' + format_telefone(tagtext(
oNode=elem_emit, cTag='fone'))
self._drawCenteredParagraph(cEnd)
self.drawLine()
def danfce_information(self):
self.drawTitle(
"DANFE NFC-e - Documento Auxiliar da Nota Fiscal de",
7, 'NimbusSanL-Bold')
self.drawTitle("Consumidor Eletrônica", 7, 'NimbusSanL-Bold')
self.drawString(
"NFC-e não permite aproveitamento de crédito de ICMS", True)
self.drawLine()
def produtos(self, oXML=None, el_det=None, oPaginator=None,
list_desc=None, list_cod_prod=None):
rows = [['Cód', 'Descrição', 'Qtde', 'Un', 'Unit.', 'Total']]
colWidths = (25, 90, 15, 15, 25, 25)
rowHeights = [7]
for id in range(oPaginator[0], oPaginator[1]):
item = el_det[id]
el_prod = item.find(".//{http://www.portalfiscal.inf.br/nfe}prod")
cod = tagtext(oNode=el_prod, cTag='cProd')
descricao = tagtext(oNode=el_prod, cTag='xProd')
descricao = (descricao[:20] + '..') if len(descricao) > 20 else descricao
Un = tagtext(oNode=el_prod, cTag='uCom')
Un = (Un[:2]) if len(Un) > 2 else Un
qtde = format_number(tagtext(oNode=el_prod, cTag='qCom'),
precision=2)
vl_unit = format_number(tagtext(oNode=el_prod, cTag='vUnCom'),
precision=2)
vl_total = format_number(
tagtext(oNode=el_prod, cTag='vProd'), precision=2)
new_row = [cod, descricao, qtde, Un, vl_unit, vl_total]
rows.append(new_row)
rowHeights.append(self.current_font_size + 2)
self._draw_product_table(rows, colWidths, rowHeights)
def _draw_product_table(self, rows, colWidths, rowHeights):
table = Table(rows, colWidths, tuple(rowHeights))
table.setStyle(TableStyle([
('FONTSIZE', (0, 0), (-1, -1), 7),
('FONT', (0, 1), (-1, -1), 'NimbusSanL-Regu'),
('FONT', (0, 0), (-1, 0), 'NimbusSanL-Bold'),
('ALIGN', (0, 0), (-1, 0), "LEFT"),
('ALIGN', (1, 0), (-1, 0), "LEFT"),
('ALIGN', (2, 0), (-1, 0), "CENTER"),
('ALIGN', (3, 0), (-1, 0), "CENTER"),
('ALIGN', (0, 1), (-1, -1), "LEFT"),
('ALIGN', (1, 1), (-1, -1), "LEFT"),
('ALIGN', (2, 1), (-1, -1), "CENTER"),
('ALIGN', (3, 1), (-1, -1), "CENTER"),
]))
w, h = table.wrapOn(self.canvas, 200, 450)
table.drawOn(self.canvas, 0, self.current_height - (h * 1.2))
self.current_height -= (h * 1.1)
def totais(self, oXML=None):
# Impostos
el_total = oXML.find(".//{http://www.portalfiscal.inf.br/nfe}total")
total_tributo = format_number(
tagtext(oNode=el_total, cTag='vTotTrib'), precision=2)
valor_total = format_number(
tagtext(oNode=el_total, cTag='vProd'), precision=2)
desconto = format_number(
tagtext(oNode=el_total, cTag='vDesc'), precision=2)
valor_a_pagar = format_number(
tagtext(oNode=el_total, cTag='vNF'), precision=2)
el_pag = oXML.find(".//{http://www.portalfiscal.inf.br/nfe}pag")
troco = format_number(tagtext(oNode=el_pag, cTag="vTroco"))
payment_method_list = {'01': 'Dinheiro',
'02': 'Cheque',
'03': 'Cartão de Crédito',
'04': 'Cartão de Débito',
"05": "Crédito Loja",
'10': 'Vale Alimentação',
'11': 'Vale Refeição',
'12': 'Vale Presente',
'13': 'Vale Combustível',
'14': 'Duplicata Mercantil',
'15': 'Boleto Bancario',
'90': 'Sem Pagamento',
'99': 'Outros'}
quant_produtos = len(oXML.findall(
".//{http://www.portalfiscal.inf.br/nfe}det"))
payment_methods = []
for pagId, item in enumerate(el_pag):
payment = []
tipo_pagamento = tagtext(oNode=item, cTag="tPag")
val = format_number(tagtext(oNode=item, cTag="vPag"), precision=2)
method = payment_method_list[tipo_pagamento]
payment.append(method)
payment.append(val)
payment_methods.append(payment)
values = {
'quantidade_itens': quant_produtos,
'total_tributo': total_tributo,
'valor_total': valor_total,
'desconto': desconto,
'valor_a_pagar': valor_a_pagar,
'formas_de_pagamento': payment_methods,
'troco': troco,
}
self.draw_totals_table(values)
self.drawLine()
def draw_totals_table(self, values):
rowHeights = [7, 7, 7, 7, 10]
data = [['QTD.TOTAL DE ITENS', values['quantidade_itens']],
['VALOR TOTAL R$', values['valor_total']],
['DESCONTO R$', values['desconto']],
['VALOR A PAGAR R$', values['valor_a_pagar']],
['FORMA DE PAGAMENTO', 'VALOR PAGO R$'],
]
for item in values['formas_de_pagamento']:
data.append([item[0], item[1]])
rowHeights.append(7)
data.append(['TROCO', format_number(values['troco'], precision=2)])
rowHeights.append(7)
table2 = Table(data, colWidths=(150, 50), rowHeights=tuple(rowHeights))
table2.setStyle(TableStyle([
('FONTSIZE', (0, 0), (-1, -1), 7),
('FONT', (0, 0), (1, -1), 'NimbusSanL-Regu'),
('FONT', (0, 4), (1, 4), 'NimbusSanL-Bold'),
('ALIGN', (1, 0), (1, -1), "RIGHT")
]))
w, h = table2.wrapOn(self.canvas, 200, 450)
table2.drawOn(self.canvas, 0, self.current_height - (h * 1.1))
self.current_height -= h
def inf_authentication(self, oXML=None):
el_infNFe = oXML.find(".//{http://www.portalfiscal.inf.br/nfe}infNFe")
# n nfce, serie e data de solicitacao
el_ide = oXML.find(".//{http://www.portalfiscal.inf.br/nfe}ide")
el_NFeSupl = oXML.find(
".//{http://www.portalfiscal.inf.br/nfe}infNFeSupl")
el_dest = el_infNFe.find(".//{http://www.portalfiscal.inf.br/nfe}dest")
# chave, n protocolo, data autorizacao
el_prot_nfe = oXML.find(
".//{http://www.portalfiscal.inf.br/nfe}protNFe")
el_infAdic = oXML.find(
".//{http://www.portalfiscal.inf.br/nfe}infAdic")
url_chave = tagtext(oNode=el_NFeSupl, cTag='urlChave')
access_key = tagtext(oNode=el_prot_nfe, cTag="chNFe")
frase_chave_acesso = 'Consulte pela Chave de Acesso em:<br />\
%s<br />%s' % (url_chave, access_key)
qrcode = tagtext(oNode=el_NFeSupl, cTag='qrCode')
cnpj = tagtext(oNode=el_dest, cTag='CNPJ')
cpf = tagtext(oNode=el_dest, cTag='CPF')
if cnpj:
cnpj_cpf = format_cnpj_cpf(cnpj)
cnpj_cpf = "CONSUMIDOR CNPJ: %s" % (cnpj)
elif cpf:
cnpj_cpf = format_cnpj_cpf(cpf)
cnpj_cpf = "CONSUMIDOR CPF: %s" % (cpf)
else:
cnpj_cpf = u"CONSUMIDOR NÃO IDENTIFICADO"
nNFC = tagtext(oNode=el_ide, cTag="nNF")
serie = tagtext(oNode=el_ide, cTag='serie')
dataSolicitacao = getdateUTC(tagtext(oNode=el_ide, cTag="dhEmi"))
dataSolicitacao = dataSolicitacao[0] + " " + dataSolicitacao[1]
numProtocolo = tagtext(oNode=el_prot_nfe, cTag="nProt")
dataAutorizacao = getdateUTC(tagtext(oNode=el_prot_nfe,
cTag='dhRecbto'))
dataAutorizacao = dataAutorizacao[0] + " " + dataAutorizacao[1]
text = u"%s <br />%s <br />NFC-e nº%s Série %s %s<br />\
Protocolo de autorização: %s<br />Data de autorização %s<br />\
" % (frase_chave_acesso, cnpj_cpf, nNFC, serie, dataSolicitacao,
numProtocolo, dataAutorizacao)
self._drawCenteredParagraph(text)
self.draw_qr_code(qrcode)
infAdFisco = tagtext(oNode=el_infAdic, cTag='infAdFisco')
self._drawCenteredParagraph(infAdFisco)
infCpl = tagtext(oNode=el_infAdic, cTag='infCpl')
self._drawCenteredParagraph(infCpl)
def _drawCenteredParagraph(self, text):
style = ParagraphStyle(
name='Normal',
fontName='NimbusSanL-Regu',
fontSize=7,
alignment=TA_CENTER,
leading=7,
)
paragraph = Paragraph(text, style=style)
w, h = paragraph.wrapOn(self.canvas, 180, 300)
paragraph.drawOn(self.canvas, 10, self.current_height - h)
self.current_height -= (h*1.1)
def drawString(self, string, centered=False):
if centered:
self.canvas.drawCentredString(
self.max_width / 2, self.current_height, string)
self.current_height -= self.current_font_size
else:
self.canvas.drawString(self.min_width, self.current_height, string)
self.current_height -= self.current_font_size
def drawTitle(self, string, size, font='NimbusSanL-Regu'):
self.canvas.setFont(font, size)
self.canvas.drawCentredString(
self.max_width / 2, self.current_height, string)
self.current_height -= self.current_font_size
self.canvas.setFont(self.current_font_name, self.current_font_size)
def drawLine(self):
self.canvas.line(self.min_width, self.current_height,
self.max_width, self.current_height)
self.current_height -= self.current_font_size
def draw_qr_code(self, string):
qr_code = qr.QrCodeWidget(string)
drawing = Drawing(23 * mm, 23 * mm)
drawing.add(qr_code)
renderPDF.draw(drawing, self.canvas, 20 * mm, self.current_height - 85)
self.current_height -= 85
def newpage(self):
self.current_height = self.max_height
self.Page += 1
self.canvas.showPage()
def nfce_generate(self):
for oXML in self.list_xml:
oXML_cobr = oXML.find(
".//{http://www.portalfiscal.inf.br/nfe}cobr")
self.NrPages = 1
self.Page = 1
# Calculando total linhas usadas para descrições dos itens
# Com bloco fatura, apenas 29 linhas para itens na primeira folha
nNr_Lin_Pg_1 = 34 if oXML_cobr is None else 30
# [ rec_ini , rec_fim , lines , limit_lines ]
oPaginator = [[0, 0, 0, nNr_Lin_Pg_1]]
el_det = oXML.findall(".//{http://www.portalfiscal.inf.br/nfe}det")
if el_det is not None:
list_desc = []
list_cod_prod = []
nPg = 0
for nId, item in enumerate(el_det):
el_prod = item.find(
".//{http://www.portalfiscal.inf.br/nfe}prod")
infAdProd = item.find(
".//{http://www.portalfiscal.inf.br/nfe}infAdProd")
list_ = wrap(tagtext(oNode=el_prod, cTag='xProd'), 56)
if infAdProd is not None:
list_.extend(wrap(infAdProd.text, 56))
list_desc.append(list_)
list_cProd = wrap(tagtext(oNode=el_prod, cTag='cProd'), 14)
list_cod_prod.append(list_cProd)
# Nr linhas necessárias p/ descrição item
nLin_Itens = len(list_)
if (oPaginator[nPg][2] + nLin_Itens) >= oPaginator[nPg][3]:
oPaginator.append([0, 0, 0, 77])
nPg += 1
oPaginator[nPg][0] = nId
oPaginator[nPg][1] = nId + 1
oPaginator[nPg][2] = nLin_Itens
else:
# adiciona-se 1 pelo funcionamento de xrange
oPaginator[nPg][1] = nId + 1
oPaginator[nPg][2] += nLin_Itens
self.NrPages = len(oPaginator) # Calculando nr. páginas
self.ide_emit(oXML=oXML)
# self.destinatario(oXML=oXML)
self.danfce_information()
self.produtos(oXML=oXML, el_det=el_det, oPaginator=oPaginator[0],
list_desc=list_desc, list_cod_prod=list_cod_prod)
self.drawLine()
self.totais(oXML=oXML)
self.inf_authentication(oXML=oXML)
# Gera o restante das páginas do XML
for oPag in oPaginator[1:]:
if oPag:
self.newpage()
self.ide_emit(oXML=oXML)
# self.destinatario(oXML=oXML)
self.produtos(oXML=oXML, el_det=el_det, oPaginator=oPag,
list_desc=list_desc,
list_cod_prod=list_cod_prod)
self.totais(oXML=oXML)
self.inf_authentication(oXML=oXML)
self.newpage()
self.canvas.save()
def writeto_pdf(self, fileObj):
pdf_out = self.oPDF_IO.getvalue()
self.oPDF_IO.close()
fileObj.write(pdf_out)

0
pytrustnfe/cte/templates/CTeDistribuicaoDFe.xml

0
pytrustnfe/cte/templates/CTeRecepcaoOS.xml

0
pytrustnfe/cte/templates/CteConsultaCadastro.xml

15
pytrustnfe/cte/templates/CteConsultaProtocolo.xml

@ -0,0 +1,15 @@
<Consulta>
<ModeloDocumento>CTe</ModeloDocumento>
<Versao>3.00</Versao>
<tpAmb>2</tpAmb>
<CnpjEmpresa>99999999999999</CnpjEmpresa>
<CnpjEmissor>99999999999999</CnpjEmissor>
<NumeroInicial>1</NumeroInicial>
<NumeroFinal>10</NumeroFinal>
<Serie>1</Serie>
<ChaveAcesso/>
<DataEmissaoInicial/>
<DataEmissaoFinal/>
<dhUF/>
<EmitidoRecebido/>
</Consulta>

10
pytrustnfe/cte/templates/CteInutilizacao.xml

@ -0,0 +1,10 @@
<Inutilizacao>
<ModeloDocumento>CTe</ModeloDocumento>
<Versao>3.00</Versao>
<CnpjEmissor>99999999999999</CnpjEmissor>
<tpAmb>2</tpAmb>
<NumeroInicial>1</NumeroInicial>
<NumeroFinal>1</NumeroFinal>
<Serie>50</Serie>
<Justificativa>Inutilizacao por motivos de pulo de numeracao</Justificativa>
</Inutilizacao>

305
pytrustnfe/cte/templates/CteRecepcao.xml

@ -0,0 +1,305 @@
<Envio>
<ModeloDocumento>CTe</ModeloDocumento>
<Versao>3.00</Versao>
<ide>
<cCT>17281638</cCT>
<cUF>43</cUF>
<natOp>Frete de mercadorias</natOp>
<CFOP>5352</CFOP>
<mod>57</mod>
<serie>50</serie>
<nCT>14</nCT>
<dhEmi>2017-06-06T15:00:01</dhEmi>
<fusoHorario>-03:00</fusoHorario>
<tpImp>1</tpImp>
<tpEmis>1</tpEmis>
<tpAmb>2</tpAmb>
<tpCTe>0</tpCTe>
<procEmi>0</procEmi>
<cMunEnv>4310405</cMunEnv>
<xMunEnv>Independencia</xMunEnv>
<UFEnv>RS</UFEnv>
<modal>01</modal>
<tpServ>0</tpServ>
<cMunIni>4310405</cMunIni>
<xMunIni>Independencia</xMunIni>
<UFIni>RS</UFIni>
<cMunFim>4302204</cMunFim>
<xMunFim>Boa Vista do Burica</xMunFim>
<UFFim>RS</UFFim>
<retira>0</retira>
<xDetRetira>Retirar o pacote no local de entrega indicado</xDetRetira>
<indIEToma>9</indIEToma>
<tomador>
<toma>4</toma>
<CNPJ_toma/>
<CPF_toma>99999999999</CPF_toma>
<IE_toma/>
<xNome_toma>Ricardo</xNome_toma>
<xFant_toma/>
<fone_toma>5597207426</fone_toma>
<enderTomador>
<xLgr_toma>Rua Senador Salgado Filho</xLgr_toma>
<nro_toma>463</nro_toma>
<xCpl_toma>Complemento nao informado</xCpl_toma>
<xBairro_toma>Centro</xBairro_toma>
<cMun_toma>4310405</cMun_toma>
<xMun_toma>Independencia</xMun_toma>
<CEP_toma>98915000</CEP_toma>
<UF_toma>RS</UF_toma>
<cPais_toma>1046</cPais_toma>
<xPais_toma>Brasil</xPais_toma>
</enderTomador>
<email_toma>email@gmail.com.br</email_toma>
</tomador>
</ide>
<compl>
<xCaracAd>Encomenda</xCaracAd>
<xCaracSer>Transporte</xCaracSer>
<xEmi>Jose Campos</xEmi>
<xObs>Pagar em qualquer lugar</xObs>
<fluxo>
<xOrig>Angra dos Reis</xOrig>
<xDest>Maria da Silva</xDest>
<xRota>129386</xRota>
<passagem>
<passItem>
<xPass>LHR</xPass>
</passItem>
<passItem>
<xPass>CGH</xPass>
</passItem>
<passItem>
<xPass>POA</xPass>
</passItem>
</passagem>
</fluxo>
<Entrega>
<tpPer>1</tpPer>
<dProg>2014-07-03</dProg>
<dIni>2014-07-03</dIni>
<dFim>2014-07-03</dFim>
<tpHor>1</tpHor>
<hProg>10:30:22</hProg>
<hIni>10:30:22</hIni>
<hFim>10:30:22</hFim>
</Entrega>
</compl>
<emit>
<CNPJ_emit>99999999999999</CNPJ_emit>
<IE>9999999999</IE>
<IEST>999999999</IEST>
<xNome>CT-E EMITIDO EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL</xNome>
<xFant>EMPRESA 1</xFant>
<enderEmit>
<xLgr>Endereco</xLgr>
<nro>1234</nro>
<xCpl>Complemento</xCpl>
<xBairro>Centro</xBairro>
<cMun>4310405</cMun>
<xMun>Independencia</xMun>
<CEP>98910000</CEP>
<UF>RS</UF>
<fone>35354560</fone>
</enderEmit>
</emit>
<rem>
<CNPJ_rem/>
<CPF_rem>99999999999</CPF_rem>
<IE_rem/>
<xNome_rem>CT-E EMITIDO EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL</xNome_rem>
<xFant_rem>Migrate Company</xFant_rem>
<fone_rem>55118822773343</fone_rem>
<email_rem>email@gmail.com.br</email_rem>
<enderRem>
<xLgr_rem>Rua Angra dos Reis</xLgr_rem>
<nro_rem>666</nro_rem>
<xCpl_rem/>
<xBairro_rem>Centro</xBairro_rem>
<cMun_rem>4310405</cMun_rem>
<xMun_rem>Independencia</xMun_rem>
<CEP_rem>98917666</CEP_rem>
<UF_rem>RS</UF_rem>
<cPais_rem>1046</cPais_rem>
<xPais_rem>Brasil</xPais_rem>
</enderRem>
</rem>
<exped>
<CNPJ_exp>99999999999999</CNPJ_exp>
<IE_exp>9999999999</IE_exp>
<xNome_exp>CT-E EMITIDO EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL</xNome_exp>
<fone_exp>5535358668</fone_exp>
<email_exp>email@email.com.br</email_exp>
<enderExped>
<xLgr_exp>Rua das Palmeiras</xLgr_exp>
<nro_exp>115</nro_exp>
<xCpl_exp>Próximo ao bar do Zé</xCpl_exp>
<xBairro_exp>Centro</xBairro_exp>
<cMun_exp>4310405</cMun_exp>
<xMun_exp>Independencia</xMun_exp>
<CEP_exp>98915000</CEP_exp>
<UF_exp>RS</UF_exp>
<cPais_exp>1046</cPais_exp>
<xPais_exp>Brasil</xPais_exp>
</enderExped>
</exped>
<receb>
<CNPJ_rec/>
<CPF_rec>99999999999</CPF_rec>
<IE_rec/>
<xNome_rec>CT-E EMITIDO EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL</xNome_rec>
<fone_rec>5597207496</fone_rec>
<email_rec>email@gmail.com.br</email_rec>
<enderReceb>
<xLgr_rec>Rua Senador Salgado Filho</xLgr_rec>
<nro_rec>463</nro_rec>
<xCpl_rec/>
<xBairro_rec>Centro</xBairro_rec>
<cMun_rec>4310405</cMun_rec>
<xMun_rec>Independencia</xMun_rec>
<CEP_rec>98915000</CEP_rec>
<UF_rec>RS</UF_rec>
<cPais_rec>1046</cPais_rec>
<xPais_rec>Brasil</xPais_rec>
</enderReceb>
</receb>
<dest>
<CPF_dest>99999999999</CPF_dest>
<IE_dest />
<xNome_dest>CT-E EMITIDO EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL</xNome_dest>
<fone_dest>5599733466</fone_dest>
<email_dest>email@gmail.com.br</email_dest>
<enderDest>
<xLgr_dest>Rua Travessa</xLgr_dest>
<nro_dest>280</nro_dest>
<xCpl_dest>Próximo ao hospital</xCpl_dest>
<xBairro_dest>Rita</xBairro_dest>
<cMun_dest>4310405</cMun_dest>
<xMun_dest>Independencia</xMun_dest>
<CEP_dest>98910000</CEP_dest>
<UF_dest>RS</UF_dest>
<cPais_dest>1046</cPais_dest>
<xPais_dest>Brasil</xPais_dest>
</enderDest>
</dest>
<vPrest>
<vTPrest>32321.23</vTPrest>
<vRec>12312.23</vRec>
<Comp>
<compItem>
<xNome_comp>Componente 1</xNome_comp>
<vComp>812.44</vComp>
</compItem>
<compItem>
<xNome_comp>Componente 2</xNome_comp>
<vComp>1612.44</vComp>
</compItem>
</Comp>
</vPrest>
<imp>
<vTotImp>59.90</vTotImp>
<infAdFisco>Informacoes de interesse do fisco estarão escritas aqui</infAdFisco>
<ICMS>
<CST>00</CST>
<vBC>12</vBC>
<pICMS>13</pICMS>
<vICMS>1.56</vICMS>
<indSN>1</indSN>
</ICMS>
</imp>
<infCTeNorm>
<infCarga>
<vMerc>599.65</vMerc>
<proPred>Pepitas de ouro</proPred>
<xOutCat>Que valem mais do que dinheiro</xOutCat>
<infQ>
<infQItem>
<cUnid>01</cUnid>
<tpMed>PESO BASE DE CÁLCULO</tpMed>
<qCarga>899</qCarga>
</infQItem>
<infQItem>
<cUnid>01</cUnid>
<tpMed>PESO BRUTO</tpMed>
<qCarga>500</qCarga>
</infQItem>
<infQItem>
<cUnid>00</cUnid>
<tpMed>M3</tpMed>
<qCarga>600</qCarga>
</infQItem>
<infQItem>
<cUnid>03</cUnid>
<tpMed>UNIDADE</tpMed>
<qCarga>520</qCarga>
</infQItem>
<infQItem>
<cUnid>05</cUnid>
<tpMed>PESO AFERIDO</tpMed>
<qCarga>332</qCarga>
</infQItem>
</infQ>
<vCargaAverb>200.00</vCargaAverb>
</infCarga>
<infDoc>
<infDocItem>
<tipoDocumento>1</tipoDocumento>
<mod_nf>01</mod_nf>
<serie_nf>445</serie_nf>
<nDoc_nf>887</nDoc_nf>
<dEmi_nf>2014-09-03</dEmi_nf>
<vBC_nf>99.01</vBC_nf>
<vICMS_nf>99.02</vICMS_nf>
<vBCST_nf>99.03</vBCST_nf>
<vST_nf>99.04</vST_nf>
<vProd_nf>99.05</vProd_nf>
<vNF_nf>99.06</vNF_nf>
<CFOP_nf>5352</CFOP_nf>
<UnidadesTransp>
<UnidadesTranspItem>
<tipoUnidTransporte>5</tipoUnidTransporte>
<idUnidTransporte>BCIASUDX988</idUnidTransporte>
<qtdRateada>999</qtdRateada>
<LacresUnidTransp>
<LacresUnidTranspItem>
<nLacreUnidTransp>999</nLacreUnidTransp>
</LacresUnidTranspItem>
</LacresUnidTransp>
<UnidadesCargaTran>
<UnidadesCargaTranItem>
<tipoUnidCargaTran>2</tipoUnidCargaTran>
<idUnidCargaTran>22</idUnidCargaTran>
<qtdRateadaCargaTran>10</qtdRateadaCargaTran>
<LacresUnidCargaTran>
<LacresUnidCargaTranItem>
<nLacreUnidCargaTran>100</nLacreUnidCargaTran>
</LacresUnidCargaTranItem>
</LacresUnidCargaTran>
</UnidadesCargaTranItem>
</UnidadesCargaTran>
</UnidadesTranspItem>
</UnidadesTransp>
</infDocItem>
</infDoc>
<infModal>
<versaoModal>3.00</versaoModal>
<rodo>
<RNTRC>89173646</RNTRC>
<dPrev_rodo>2017-05-19</dPrev_rodo>
<occ>
<occItem>
<serie_occ>123</serie_occ>
<nOcc>123456</nOcc>
<dEmi_occ>2017-05-19</dEmi_occ>
<emiOcc>
<CNPJ_occ>99999999999999</CNPJ_occ>
<cInt_occ>123</cInt_occ>
<IE_occ>9999999999</IE_occ>
<UF_occ>RS</UF_occ>
</emiOcc>
</occItem>
</occ>
</rodo>
</infModal>
</infCTeNorm>
</Envio>

0
pytrustnfe/cte/templates/CteRecepcaoEvento.xml

0
pytrustnfe/cte/templates/CteRetRecepcao.xml

3
pytrustnfe/cte/webservices.py

@ -0,0 +1,3 @@
def localizar_url(servico, estado, ambiente=2):
Loading…
Cancel
Save