Browse Source

Merge pull request #98 from danimaribeiro/master-fix

Master fix
pull/99/head
Danimar Ribeiro 8 years ago
committed by GitHub
parent
commit
baca382a0f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      pytrustnfe/Servidores.py
  2. 157
      pytrustnfe/nfe/danfe.py
  3. 2
      pytrustnfe/nfse/ginfes/templates/Rps.xml
  4. 76
      pytrustnfe/nfse/imperial/__init__.py
  5. 17
      pytrustnfe/nfse/imperial/templates/CANCELANOTAELETRONICA.xml
  6. 9
      pytrustnfe/nfse/imperial/templates/CONSULTANOTASPROTOCOLO.xml
  7. 9
      pytrustnfe/nfse/imperial/templates/CONSULTAPROTOCOLO.xml
  8. 81
      pytrustnfe/nfse/imperial/templates/PROCESSARPS.xml
  9. 5
      pytrustnfe/nfse/imperial/templates/SoapRequest.xml
  10. 13
      pytrustnfe/xml/__init__.py
  11. 6
      pytrustnfe/xml/filters.py
  12. 3
      setup.py

8
pytrustnfe/Servidores.py

@ -332,8 +332,8 @@ UFBA = {
WS_NFE_SITUACAO: 'webservices/NfeStatusServico/NfeStatusServico.asmx',
WS_NFE_INUTILIZACAO: 'webservices/nfenw/nfeinutilizacao2.asmx',
WS_NFE_CADASTRO: 'webservices/nfenw/CadConsultaCadastro2.asmx',
WS_NFE_RECEPCAO_EVENTO: 'webservices/sre/recepcaoevento',
WS_NFE_CANCELAMENTO: 'webservices/sre/recepcaoevento',
WS_NFE_RECEPCAO_EVENTO: 'webservices/sre/recepcaoevento.asmx',
WS_NFE_CANCELAMENTO: 'webservices/sre/recepcaoevento.asmx',
},
NFE_AMBIENTE_HOMOLOGACAO: {
'servidor': 'hnfe.sefaz.ba.gov.br',
@ -344,8 +344,8 @@ UFBA = {
WS_NFE_SITUACAO: 'webservices/NfeStatusServico/NfeStatusServico.asmx',
WS_NFE_INUTILIZACAO: 'webservices/nfenw/nfeinutilizacao2.asmx',
WS_NFE_CADASTRO: 'webservices/nfenw/CadConsultaCadastro2.asmx',
WS_NFE_RECEPCAO_EVENTO: 'webservices/sre/recepcaoevento',
WS_NFE_CANCELAMENTO: 'webservices/sre/recepcaoevento',
WS_NFE_RECEPCAO_EVENTO: 'webservices/sre/recepcaoevento.asmx',
WS_NFE_CANCELAMENTO: 'webservices/sre/recepcaoevento.asmx',
}
}

157
pytrustnfe/nfe/danfe.py

@ -16,6 +16,7 @@ from reportlab.graphics.barcode import code128
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.enums import TA_CENTER
from reportlab.platypus import Paragraph, Image
from reportlab.lib.styles import ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
@ -41,11 +42,9 @@ def getdateUTC(cDateUTC):
return '/'.join(cDt), cDateUTC[11:16]
def format_number(cNumber, precision=0, group_sep='.', decimal_sep=','):
def format_number(cNumber):
if cNumber:
number = float(cNumber)
return ("{:,." + str(precision) + "f}").format(number).\
replace(",", "X").replace(".", ",").replace("X", ".")
return cNumber.replace(",", "X").replace(".", ",").replace("X", ".")
return ""
@ -57,6 +56,7 @@ def tagtext(oNode=None, cTag=None):
cText = ''
return cText
REGIME_TRIBUTACAO = {
'1': 'Simples Nacional',
'2': 'Simples Nacional, excesso sublimite de receita bruta',
@ -74,7 +74,7 @@ def get_image(path, width=1 * cm):
class danfe(object):
def __init__(self, sizepage=A4, list_xml=None, recibo=True,
orientation='portrait', logo=None):
orientation='portrait', logo=None, cce_xml=None):
path = os.path.join(os.path.dirname(__file__), 'fonts')
pdfmetrics.registerFont(
@ -178,7 +178,10 @@ class danfe(object):
list_cod_prod=list_cod_prod)
self.newpage()
if cce_xml:
for xml in cce_xml:
self._generate_cce(cce_xml=xml, oXML=oXML)
self.newpage()
self.canvas.save()
def ide_emit(self, oXML=None):
@ -422,8 +425,7 @@ class danfe(object):
self.string(self.nLeft + nCol + 17, self.nlin + nLin, cDt)
self.stringRight(
self.nLeft + nCol + 47, self.nlin + nLin,
format_number(tagtext(oNode=oXML_dup, cTag='vDup'),
precision=2))
format_number(tagtext(oNode=oXML_dup, cTag='vDup')))
if nPar == 3:
nLin = 7
@ -491,41 +493,40 @@ obsCont[@xCampo='NomeVendedor']")
self.canvas.setFont('NimbusSanL-Regu', 8)
self.stringRight(
self.nLeft + 34, self.nlin + 7.7,
format_number(tagtext(oNode=el_total, cTag='vBC'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vBC')))
self.stringRight(
self.nLeft + 64, self.nlin + 7.7,
format_number(tagtext(oNode=el_total, cTag='vICMS'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vICMS')))
self.stringRight(
self.nLeft + 94, self.nlin + 7.7,
format_number(tagtext(oNode=el_total, cTag='vBCST'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vBCST')))
self.stringRight(
nMr - 66, self.nlin + 7.7,
format_number(tagtext(oNode=el_total, cTag='vST'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vST')))
self.stringRight(
nMr - 36, self.nlin + 7.7,
format_number(tagtext(oNode=el_total, cTag='vTotTrib'),
precision=2))
format_number(tagtext(oNode=el_total, cTag='vTotTrib')))
self.stringRight(
nMr - 1, self.nlin + 7.7,
format_number(tagtext(oNode=el_total, cTag='vProd'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vProd')))
self.stringRight(
self.nLeft + 34, self.nlin + 14.1,
format_number(tagtext(oNode=el_total, cTag='vFrete'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vFrete')))
self.stringRight(
self.nLeft + 64, self.nlin + 14.1,
format_number(tagtext(oNode=el_total, cTag='vSeg'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vSeg')))
self.stringRight(
self.nLeft + 94, self.nlin + 14.1,
format_number(tagtext(oNode=el_total, cTag='vDesc'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vDesc')))
self.stringRight(
self.nLeft + 124, self.nlin + 14.1,
format_number(tagtext(oNode=el_total, cTag='vOutro'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vOutro')))
self.stringRight(
self.nLeft + 154, self.nlin + 14.1,
format_number(tagtext(oNode=el_total, cTag='vIPI'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vIPI')))
self.stringRight(
nMr - 1, self.nlin + 14.1,
format_number(tagtext(oNode=el_total, cTag='vNF'), precision=2))
format_number(tagtext(oNode=el_total, cTag='vNF')))
self.nlin += 17 # Nr linhas ocupadas pelo bloco
@ -594,10 +595,10 @@ obsCont[@xCampo='NomeVendedor']")
tagtext(oNode=el_transp, cTag='nVol'))
self.stringRight(
nMr - 27, self.nlin + 21.2,
format_number(tagtext(oNode=el_transp, cTag='pesoB'), precision=3))
format_number(tagtext(oNode=el_transp, cTag='pesoB')))
self.stringRight(
nMr - 1, self.nlin + 21.2,
format_number(tagtext(oNode=el_transp, cTag='pesoL'), precision=3))
format_number(tagtext(oNode=el_transp, cTag='pesoL')))
self.nlin += 23
@ -633,10 +634,10 @@ obsCont[@xCampo='NomeVendedor']")
self.stringcenter(nMr - 44, self.nlin + 5.5, 'BC ICMS')
self.vline(nMr - 64, self.nlin + 2, nH)
self.stringcenter(nMr - 57, self.nlin + 5.5, 'VLR TOTAL')
self.vline(nMr - 77, self.nlin + 2, nH)
self.vline(nMr - 78, self.nlin + 2, nH)
self.stringcenter(nMr - 70.5, self.nlin + 5.5, 'VLR UNIT')
self.vline(nMr - 90, self.nlin + 2, nH)
self.stringcenter(nMr - 83.5, self.nlin + 5.5, 'QTD')
self.stringcenter(nMr - 83.8, self.nlin + 5.5, 'QTD')
self.vline(nMr - 96, self.nlin + 2, nH)
self.stringcenter(nMr - 93, self.nlin + 5.5, 'UNID')
self.vline(nMr - 102, self.nlin + 2, nH)
@ -665,7 +666,6 @@ obsCont[@xCampo='NomeVendedor']")
".//{http://www.portalfiscal.inf.br/nfe}ICMS")
el_imp_IPI = el_imp.find(
".//{http://www.portalfiscal.inf.br/nfe}IPI")
cCST = tagtext(oNode=el_imp_ICMS, cTag='orig') + \
(tagtext(oNode=el_imp_ICMS, cTag='CST') or
tagtext(oNode=el_imp_ICMS, cTag='CSOSN'))
@ -683,24 +683,20 @@ obsCont[@xCampo='NomeVendedor']")
tagtext(oNode=el_prod, cTag='CFOP'))
self.stringcenter(nMr - 93, nLin,
tagtext(oNode=el_prod, cTag='uCom'))
self.stringRight(nMr - 77.5, nLin, format_number(
tagtext(oNode=el_prod, cTag='qCom'), precision=4))
self.stringRight(nMr - 78.5, nLin, format_number(
tagtext(oNode=el_prod, cTag='qCom')))
self.stringRight(nMr - 64.5, nLin, format_number(
tagtext(oNode=el_prod, cTag='vUnCom'), precision=2))
self.stringRight(nMr - 50.5, nLin, format_number(
tagtext(oNode=el_prod, cTag='vProd'), precision=2))
self.stringRight(nMr - 38.5, nLin, format_number(vBC, precision=2))
self.stringRight(nMr - 26.5, nLin,
format_number(vICMS, precision=2))
self.stringRight(
nMr - 7.5, nLin, format_number(pICMS, precision=2))
tagtext(oNode=el_prod, cTag='vUnCom')))
self.stringRight(nMr - 50.5, nLin,
tagtext(oNode=el_prod, cTag='vProd'))
self.stringRight(nMr - 38.5, nLin, format_number(vBC))
self.stringRight(nMr - 26.5, nLin, format_number(vICMS))
self.stringRight(nMr - 7.5, nLin, format_number(pICMS))
if vIPI:
self.stringRight(nMr - 14.5, nLin,
format_number(vIPI, precision=2))
self.stringRight(nMr - 14.5, nLin, format_number(vIPI))
if pIPI:
self.stringRight(nMr - 0.5, nLin,
format_number(pIPI, precision=2))
self.stringRight(nMr - 0.5, nLin, format_number(pIPI))
# Código Item
line_cod = nLin
@ -741,7 +737,6 @@ obsCont[@xCampo='NomeVendedor']")
styleN.fontSize = 6
styleN.fontName = 'NimbusSanL-Regu'
styleN.leading = 7
fisco = tagtext(oNode=el_infAdic, cTag='infAdFisco')
observacoes = tagtext(oNode=el_infAdic, cTag='infCpl')
if fisco:
@ -785,8 +780,7 @@ obsCont[@xCampo='NomeVendedor']")
"SÉRIE %s" % (tagtext(oNode=el_ide, cTag='serie')))
cDt, cHr = getdateUTC(tagtext(oNode=el_ide, cTag='dhEmi'))
cTotal = format_number(tagtext(oNode=el_total, cTag='vNF'),
precision=2)
cTotal = format_number(tagtext(oNode=el_total, cTag='vNF'))
cEnd = tagtext(oNode=el_dest, cTag='xNome') + ' - '
cEnd += tagtext(oNode=el_dest, cTag='xLgr') + ', ' + tagtext(
@ -852,3 +846,80 @@ obsCont[@xCampo='NomeVendedor']")
self.oPDF_IO.close()
fileObj.write(pdf_out)
def _generate_cce(self, cce_xml=None, oXML=None):
self.canvas.setLineWidth(.2)
# labels
self.canvas.setFont('NimbusSanL-Bold', 12)
self.stringcenter(105, 10, u"Carta de Correção")
self.canvas.setFont('NimbusSanL-Regu', 6)
self.string(10, 18, u"RAZÃO SOCIAL DO EMITENTE")
self.string(10, 24, u"CNPJ DO EMITENTE")
self.string(10, 30, u"CHAVE DE ACESSO DA NF-E")
self.string(10, 36, u"DATA DA CORREÇÃO")
self.string(10, 42, u"ID")
self.stringcenter(105, 48, u"CORREÇÃO")
# lines
self.hline(9, 14, 200)
self.hline(9, 20, 200)
self.hline(9, 26, 200)
self.hline(9, 32, 200)
self.hline(9, 38, 200)
self.hline(9, 44, 200)
self.hline(9, 50, 200)
# values
infNFe = oXML.find(
".//{http://www.portalfiscal.inf.br/nfe}infNFe")
res_partner = infNFe.find(
".//{http://www.portalfiscal.inf.br/nfe}xNome")
elem_infNFe = cce_xml.find(
".//{http://www.portalfiscal.inf.br/nfe}infEvento")
res_partner = tagtext(oNode=infNFe, cTag='xNome')
self.string(82, 18, res_partner)
cnpj = format_cnpj_cpf(tagtext
(oNode=elem_infNFe, cTag='CNPJ'))
self.string(82, 24, cnpj)
chave_acesso = tagtext(oNode=elem_infNFe, cTag='chNFe')
self.string(82, 30, chave_acesso)
data_correcao = getdateUTC(tagtext(
oNode=elem_infNFe, cTag='dhEvento'))
data_correcao = data_correcao[0] + " " + data_correcao[1]
self.string(82, 36, data_correcao)
cce_id = elem_infNFe.values()[0]
self.string(82, 42, cce_id)
correcao = tagtext(oNode=elem_infNFe, cTag='xCorrecao')
w, h, paragraph = self._paragraph(
correcao, 'NimbusSanL-Regu', 10, 190 * mm, 20 * mm)
paragraph.drawOn(self.canvas, 10 * mm, (297 - 52) * mm - h)
self.hline(9, 54 + (h / mm), 200)
self.stringcenter(105, 58 + (h / mm), u"CONDIÇÃO DE USO")
self.hline(9, 60 + (h / mm), 200)
condicoes = tagtext(oNode=elem_infNFe, cTag='xCondUso')
w2, h2, paragraph = self._paragraph(
condicoes, 'NimbusSanL-Regu', 10, 190 * mm, 20 * mm)
paragraph.drawOn(self.canvas, 10 * mm, (297 - 62) * mm - h - h2)
self.hline(9, 68 + ((h + h2) / mm), 200)
self.vline(80, 14, 30)
self.vline(9, 14, 54 + ((h + h2) / mm))
self.vline(200, 14, 54 + ((h + h2) / mm))
def _paragraph(self, text, font, font_size, x, y):
ptext = '<font size=%s>%s</font>' % (font_size, text)
style = ParagraphStyle(name='Normal',
fontName=font,
fontSize=font_size,
)
paragraph = Paragraph(ptext, style=style)
w, h = paragraph.wrapOn(self.canvas, x, y)
return w, h, paragraph

2
pytrustnfe/nfse/ginfes/templates/Rps.xml

@ -27,11 +27,11 @@
<ValorCsll>{{ rps.valor_csll }}</ValorCsll>
<IssRetido>{{ rps.iss_retido }}</IssRetido>
<ValorIss>{{ rps.valor_iss }}</ValorIss>
<ValorIssRetido>{{ rps.valor_iss_retido }}</ValorIssRetido>
<OutrasRetencoes>{{ rps.outras_retencoes }}</OutrasRetencoes>
<BaseCalculo>{{ rps.base_calculo }}</BaseCalculo>
<Aliquota>{{ rps.aliquota_issqn }}</Aliquota>
<ValorLiquidoNfse>{{ rps.valor_liquido_nfse }}</ValorLiquidoNfse>
<ValorIssRetido>{{ rps.valor_iss_retido }}</ValorIssRetido>
<DescontoIncondicionado>{{ rps.desconto_incondicionado }}</DescontoIncondicionado>
<DescontoCondicionado>{{ rps.desconto_condicionado }}</DescontoCondicionado>
</Valores>

76
pytrustnfe/nfse/imperial/__init__.py

@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# © 2016 Danimar Ribeiro, Trustcode
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import os
from lxml import etree
from pytrustnfe import HttpClient
from pytrustnfe.xml import render_xml, sanitize_response
def _render(certificado, method, **kwargs):
path = os.path.join(os.path.dirname(__file__), 'templates')
xml_send = render_xml(path, '%s.xml' % method, True, **kwargs)
return etree.tostring(xml_send)
def _send(certificado, method, **kwargs):
base_url = ''
if kwargs['ambiente'] == 'producao':
base_url = 'https://nfe.etransparencia.com.br/rj.petropolis/webservice/aws_nfe.aspx' # noqa
else:
base_url = 'https://nfehomologacao.etransparencia.com.br/rj.petropolis/webservice/aws_nfe.aspx' # noqa
xml_send = kwargs["xml"]
path = os.path.join(os.path.dirname(__file__), 'templates')
soap = render_xml(path, 'SoapRequest.xml', False, soap_body=xml_send)
client = HttpClient(base_url)
response = client.post_soap(soap, 'NFeaction/AWS_NFE.%s' % method)
response, obj = sanitize_response(response)
return {
'sent_xml': xml_send,
'received_xml': response,
'object': obj
}
def xml_processa_rps(certificado, **kwargs):
return _render(certificado, 'PROCESSARPS', **kwargs)
def processa_rps(certificado, **kwargs):
if "xml" not in kwargs:
kwargs['xml'] = xml_processa_rps(certificado, **kwargs)
return _send(certificado, 'PROCESSARPS', **kwargs)
def xml_consulta_protocolo(certificado, **kwargs):
return _render(certificado, 'CONSULTAPROTOCOLO', **kwargs)
def consulta_protocolo(certificado, **kwargs):
if "xml" not in kwargs:
kwargs['xml'] = xml_consulta_protocolo(certificado, **kwargs)
return _send(certificado, 'CONSULTAPROTOCOLO', **kwargs)
def xml_consulta_notas_protocolo(certificado, **kwargs):
return _render(certificado, 'CONSULTANOTASPROTOCOLO', **kwargs)
def consulta_notas_protocolo(certificado, **kwargs):
if "xml" not in kwargs:
kwargs['xml'] = xml_consulta_notas_protocolo(certificado, **kwargs)
return _send(certificado, 'CONSULTANOTASPROTOCOLO', **kwargs)
def xml_cancelar_nfse(certificado, **kwargs):
return _render(certificado, 'CANCELANOTAELETRONICA', **kwargs)
def cancelar_nfse(certificado, **kwargs):
if "xml" not in kwargs:
kwargs['xml'] = xml_cancelar_nfse(certificado, **kwargs)
return _send(certificado, 'CANCELANOTAELETRONICA', **kwargs)

17
pytrustnfe/nfse/imperial/templates/CANCELANOTAELETRONICA.xml

@ -0,0 +1,17 @@
<ws_nfe.CANCELANOTAELETRONICA xmlns="NFe">
<Sdt_cancelanfe>
<Login>
<CodigoUsuario>{{ cancelamento.codigo_usuario }}</CodigoUsuario>
<CodigoContribuinte>{{ cancelamento.codigo_contribuinte }}</CodigoContribuinte>
</Login>
<Nota>
<SerieNota>{{ cancelamento.serie_nota }}</SerieNota>
<NumeroNota>{{ cancelamento.numero_nota }}</NumeroNota>
<SerieRPS>{{ cancelamento.serie_rps }}</SerieRPS>
<NumeroRps>{{ cancelamento.numero_rps }}</NumeroRps>
<ValorNota>{{ cancelamento.valor }}</ValorNota>
<MotivoCancelamento>{{ cancelamento.motivo }}</MotivoCancelamento>
<PodeCancelarGuia>{{ cancelamento.cancelar_guia }}</PodeCancelarGuia>
</Nota>
</Sdt_cancelanfe>
</ws_nfe.CANCELANOTAELETRONICA>

9
pytrustnfe/nfse/imperial/templates/CONSULTANOTASPROTOCOLO.xml

@ -0,0 +1,9 @@
<ws_nfe.CONSULTANOTASPROTOCOLO xmlns="NFe">
<Sdt_consultanotasprotocoloin>
<Protocolo>{{ consulta.protocolo }}</Protocolo>
<Login>
<CodigoUsuario>{{ consulta.codigo_usuario }}</CodigoUsuario>
<CodigoContribuinte>{{ consulta.codigo_contribuinte }}</CodigoContribuinte>
</Login>
</Sdt_consultanotasprotocoloin>
</ws_nfe.CONSULTANOTASPROTOCOLO>

9
pytrustnfe/nfse/imperial/templates/CONSULTAPROTOCOLO.xml

@ -0,0 +1,9 @@
<ws_nfe.CONSULTAPROTOCOLO xmlns="NFe">
<Sdt_consultaprotocoloin>
<Protocolo>{{ consulta.protocolo }}</Protocolo>
<Login>
<CodigoUsuario>{{ consulta.codigo_usuario }}</CodigoUsuario>
<CodigoContribuinte>{{ consulta.codigo_contribuinte }}</CodigoContribuinte>
</Login>
</Sdt_consultaprotocoloin>
</ws_nfe.CONSULTAPROTOCOLO>

81
pytrustnfe/nfse/imperial/templates/PROCESSARPS.xml

@ -0,0 +1,81 @@
<ws_nfe.PROCESSARPS xmlns="NFe">
<Sdt_processarpsin>
<Login>
<CodigoUsuario>{{ nfse.codigo_usuario }}</CodigoUsuario>
<CodigoContribuinte>{{ nfse.codigo_contribuinte }}</CodigoContribuinte>
</Login>
<SDTRPS>
<Ano>{{ nfse.ano }}</Ano>
<Mes>{{ nfse.mes }}</Mes>
<CPFCNPJ>{{ nfse.cnpj_prestador }}</CPFCNPJ>
<DTIni>{{ nfse.data_emissao }}</DTIni>
<DTFin>{{ nfse.data_emissao }}</DTFin>
<TipoTrib>{{ nfse.tipo_tributacao }}</TipoTrib>
<DtAdeSN>{{ nfse.data_adesao_simples }}</DtAdeSN>
<AlqIssSN_IP>{{ nfse.aliquota_simples_isencao|comma }}</AlqIssSN_IP>
<Versao>2.00</Versao>
{% for rps in nfse.lista_rps -%}
<Reg20>
<!-- Optional -->
<Reg20Item>
<TipoNFS>{{ rps.tipo_nfse }}</TipoNFS>
<NumRps>{{ rps.numero }}</NumRps>
<SerRps>{{ rps.serie }}</SerRps>
<DtEmi>{{ rps.data_emissao }}</DtEmi>
<RetFonte>{{ rps.iss_retido }}</RetFonte>
<CodSrv>{{ rps.codigo_servico }}</CodSrv>
<DiscrSrv>{{ rps.descricao}}</DiscrSrv>
<VlNFS>{{ rps.valor_liquido_nfse|comma }}</VlNFS>
<VlDed>{{ rps.valor_deducao|comma }}</VlDed>
<DiscrDed>{{ rps.discriminacao_deducao }}</DiscrDed>
<VlBasCalc>{{ rps.base_calculo|comma }}</VlBasCalc>
<AlqIss>{{ rps.aliquota_issqn|comma }}</AlqIss>
<VlIss>{{ rps.valor_iss|comma }}</VlIss>
<VlIssRet>{{ rps.valor_iss_retido|comma }}</VlIssRet>
<CpfCnpTom>{{ rps.tomador.cnpj_cpf }}</CpfCnpTom>
<RazSocTom>{{ rps.tomador.razao_social }}</RazSocTom>
<TipoLogtom>{{ rps.tomador.tipo_logradouro }}</TipoLogtom>
<LogTom>{{ rps.tomador.logradouro }}</LogTom>
<NumEndTom>{{ rps.tomador.numero }}</NumEndTom>
<ComplEndTom>{{ rps.tomador.complemento }}</ComplEndTom>
<BairroTom>{{ rps.tomador.bairro }}</BairroTom>
<MunTom>{{ rps.tomador.municipio }}</MunTom>
<SiglaUFTom>{{ rps.tomador.uf }}</SiglaUFTom>
<CepTom>{{ rps.tomador.cep }}</CepTom>
<Telefone>{{ rps.tomador.telefone }}</Telefone>
<InscricaoMunicipal>{{ rps.tomador.inscricao_municipal }}</InscricaoMunicipal>
{% if rps.local_prestacao == 'prestador' %}
<TipoLogLocPre>{{ rps.prestador.tipo_logradouro }}</TipoLogLocPre>
<LogLocPre>{{ rps.prestador.logradouro }}</LogLocPre>
<NumEndLocPre>{{ rps.prestador.numero }}</NumEndLocPre>
<ComplEndLocPre>{{ rps.prestador.complemento }}</ComplEndLocPre>
<BairroLocPre>{{ rps.prestador.bairro }}</BairroLocPre>
<MunLocPre>{{ rps.prestador.municipio }}</MunLocPre>
<SiglaUFLocpre>{{ rps.prestador.uf }}</SiglaUFLocpre>
<CepLocPre>{{ rps.prestador.cep }}</CepLocPre>
{% endif %}
<Email1>{{ rps.tomador.email }}</Email1>
{% for imposto in rps.impostos -%}
<Reg30>
<Reg30Item>
<TributoSigla>{{ imposto.sigla }}</TributoSigla>
<TributoAliquota>{{ imposto.aliquota|comma }}</TributoAliquota>
<TributoValor>{{ imposto.valor|comma }}</TributoValor>
</Reg30Item>
</Reg30>
{% endfor %}
</Reg20Item>
</Reg20>
{% endfor %}
<Reg90>
<QtdRegNormal>{{ nfse.lista_rps|length }}</QtdRegNormal>
<ValorNFS>{{ nfse.lista_rps|sum(attribute='valor_liquido_nfse')|comma }}</ValorNFS>
<ValorISS>{{ nfse.lista_rps|sum(attribute='valor_iss')|comma }}</ValorISS>
<ValorDed>{{ nfse.lista_rps|sum(attribute='valor_deducao')|comma }}</ValorDed>
<ValorIssRetTom>{{ nfse.lista_rps|sum(attribute='valor_iss_retido')|comma }}</ValorIssRetTom>
<QtdReg30>{{ nfse.quantidade_impostos }}</QtdReg30>
<ValorTributos>{{ nfse.valor_tributos|comma }}</ValorTributos>
</Reg90>
</SDTRPS>
</Sdt_processarpsin>
</ws_nfe.PROCESSARPS>

5
pytrustnfe/nfse/imperial/templates/SoapRequest.xml

@ -0,0 +1,5 @@
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
{{ soap_body }}
</Body>
</Envelope>

13
pytrustnfe/xml/__init__.py

@ -15,6 +15,18 @@ def recursively_empty(e):
return all((recursively_empty(c) for c in e.iterchildren()))
def recursively_normalize(vals):
for item in vals:
if type(vals[item]) is str:
vals[item] = vals[item].strip()
elif type(vals[item]) is dict:
recursively_normalize(vals[item])
elif type(vals[item]) is list:
for a in vals[item]:
recursively_normalize(a)
return vals
def render_xml(path, template_name, remove_empty, **nfe):
nfe = recursively_normalize(nfe)
env = Environment(
@ -25,6 +37,7 @@ def render_xml(path, template_name, remove_empty, **nfe):
env.filters["format_percent"] = filters.format_percent
env.filters["format_datetime"] = filters.format_datetime
env.filters["format_date"] = filters.format_date
env.filters["comma"] = filters.format_with_comma
template = env.get_template(template_name)
xml = template.render(**nfe)

6
pytrustnfe/xml/filters.py

@ -59,3 +59,9 @@ def format_date(value):
if isinstance(value, date):
return value.strftime(dt_format)
return value
def format_with_comma(value):
if isinstance(value, float):
return ('%.2f' % value).replace('.', ',')
return value

3
setup.py

@ -1,8 +1,10 @@
# coding=utf-8
from setuptools import setup, find_packages
VERSION = "0.9.8"
setup(
name="PyTrustNFe3",
version=VERSION,
@ -32,6 +34,7 @@ later (LGPLv2+)',
'nfse/simpliss/templates/*xml',
'nfse/betha/templates/*xml',
'nfse/susesu/templates/*xml',
'nfse/imperial/templates/*xml',
'nfse/floripa/templates/*xml',
'xml/schemas/*xsd',
]},

Loading…
Cancel
Save