From 374e0ec283af6311d31c3ab5777f1157ee6f6e1d Mon Sep 17 00:00:00 2001 From: Danimar Ribeiro Date: Sat, 25 Feb 2017 12:54:34 -0300 Subject: [PATCH] Teste para gerar a danfe - Ajuste na logo e dados da empresa --- pytrustnfe/nfe/danfe.py | 63 ++++++++++++++++++------------------ pytrustnfe/test/XMLs/NFe00000857.xml | 46 ++++++++++++++++++++++++++ pytrustnfe/test/test_danfe.py | 22 +++++++++++++ requirements.txt | 1 + setup.py | 1 + 5 files changed, 101 insertions(+), 32 deletions(-) create mode 100644 pytrustnfe/test/XMLs/NFe00000857.xml create mode 100644 pytrustnfe/test/test_danfe.py diff --git a/pytrustnfe/nfe/danfe.py b/pytrustnfe/nfe/danfe.py index 295cc64..bbaddf0 100644 --- a/pytrustnfe/nfe/danfe.py +++ b/pytrustnfe/nfe/danfe.py @@ -3,12 +3,8 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # Classe para geração de PDF da DANFE a partir de xml etree.fromstring -# TO DO -# Layout Paisagem -# Logo imagem da empresa from cStringIO import StringIO as IO -from lxml import etree from textwrap import wrap from reportlab.lib import utils @@ -18,6 +14,7 @@ from reportlab.lib.pagesizes import A4 from reportlab.lib.colors import black, gray 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 @@ -58,6 +55,12 @@ def tagtext(oNode=None, cTag=None): cText = '' return cText +REGIME_TRIBUTACAO = { + '1': 'Simples Nacional', + '2': 'Simples Nacional, excesso sublimite de receita bruta', + '3': 'Regime Normal' +} + def get_image(path, width=1*cm): img = utils.ImageReader(path) @@ -68,7 +71,7 @@ def get_image(path, width=1*cm): class danfe(object): def __init__(self, sizepage=A4, list_xml=None, recibo=True, - orientation='portrait'): + orientation='portrait', logo=None): self.width = 210 # 21 x 29,7cm self.height = 297 self.nLeft = 10 @@ -76,6 +79,7 @@ class danfe(object): self.nTop = 7 self.nBottom = 15 self.nlin = self.nTop + self.logo = logo self.oFrete = {'0': '0 - Emitente', '1': '1 - Dest/Remet', '2': '2 - Terceiros', @@ -248,31 +252,39 @@ class danfe(object): styles = getSampleStyleSheet() styleN = styles['Normal'] - styleN.fontSize = 11 - styleN.fontName = 'NimbusSanL-Regu' + styleN.fontSize = 10 + styleN.fontName = 'NimbusSanL-Bold' + styleN.alignment = TA_CENTER # Razão Social emitente P = Paragraph(tagtext(oNode=elem_emit, cTag='xNome'), styleN) w, h = P.wrap(55*mm, 50*mm) P.drawOn(self.canvas, (self.nLeft+30)*mm, - (self.height-self.nlin-10)*mm) + (self.height-self.nlin-12)*mm) - logo = '/home/danimar/Downloads/innova.png' - img = get_image(logo, width=2*cm) - img.drawOn(self.canvas, (self.nLeft+5)*mm, (self.height-self.nlin-22)*mm) + if self.logo: + img = get_image(self.logo, width=2*cm) + img.drawOn(self.canvas, (self.nLeft+5)*mm, + (self.height-self.nlin-22)*mm) cEnd = tagtext(oNode=elem_emit, cTag='xLgr') + ', ' + tagtext( oNode=elem_emit, cTag='nro') + ' - ' - cEnd += tagtext(oNode=elem_emit, cTag='xBairro') + ' - ' + tagtext( + cEnd += tagtext(oNode=elem_emit, cTag='xBairro') + '
' + tagtext( oNode=elem_emit, cTag='xMun') + ' - ' + cEnd += 'Fone: ' + tagtext(oNode=elem_emit, cTag='fone') + '
' cEnd += tagtext(oNode=elem_emit, cTag='UF') + ' - ' + tagtext( oNode=elem_emit, cTag='CEP') - cEnd += ' - Fone: ' + tagtext(oNode=elem_emit, cTag='fone') - styleN.fontSize = 8 + + regime = tagtext(oNode=elem_emit, cTag='CRT') + cEnd += u'
Regime Tributário: %s' % (REGIME_TRIBUTACAO[regime]) + + styleN.fontName = 'NimbusSanL-Regu' + styleN.fontSize = 7 styleN.leading = 10 P = Paragraph(cEnd, styleN) - w, h = P.wrap(80*mm, 30*mm) - P.drawOn(self.canvas, (self.nLeft+5)*mm, (self.height-self.nlin-30)*mm) + w, h = P.wrap(55*mm, 30*mm) + P.drawOn(self.canvas, (self.nLeft+30)*mm, + (self.height-self.nlin-31)*mm) # Homologação if tagtext(oNode=elem_ide, cTag='tpAmb') == '2': @@ -695,7 +707,7 @@ obsCont[@xCampo='NomeVendedor']") P = Paragraph(tagtext(oNode=el_infAdic, cTag='infCpl'), styles['Normal']) w, h = P.wrap(92*mm, 32*mm) - P.drawOn(self.canvas, (self.nLeft+1)*mm, (self.height-self.nlin-12)*mm) + P.drawOn(self.canvas, (self.nLeft+1)*mm, (self.height-self.nlin-17)*mm) self.nlin += 36 @@ -792,20 +804,7 @@ obsCont[@xCampo='NomeVendedor']") y = self.height - y self.canvas.drawCentredString(x*mm, y*mm, value) - def get_buffer(self): + def writeto_pdf(self, fileObj): pdf_out = self.oPDF_IO.getvalue() self.oPDF_IO.close() - return pdf_out - - -# Exemplo de uso - -if __name__ == "__main__": - xml_string = open( - "/home/danimar/Downloads/nfe-envio-2017-02-13-10-10.xml", "r").read() - xml_element = etree.fromstring(xml_string) - - oDanfe = danfe(list_xml=[xml_element]) - oFile = open('/home/danimar/DANFE.pdf', 'w') - oFile.write(oDanfe.get_buffer()) - oFile.close() + fileObj.write(pdf_out) diff --git a/pytrustnfe/test/XMLs/NFe00000857.xml b/pytrustnfe/test/XMLs/NFe00000857.xml new file mode 100644 index 0000000..cb47a9c --- /dev/null +++ b/pytrustnfe/test/XMLs/NFe00000857.xml @@ -0,0 +1,46 @@ +3513416577Venda Não Contribuintes15518572017-02-24T11:39:30-00:002017-02-24T11:39:30-00:0012355030811721100Odoo Brasil 1021332917000163TRUSTCODE TECNOLOGIA DA INFORMAÇÃO LTDATrustcodeRua Vinicius de Moraes42Córrego Grande3550308FlorianópolisSC880372401058Brasil1135302850144013873114111370685000184NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCALAV AMAZONAS1193Centro4314902Porto AlegreRS902405421058Brasil9VTS-L1231100907VENTIS PRETO- O2 CO H2S DIFUSAO902710006108UN1.0100.00100.00UN1.03562.2695.0010.000102999493657.260.000.0007070.000.000.000.000.003562.2695.000.000.000.000.000.000.000.003657.260.001SEDEXFalse - False, FalseINV/2017/01263562.263657.26012017-03-161828.63022017-04-151828.63PERMITE O APROVEITAMENTO DO CRÉDITO DE ICMS NO VALOR CORRESPONDENTE À ALÍQUOTA DE 1,25%, NOS TERMOS DO ART. 23 DA LC 123/2006 >>IMPORTANTE<< P/ LIQUIDACAO DESTA NF, EFETUE DEPOSITO IDENTIFICADO NO BANCO BRADESCO AG: 1992-5, C/c: 4897-6 PEDIDO DE COMPRAS: OC 0045-05/2017 N/S 16122WZ-021 (Orçamento SO176) **VENCIMENTO: 15/04/2017 ==> .OC 0045-05/2017 N/S 16122WZ-021bNLOBxpMk5J6rrz37coB8/pvTBE=Y++vItLsZAbwzM/YDsgGqSn2+u035OSigoskd1x7DDJuAFuM0imbOuC20TAJPODcZCFxfqO1VTFCVgMmJUtHGzwvVdr3DSlbxIevfTF0nNwBYN2LzQVY2R/495ro2Vw2waKfOU+O2IZrKlFxBfu91Vv/JRpbECElwZaDK1BEp2ekGkB0tHfisGbQu1WFR8HBqwcyn8khhScO8nE7S+MR8uyEqf5057AiZZr1/vG/vyNhN1yzP8FFT3kHOG3w2aNe0H85s9spUrSC5hOAIy0yD6/NUUfH9AOOlER+cCLgLT52W7I5nnxC7dgEzG6YQffy1XGd/TQ4RC7ppKwmkVFaoQ==MIIIPzCCBiegAwIBAgIQYdesnYUNG8VPne0qhTeKOzANBgkqhkiG9w0BAQsFADB4 +MQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2Vj +cmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRwwGgYD +VQQDExNBQyBDZXJ0aXNpZ24gUkZCIEc0MB4XDTE2MDUxMDAwMDAwMFoXDTE3MDUw +OTIzNTk1OVowgekxCzAJBgNVBAYTAkJSMRMwEQYDVQQKFApJQ1AtQnJhc2lsMQsw +CQYDVQQIEwJTUDESMBAGA1UEBxQJU2FvIFBhdWxvMTYwNAYDVQQLFC1TZWNyZXRh +cmlhIGRhIFJlY2VpdGEgRmVkZXJhbCBkbyBCcmFzaWwgLSBSRkIxFjAUBgNVBAsU +DVJGQiBlLUNOUEogQTExJDAiBgNVBAsUG0F1dGVudGljYWRvIHBvciBBUiBTdW5z +aGluZTEuMCwGA1UEAxMlTEVaIEFNQklFTlRBTCBMVERBIEVQUDoyMTMzMjkxNzAw +MDE2MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANEG6j0uXIvvHlMz +0IGzuY/vuFQncIoSE+cBUk0uq6J3dtmGAg4oaVWCHUfHbX9s2Ag1jIG+PFAo2dlt +sbLSEji74XhD+IpM/9aHm3ke8kb05ay+bYRuUjTNSwUbslT1+amAmIu7m1yPBi6u +v3+/Lj2I0g7VeBBAjv/TiBG0VRCURXvKrwWrv2Lpybo/yDnENGtRqQHihqeYFKin +nDzBsMbv4ripbi3XiAgcy/bF6NFgVMqxrNnGvSiSUhDRkmceVFIysRXUMke02Qo1 +Q5Ik1j1goUIHP44QOruXCMiT0yOK8u0qNAXR0yzSaWcBR2aJCeWgFg7sNbB50Qcx +c+2GKUECAwEAAaOCA1EwggNNMIG2BgNVHREEga4wgaugPQYFYEwBAwSgNAQyMTYw +NjE5ODYzNDEzNzgyODg2NTAwMDAwMDAwMDAwMDAwMDAwMDQwMDAwMzczU1NQU1Cg +IgYFYEwBAwKgGQQXTEVPTkFSRE8gREUgTElNQSBTQU5UT1OgGQYFYEwBAwOgEAQO +MjEzMzI5MTcwMDAxNjOgFwYFYEwBAwegDgQMMDAwMDAwMDAwMDAwgRJ3YWduZXJA +emVsbC5jb20uYnIwCQYDVR0TBAIwADAfBgNVHSMEGDAWgBQukerWbeWyWYLcOIUp +djQWVjzQPjAOBgNVHQ8BAf8EBAMCBeAwfwYDVR0gBHgwdjB0BgZgTAECAQwwajBo +BggrBgEFBQcCARZcaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9y +ZXBvc2l0b3Jpby9kcGMvQUNfQ2VydGlzaWduX1JGQi9EUENfQUNfQ2VydGlzaWdu +X1JGQi5wZGYwggEWBgNVHR8EggENMIIBCTBXoFWgU4ZRaHR0cDovL2ljcC1icmFz +aWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9sY3IvQUNDZXJ0aXNpZ25S +RkJHNC9MYXRlc3RDUkwuY3JsMFagVKBShlBodHRwOi8vaWNwLWJyYXNpbC5vdXRy +YWxjci5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL0FDQ2VydGlzaWduUkZCRzQvTGF0 +ZXN0Q1JMLmNybDBWoFSgUoZQaHR0cDovL3JlcG9zaXRvcmlvLmljcGJyYXNpbC5n +b3YuYnIvbGNyL0NlcnRpc2lnbi9BQ0NlcnRpc2lnblJGQkc0L0xhdGVzdENSTC5j +cmwwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMIGbBggrBgEFBQcBAQSB +jjCBizBfBggrBgEFBQcwAoZTaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNv +bS5ici9yZXBvc2l0b3Jpby9jZXJ0aWZpY2Fkb3MvQUNfQ2VydGlzaWduX1JGQl9H +NC5wN2MwKAYIKwYBBQUHMAGGHGh0dHA6Ly9vY3NwLmNlcnRpc2lnbi5jb20uYnIw +DQYJKoZIhvcNAQELBQADggIBAFIUBrNIyC4kBap/7hCW63tQhA/WNnWDNYpKM5wN +zwApVV2bqFMJURzO/7AUrHu7uZS1p/Ubo+w2dFjmnmj5DniQkY85Sd6HNa1fukJY +PK13wcUMVHMjeevIAcxnYraNdN4BIz1Svl6A8leGFgIEuDUll7Td+R7+aA8N5JYQ +dFFIe2VxvJNbWP/WA49oI8U2wkoPTfOZtfrgKf2msHm3FnTfnmyOPhIf8L31iFt6 +MbKuFjOGIaWu+Z/gRDqj/EbFcEMUrDbeIYqz2724ZGBOJrkjHO7DBqXXoN9pzCTO +RB5+gILMEnMS7zFsCuLOtLVohxgYUzg8p4Fy3nsHEzb/7IDVOnKLfjh/c5GSTvOa +JT6qznYV2yav7NyuUSNUv+5bCIBNk45+qrQ8DwpsLBsFa+RLfCwvYVK95ad/xVgJ +QosPJuzW3t0fU/FWbc00sZWV6lgBPyWhdF8EodaRIWC+EOC2wJbODyw+vdX8pUxT +TUJKV2iAP8206gR2h07o2CZgXckJGJQ5MnBUbS78AaITXZ5JlPaS7ZdU9zWY3kD+ +j5YERs0+UweijKi5eHZioGRZRDZ2uksh1wrgeLFLWuiSNaPFYVVrQ/ZGo+E5uVNl +8FuoR6P9TZjx1/A4XjqLQ9yPoPWgIWe14Vh/76dVcgz3ElWMbmPCDoc/wX+FoHX1 +Fbux +2SP_NFE_PL_008i2351702213329170001635500100000085711341657772017-02-24T08:39:31-03:00135170000807903bNLOBxpMk5J6rrz37coB8/pvTBE=100Autorizado o uso da NF-e diff --git a/pytrustnfe/test/test_danfe.py b/pytrustnfe/test/test_danfe.py new file mode 100644 index 0000000..c73bfd9 --- /dev/null +++ b/pytrustnfe/test/test_danfe.py @@ -0,0 +1,22 @@ +# coding=utf-8 + +import tempfile +import os.path +import unittest +from lxml import etree +from pytrustnfe.nfe.danfe import danfe + + +class test_danfe(unittest.TestCase): + + caminho = os.path.dirname(__file__) + + def test_can_generate_danfe(self): + path = os.path.join(os.path.dirname(__file__), 'XMLs') + xml_string = open(os.path.join(path, 'NFe00000857.xml'), "r").read() + xml_element = etree.fromstring(xml_string) + + oDanfe = danfe(list_xml=[xml_element]) + + with tempfile.TemporaryFile(mode='w') as oFile: + oDanfe.writeto_pdf(oFile) diff --git a/requirements.txt b/requirements.txt index a8fbe02..e343fde 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,4 @@ eight >= 0.3.0, < 0.4 cryptography >= 1.4, < 1.8 pyOpenSSL >= 16.0.0, < 17 certifi >= 2015.11.20.1 +reportlab diff --git a/setup.py b/setup.py index 223c55c..9d396e9 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,7 @@ later (LGPLv2+)', 'lxml >= 3.6.0, < 3.7', 'suds >= 0.4', 'suds_requests >= 0.3', + 'reportlab' ], test_suite='nose.collector', tests_require=[