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_SITUACAO: 'webservices/NfeStatusServico/NfeStatusServico.asmx',
WS_NFE_INUTILIZACAO: 'webservices/nfenw/nfeinutilizacao2.asmx', WS_NFE_INUTILIZACAO: 'webservices/nfenw/nfeinutilizacao2.asmx',
WS_NFE_CADASTRO: 'webservices/nfenw/CadConsultaCadastro2.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: { NFE_AMBIENTE_HOMOLOGACAO: {
'servidor': 'hnfe.sefaz.ba.gov.br', 'servidor': 'hnfe.sefaz.ba.gov.br',
@ -344,8 +344,8 @@ UFBA = {
WS_NFE_SITUACAO: 'webservices/NfeStatusServico/NfeStatusServico.asmx', WS_NFE_SITUACAO: 'webservices/NfeStatusServico/NfeStatusServico.asmx',
WS_NFE_INUTILIZACAO: 'webservices/nfenw/nfeinutilizacao2.asmx', WS_NFE_INUTILIZACAO: 'webservices/nfenw/nfeinutilizacao2.asmx',
WS_NFE_CADASTRO: 'webservices/nfenw/CadConsultaCadastro2.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.styles import getSampleStyleSheet
from reportlab.lib.enums import TA_CENTER from reportlab.lib.enums import TA_CENTER
from reportlab.platypus import Paragraph, Image from reportlab.platypus import Paragraph, Image
from reportlab.lib.styles import ParagraphStyle
from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase.ttfonts import TTFont
@ -41,11 +42,9 @@ def getdateUTC(cDateUTC):
return '/'.join(cDt), cDateUTC[11:16] return '/'.join(cDt), cDateUTC[11:16]
def format_number(cNumber, precision=0, group_sep='.', decimal_sep=','):
def format_number(cNumber):
if 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 "" return ""
@ -57,6 +56,7 @@ def tagtext(oNode=None, cTag=None):
cText = '' cText = ''
return cText return cText
REGIME_TRIBUTACAO = { REGIME_TRIBUTACAO = {
'1': 'Simples Nacional', '1': 'Simples Nacional',
'2': 'Simples Nacional, excesso sublimite de receita bruta', '2': 'Simples Nacional, excesso sublimite de receita bruta',
@ -74,7 +74,7 @@ def get_image(path, width=1 * cm):
class danfe(object): class danfe(object):
def __init__(self, sizepage=A4, list_xml=None, recibo=True, 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') path = os.path.join(os.path.dirname(__file__), 'fonts')
pdfmetrics.registerFont( pdfmetrics.registerFont(
@ -178,7 +178,10 @@ class danfe(object):
list_cod_prod=list_cod_prod) list_cod_prod=list_cod_prod)
self.newpage() self.newpage()
if cce_xml:
for xml in cce_xml:
self._generate_cce(cce_xml=xml, oXML=oXML)
self.newpage()
self.canvas.save() self.canvas.save()
def ide_emit(self, oXML=None): def ide_emit(self, oXML=None):
@ -422,8 +425,7 @@ class danfe(object):
self.string(self.nLeft + nCol + 17, self.nlin + nLin, cDt) self.string(self.nLeft + nCol + 17, self.nlin + nLin, cDt)
self.stringRight( self.stringRight(
self.nLeft + nCol + 47, self.nlin + nLin, 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: if nPar == 3:
nLin = 7 nLin = 7
@ -491,41 +493,40 @@ obsCont[@xCampo='NomeVendedor']")
self.canvas.setFont('NimbusSanL-Regu', 8) self.canvas.setFont('NimbusSanL-Regu', 8)
self.stringRight( self.stringRight(
self.nLeft + 34, self.nlin + 7.7, 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.stringRight(
self.nLeft + 64, self.nlin + 7.7, 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.stringRight(
self.nLeft + 94, self.nlin + 7.7, 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( self.stringRight(
nMr - 66, self.nlin + 7.7, 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( self.stringRight(
nMr - 36, self.nlin + 7.7, 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( self.stringRight(
nMr - 1, self.nlin + 7.7, 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.stringRight(
self.nLeft + 34, self.nlin + 14.1, 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.stringRight(
self.nLeft + 64, self.nlin + 14.1, 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.stringRight(
self.nLeft + 94, self.nlin + 14.1, 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.stringRight(
self.nLeft + 124, self.nlin + 14.1, 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.stringRight(
self.nLeft + 154, self.nlin + 14.1, 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( self.stringRight(
nMr - 1, self.nlin + 14.1, 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 self.nlin += 17 # Nr linhas ocupadas pelo bloco
@ -594,10 +595,10 @@ obsCont[@xCampo='NomeVendedor']")
tagtext(oNode=el_transp, cTag='nVol')) tagtext(oNode=el_transp, cTag='nVol'))
self.stringRight( self.stringRight(
nMr - 27, self.nlin + 21.2, 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( self.stringRight(
nMr - 1, self.nlin + 21.2, 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 self.nlin += 23
@ -633,10 +634,10 @@ obsCont[@xCampo='NomeVendedor']")
self.stringcenter(nMr - 44, self.nlin + 5.5, 'BC ICMS') self.stringcenter(nMr - 44, self.nlin + 5.5, 'BC ICMS')
self.vline(nMr - 64, self.nlin + 2, nH) self.vline(nMr - 64, self.nlin + 2, nH)
self.stringcenter(nMr - 57, self.nlin + 5.5, 'VLR TOTAL') 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.stringcenter(nMr - 70.5, self.nlin + 5.5, 'VLR UNIT')
self.vline(nMr - 90, self.nlin + 2, nH) 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.vline(nMr - 96, self.nlin + 2, nH)
self.stringcenter(nMr - 93, self.nlin + 5.5, 'UNID') self.stringcenter(nMr - 93, self.nlin + 5.5, 'UNID')
self.vline(nMr - 102, self.nlin + 2, nH) self.vline(nMr - 102, self.nlin + 2, nH)
@ -665,7 +666,6 @@ obsCont[@xCampo='NomeVendedor']")
".//{http://www.portalfiscal.inf.br/nfe}ICMS") ".//{http://www.portalfiscal.inf.br/nfe}ICMS")
el_imp_IPI = el_imp.find( el_imp_IPI = el_imp.find(
".//{http://www.portalfiscal.inf.br/nfe}IPI") ".//{http://www.portalfiscal.inf.br/nfe}IPI")
cCST = tagtext(oNode=el_imp_ICMS, cTag='orig') + \ cCST = tagtext(oNode=el_imp_ICMS, cTag='orig') + \
(tagtext(oNode=el_imp_ICMS, cTag='CST') or (tagtext(oNode=el_imp_ICMS, cTag='CST') or
tagtext(oNode=el_imp_ICMS, cTag='CSOSN')) tagtext(oNode=el_imp_ICMS, cTag='CSOSN'))
@ -683,24 +683,20 @@ obsCont[@xCampo='NomeVendedor']")
tagtext(oNode=el_prod, cTag='CFOP')) tagtext(oNode=el_prod, cTag='CFOP'))
self.stringcenter(nMr - 93, nLin, self.stringcenter(nMr - 93, nLin,
tagtext(oNode=el_prod, cTag='uCom')) 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( 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: if vIPI:
self.stringRight(nMr - 14.5, nLin,
format_number(vIPI, precision=2))
self.stringRight(nMr - 14.5, nLin, format_number(vIPI))
if pIPI: 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 # Código Item
line_cod = nLin line_cod = nLin
@ -741,7 +737,6 @@ obsCont[@xCampo='NomeVendedor']")
styleN.fontSize = 6 styleN.fontSize = 6
styleN.fontName = 'NimbusSanL-Regu' styleN.fontName = 'NimbusSanL-Regu'
styleN.leading = 7 styleN.leading = 7
fisco = tagtext(oNode=el_infAdic, cTag='infAdFisco') fisco = tagtext(oNode=el_infAdic, cTag='infAdFisco')
observacoes = tagtext(oNode=el_infAdic, cTag='infCpl') observacoes = tagtext(oNode=el_infAdic, cTag='infCpl')
if fisco: if fisco:
@ -785,8 +780,7 @@ obsCont[@xCampo='NomeVendedor']")
"SÉRIE %s" % (tagtext(oNode=el_ide, cTag='serie'))) "SÉRIE %s" % (tagtext(oNode=el_ide, cTag='serie')))
cDt, cHr = getdateUTC(tagtext(oNode=el_ide, cTag='dhEmi')) 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='xNome') + ' - '
cEnd += tagtext(oNode=el_dest, cTag='xLgr') + ', ' + tagtext( cEnd += tagtext(oNode=el_dest, cTag='xLgr') + ', ' + tagtext(
@ -852,3 +846,80 @@ obsCont[@xCampo='NomeVendedor']")
self.oPDF_IO.close() self.oPDF_IO.close()
fileObj.write(pdf_out) 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> <ValorCsll>{{ rps.valor_csll }}</ValorCsll>
<IssRetido>{{ rps.iss_retido }}</IssRetido> <IssRetido>{{ rps.iss_retido }}</IssRetido>
<ValorIss>{{ rps.valor_iss }}</ValorIss> <ValorIss>{{ rps.valor_iss }}</ValorIss>
<ValorIssRetido>{{ rps.valor_iss_retido }}</ValorIssRetido>
<OutrasRetencoes>{{ rps.outras_retencoes }}</OutrasRetencoes> <OutrasRetencoes>{{ rps.outras_retencoes }}</OutrasRetencoes>
<BaseCalculo>{{ rps.base_calculo }}</BaseCalculo> <BaseCalculo>{{ rps.base_calculo }}</BaseCalculo>
<Aliquota>{{ rps.aliquota_issqn }}</Aliquota> <Aliquota>{{ rps.aliquota_issqn }}</Aliquota>
<ValorLiquidoNfse>{{ rps.valor_liquido_nfse }}</ValorLiquidoNfse> <ValorLiquidoNfse>{{ rps.valor_liquido_nfse }}</ValorLiquidoNfse>
<ValorIssRetido>{{ rps.valor_iss_retido }}</ValorIssRetido>
<DescontoIncondicionado>{{ rps.desconto_incondicionado }}</DescontoIncondicionado> <DescontoIncondicionado>{{ rps.desconto_incondicionado }}</DescontoIncondicionado>
<DescontoCondicionado>{{ rps.desconto_condicionado }}</DescontoCondicionado> <DescontoCondicionado>{{ rps.desconto_condicionado }}</DescontoCondicionado>
</Valores> </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())) 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): def render_xml(path, template_name, remove_empty, **nfe):
nfe = recursively_normalize(nfe) nfe = recursively_normalize(nfe)
env = Environment( 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_percent"] = filters.format_percent
env.filters["format_datetime"] = filters.format_datetime env.filters["format_datetime"] = filters.format_datetime
env.filters["format_date"] = filters.format_date env.filters["format_date"] = filters.format_date
env.filters["comma"] = filters.format_with_comma
template = env.get_template(template_name) template = env.get_template(template_name)
xml = template.render(**nfe) xml = template.render(**nfe)

6
pytrustnfe/xml/filters.py

@ -59,3 +59,9 @@ def format_date(value):
if isinstance(value, date): if isinstance(value, date):
return value.strftime(dt_format) return value.strftime(dt_format)
return value 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 # coding=utf-8
from setuptools import setup, find_packages from setuptools import setup, find_packages
VERSION = "0.9.8" VERSION = "0.9.8"
setup( setup(
name="PyTrustNFe3", name="PyTrustNFe3",
version=VERSION, version=VERSION,
@ -32,6 +34,7 @@ later (LGPLv2+)',
'nfse/simpliss/templates/*xml', 'nfse/simpliss/templates/*xml',
'nfse/betha/templates/*xml', 'nfse/betha/templates/*xml',
'nfse/susesu/templates/*xml', 'nfse/susesu/templates/*xml',
'nfse/imperial/templates/*xml',
'nfse/floripa/templates/*xml', 'nfse/floripa/templates/*xml',
'xml/schemas/*xsd', 'xml/schemas/*xsd',
]}, ]},

Loading…
Cancel
Save