Browse Source

Merge branch 'master' into master

pull/74/head
Danimar Ribeiro 8 years ago
committed by GitHub
parent
commit
cd0514abb3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .gitignore
  2. 8
      pytrustnfe/Servidores.py
  3. 188
      pytrustnfe/nfe/danfe.py
  4. 13
      pytrustnfe/xml/__init__.py
  5. 2
      setup.py

1
.gitignore

@ -11,3 +11,4 @@ dist/
*egg*/
docs/_build
.vscode/tags
.cache/

8
pytrustnfe/Servidores.py

@ -334,8 +334,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',
@ -346,8 +346,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',
}
}

188
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
def chunks(cString, nLen):
@ -39,11 +40,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 ""
@ -55,6 +54,7 @@ def tagtext(oNode=None, cTag=None):
cText = ''
return cText
REGIME_TRIBUTACAO = {
'1': 'Simples Nacional',
'2': 'Simples Nacional, excesso sublimite de receita bruta',
@ -70,8 +70,9 @@ 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):
self.width = 210 # 21 x 29,7cm
self.height = 297
self.nLeft = 10
@ -81,7 +82,7 @@ class danfe(object):
self.nlin = self.nTop
self.logo = logo
self.oFrete = {'0': '0 - Emitente',
'1': '1 - Dest/Remet',
'1': '1 - Destinatário',
'2': '2 - Terceiros',
'9': '9 - Sem Frete'}
@ -167,7 +168,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):
@ -179,7 +183,8 @@ class danfe(object):
elem_ide = oXML.find(".//{http://www.portalfiscal.inf.br/nfe}ide")
cChave = elem_infNFe.attrib.get('Id')[3:]
barcode128 = code128.Code128(cChave, barHeight=10*mm, barWidth=0.25*mm)
barcode128 = code128.Code128(
cChave, barHeight=10 * mm, barWidth=0.25 * mm)
self.canvas.setLineWidth(.5)
self.rect(self.nLeft, self.nlin + 1, self.nLeft + 75, 32)
@ -213,7 +218,8 @@ class danfe(object):
self.stringcenter(self.nLeft + 100, self.nlin + 32, cPag)
self.canvas.setFont('NimbusSanL-Regu', 6)
self.string(self.nLeft + 86, self.nlin + 8, 'Documento Auxiliar da')
self.string(self.nLeft+86, self.nlin+10.5, 'Nota Fiscal Eletrônica')
self.string(self.nLeft + 86, self.nlin +
10.5, 'Nota Fiscal Eletrônica')
self.string(self.nLeft + 86, self.nlin + 16, '0 - Entrada')
self.string(self.nLeft + 86, self.nlin + 19, '1 - Saída')
self.rect(self.nLeft + 105, self.nlin + 15, 8, 6)
@ -342,8 +348,12 @@ class danfe(object):
self.canvas.setFont('NimbusSanL-Regu', 8)
self.string(self.nLeft + 1, self.nlin + 7.5,
tagtext(oNode=elem_dest, cTag='xNome'))
self.string(nMr-69, self.nlin+7.5,
format_cnpj_cpf(tagtext(oNode=elem_dest, cTag='CNPJ')))
cnpj_cpf = tagtext(oNode=elem_dest, cTag='CNPJ')
if cnpj_cpf:
cnpj_cpf = format_cnpj_cpf(cnpj_cpf)
else:
cnpj_cpf = format_cnpj_cpf(tagtext(oNode=elem_dest, cTag='CPF'))
self.string(nMr - 69, self.nlin + 7.5, cnpj_cpf)
cDt, cHr = getdateUTC(tagtext(oNode=elem_ide, cTag='dhEmi'))
self.string(nMr - 24, self.nlin + 7.7, cDt + ' ' + cHr)
cDt, cHr = getdateUTC(tagtext(oNode=elem_ide, cTag='dhSaiEnt'))
@ -405,8 +415,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
@ -474,41 +483,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
@ -577,10 +585,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
@ -616,10 +624,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)
@ -631,7 +639,8 @@ obsCont[@xCampo='NomeVendedor']")
nWidth_Prod = nMr - 135 - self.nLeft - 11
nCol_ = self.nLeft + 20 + (nWidth_Prod / 2)
self.stringcenter(nCol_, self.nlin+5.5, 'DESCRIÇÃO DO PRODUTO/SERVIÇO')
self.stringcenter(nCol_, self.nlin + 5.5,
'DESCRIÇÃO DO PRODUTO/SERVIÇO')
# Conteúdo campos
self.canvas.setFont('NimbusSanL-Regu', 5)
@ -647,9 +656,9 @@ 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')
(tagtext(oNode=el_imp_ICMS, cTag='CST') or
tagtext(oNode=el_imp_ICMS, cTag='CSOSN'))
vBC = tagtext(oNode=el_imp_ICMS, cTag='vBC')
vICMS = tagtext(oNode=el_imp_ICMS, cTag='vICMS')
pICMS = tagtext(oNode=el_imp_ICMS, cTag='pICMS')
@ -664,22 +673,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
@ -708,7 +715,8 @@ obsCont[@xCampo='NomeVendedor']")
self.canvas.setFont('NimbusSanL-Bold', 6)
self.string(self.nLeft + 1, self.nlin + 1, 'DADOS ADICIONAIS')
self.canvas.setFont('NimbusSanL-Regu', 5)
self.string(self.nLeft+1, self.nlin+4, 'INFORMAÇÕES COMPLEMENTARES')
self.string(self.nLeft + 1, self.nlin + 4,
'INFORMAÇÕES COMPLEMENTARES')
self.string((self.width / 2) + 1, self.nlin + 4, 'RESERVADO AO FISCO')
self.rect(self.nLeft, self.nlin + 2,
self.width - self.nLeft - self.nRight, 42)
@ -719,7 +727,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:
@ -751,18 +758,19 @@ obsCont[@xCampo='NomeVendedor']")
self.string(self.nLeft + 1, self.nlin + 10.2, 'DATA DE RECEBIMENTO')
self.string(self.nLeft + 41, self.nlin + 10.2,
'IDENTIFICAÇÃO E ASSINATURA DO RECEBEDOR')
self.stringcenter(self.width-self.nRight-(nW/2), self.nlin+2, 'NF-e')
self.stringcenter(self.width - self.nRight -
(nW / 2), self.nlin + 2, 'NF-e')
# Conteúdo campos
self.canvas.setFont('NimbusSanL-Bold', 8)
cNF = tagtext(oNode=el_ide, cTag='nNF')
cNF = '{0:011,}'.format(int(cNF)).replace(",", ".")
self.string(self.width-self.nRight-nW+2, self.nlin+8, "%s" % (cNF))
self.string(self.width - self.nRight - nW +
2, self.nlin + 8, "%s" % (cNF))
self.string(self.width - self.nRight - nW + 2, self.nlin + 14,
u"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(
@ -827,3 +835,81 @@ obsCont[@xCampo='NomeVendedor']")
pdf_out = self.oPDF_IO.getvalue()
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

13
pytrustnfe/xml/__init__.py

@ -16,7 +16,20 @@ 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(
loader=FileSystemLoader(path), extensions=['jinja2.ext.with_'])

2
setup.py

@ -1,7 +1,7 @@
# coding=utf-8
from setuptools import setup, find_packages
VERSION = "0.1.41"
VERSION = "0.1.44"
setup(
name="PyTrustNFe",

Loading…
Cancel
Save