Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit b454b61ab09ca911d6fa1e5b3f4c91f62239c9d4 0 parents
Arthur Furlan authored
Showing with 2,175 additions and 0 deletions.
  1. +3 −0  MANIFEST.in
  2. +127 −0 PKG-INFO
  3. +1 −0  README
  4. +104 −0 README.rst
  5. +127 −0 pyboleto.egg-info/PKG-INFO
  6. +30 −0 pyboleto.egg-info/SOURCES.txt
  7. +1 −0  pyboleto.egg-info/dependency_links.txt
  8. +3 −0  pyboleto.egg-info/entry_points.txt
  9. +1 −0  pyboleto.egg-info/not-zip-safe
  10. +1 −0  pyboleto.egg-info/requires.txt
  11. +1 −0  pyboleto.egg-info/top_level.txt
  12. +8 −0 pyboleto/__init__.py
  13. 0  pyboleto/bank/__init__.py
  14. +126 −0 pyboleto/bank/bancodobrasil.py
  15. +64 −0 pyboleto/bank/bradesco.py
  16. +74 −0 pyboleto/bank/caixa.py
  17. +50 −0 pyboleto/bank/real.py
  18. +320 −0 pyboleto/data.py
  19. BIN  pyboleto/media/logo_bancobradesco.jpg
  20. BIN  pyboleto/media/logo_bancocaixa.jpg
  21. BIN  pyboleto/media/logo_bancoreal.jpg
  22. BIN  pyboleto/media/logo_bb.jpg
  23. +762 −0 pyboleto/pdf.py
  24. 0  pyboleto/scripts/__init__.py
  25. +208 −0 pyboleto/scripts/print_sample_data.py
  26. 0  pyboleto/tests/__init__.py
  27. +39 −0 pyboleto/tests/test_banco_bradesco.py
  28. +37 −0 pyboleto/tests/test_banco_caixa.py
  29. +33 −0 pyboleto/tests/test_banco_real.py
  30. +13 −0 setup.cfg
  31. +42 −0 setup.py
3  MANIFEST.in
@@ -0,0 +1,3 @@
+include README.rst
+recursive-include pyboleto/media *
+
127 PKG-INFO
@@ -0,0 +1,127 @@
+Metadata-Version: 1.1
+Name: pyboleto
+Version: 0.1.10
+Summary: Python Library to create boletos
+Home-page: https://bitbucket.org/eduardo.cereto/pyboleto/
+Author: Eduardo Cereto Carvalho
+Author-email: eduardocereto@gmail.com
+License: BSD
+Download-URL: http://pypi.python.org/pypi/pyboleto
+Description: ========
+ pyboleto
+ ========
+
+ .. _pyboleto-synopsis:
+
+ pyboleto provides a python class to generate "boletos de cobranca" as these
+ are the Brazilian equivalent for invoices.
+
+ It's easy to implement classes for new banks.
+
+ This class is still in development and currently has no documented API.
+
+ .. contents::
+ :local:
+
+ .. _pyboleto-implemented-bank:
+
+ Implemented Banks
+ =================
+
+ You can help writing code for more banks or printing and testing current
+ implementations.
+
+ For now here's where we are.
+
+ +----------------------+----------------+-----------------+------------+
+ | **Bank** | **Carteira /** | **Implemented** | **Tested** |
+ | | **Convenio** | | |
+ +======================+================+=================+============+
+ | `Bradesco`_ | 06 | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+ | `Caixa Economica`_ | SR | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+ | `Real`_ | 57 | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+ | `Banco do Brasil`_ | 18 | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+
+ .. _Bradesco: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoBradesco
+ .. _Caixa Economica: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoCaixa
+ .. _Real: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoReal
+ .. _Banco do Brasil: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoBB
+
+
+ .. _pyboleto-docs:
+
+ Documentation
+ =============
+
+ Current documents are avilable here:
+
+ http://packages.python.org/pyboleto/
+
+ .. _pyboleto-installation:
+
+ Installation
+ ============
+
+ You can install pyboleto either via the Python Package Index (PyPI)
+ or from source.
+
+ To install using `pip`,::
+
+ $ pip install pyboleto
+
+ To install using `easy_install`,::
+
+ $ easy_install pyboleto
+
+
+ .. _pyboleto-installing-from-source:
+
+ Downloading and installing from source
+ --------------------------------------
+
+ Download the latest version of pyboleto from
+ http://pypi.python.org/pypi/pyboleto/
+
+ You can install it by doing the following,::
+
+ $ tar xvfz pyboleto-0.0.0.tar.gz
+ $ cd pyboleto-0.0.0
+ $ python setup.py build
+ # python setup.py install # as root
+
+ .. _pyboleto-installing-from-hg:
+
+ Using the development version
+ -----------------------------
+
+ You can clone the repository by doing the following::
+
+ $ hg clone https://eduardo.cereto@bitbucket.org/eduardo.cereto/pyboleto
+
+ .. _pyboleto-license:
+
+ License
+ =======
+
+ This software is licensed under the `New BSD License`. See the ``LICENSE``
+ file in the top distribution directory for the full license text.
+
+ .. vim:tw=0:sw=4:et
+
+Platform: UNKNOWN
+Classifier: Development Status :: 2 - Pre-Alpha
+Classifier: Operating System :: OS Independent
+Classifier: Framework :: Django
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Financial and Insurance Industry
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Natural Language :: Portuguese (Brazilian)
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Topic :: Office/Business :: Financial
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Provides: pyboleto
1  README
@@ -0,0 +1 @@
+README.rst
104 README.rst
@@ -0,0 +1,104 @@
+========
+pyboleto
+========
+
+.. _pyboleto-synopsis:
+
+pyboleto provides a python class to generate "boletos de cobranca" as these
+are the Brazilian equivalent for invoices.
+
+It's easy to implement classes for new banks.
+
+This class is still in development and currently has no documented API.
+
+.. contents::
+ :local:
+
+.. _pyboleto-implemented-bank:
+
+Implemented Banks
+=================
+
+You can help writing code for more banks or printing and testing current
+implementations.
+
+For now here's where we are.
+
+ +----------------------+----------------+-----------------+------------+
+ | **Bank** | **Carteira /** | **Implemented** | **Tested** |
+ | | **Convenio** | | |
+ +======================+================+=================+============+
+ | `Bradesco`_ | 06 | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+ | `Caixa Economica`_ | SR | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+ | `Real`_ | 57 | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+ | `Banco do Brasil`_ | 18 | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+
+.. _Bradesco: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoBradesco
+.. _Caixa Economica: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoCaixa
+.. _Real: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoReal
+.. _Banco do Brasil: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoBB
+
+
+.. _pyboleto-docs:
+
+Documentation
+=============
+
+Current documents are avilable here:
+
+http://packages.python.org/pyboleto/
+
+.. _pyboleto-installation:
+
+Installation
+============
+
+You can install pyboleto either via the Python Package Index (PyPI)
+or from source.
+
+To install using `pip`,::
+
+ $ pip install pyboleto
+
+To install using `easy_install`,::
+
+ $ easy_install pyboleto
+
+
+.. _pyboleto-installing-from-source:
+
+Downloading and installing from source
+--------------------------------------
+
+Download the latest version of pyboleto from
+http://pypi.python.org/pypi/pyboleto/
+
+You can install it by doing the following,::
+
+ $ tar xvfz pyboleto-0.0.0.tar.gz
+ $ cd pyboleto-0.0.0
+ $ python setup.py build
+ # python setup.py install # as root
+
+.. _pyboleto-installing-from-hg:
+
+Using the development version
+-----------------------------
+
+You can clone the repository by doing the following::
+
+ $ hg clone https://eduardo.cereto@bitbucket.org/eduardo.cereto/pyboleto
+
+.. _pyboleto-license:
+
+License
+=======
+
+This software is licensed under the `New BSD License`. See the ``LICENSE``
+file in the top distribution directory for the full license text.
+
+.. vim:tw=0:sw=4:et
127 pyboleto.egg-info/PKG-INFO
@@ -0,0 +1,127 @@
+Metadata-Version: 1.1
+Name: pyboleto
+Version: 0.1.10
+Summary: Python Library to create boletos
+Home-page: https://bitbucket.org/eduardo.cereto/pyboleto/
+Author: Eduardo Cereto Carvalho
+Author-email: eduardocereto@gmail.com
+License: BSD
+Download-URL: http://pypi.python.org/pypi/pyboleto
+Description: ========
+ pyboleto
+ ========
+
+ .. _pyboleto-synopsis:
+
+ pyboleto provides a python class to generate "boletos de cobranca" as these
+ are the Brazilian equivalent for invoices.
+
+ It's easy to implement classes for new banks.
+
+ This class is still in development and currently has no documented API.
+
+ .. contents::
+ :local:
+
+ .. _pyboleto-implemented-bank:
+
+ Implemented Banks
+ =================
+
+ You can help writing code for more banks or printing and testing current
+ implementations.
+
+ For now here's where we are.
+
+ +----------------------+----------------+-----------------+------------+
+ | **Bank** | **Carteira /** | **Implemented** | **Tested** |
+ | | **Convenio** | | |
+ +======================+================+=================+============+
+ | `Bradesco`_ | 06 | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+ | `Caixa Economica`_ | SR | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+ | `Real`_ | 57 | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+ | `Banco do Brasil`_ | 18 | Yes | No |
+ +----------------------+----------------+-----------------+------------+
+
+ .. _Bradesco: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoBradesco
+ .. _Caixa Economica: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoCaixa
+ .. _Real: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoReal
+ .. _Banco do Brasil: https://bitbucket.org/eduardo.cereto/pyboleto/wiki/BoletoBB
+
+
+ .. _pyboleto-docs:
+
+ Documentation
+ =============
+
+ Current documents are avilable here:
+
+ http://packages.python.org/pyboleto/
+
+ .. _pyboleto-installation:
+
+ Installation
+ ============
+
+ You can install pyboleto either via the Python Package Index (PyPI)
+ or from source.
+
+ To install using `pip`,::
+
+ $ pip install pyboleto
+
+ To install using `easy_install`,::
+
+ $ easy_install pyboleto
+
+
+ .. _pyboleto-installing-from-source:
+
+ Downloading and installing from source
+ --------------------------------------
+
+ Download the latest version of pyboleto from
+ http://pypi.python.org/pypi/pyboleto/
+
+ You can install it by doing the following,::
+
+ $ tar xvfz pyboleto-0.0.0.tar.gz
+ $ cd pyboleto-0.0.0
+ $ python setup.py build
+ # python setup.py install # as root
+
+ .. _pyboleto-installing-from-hg:
+
+ Using the development version
+ -----------------------------
+
+ You can clone the repository by doing the following::
+
+ $ hg clone https://eduardo.cereto@bitbucket.org/eduardo.cereto/pyboleto
+
+ .. _pyboleto-license:
+
+ License
+ =======
+
+ This software is licensed under the `New BSD License`. See the ``LICENSE``
+ file in the top distribution directory for the full license text.
+
+ .. vim:tw=0:sw=4:et
+
+Platform: UNKNOWN
+Classifier: Development Status :: 2 - Pre-Alpha
+Classifier: Operating System :: OS Independent
+Classifier: Framework :: Django
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Financial and Insurance Industry
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Natural Language :: Portuguese (Brazilian)
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Topic :: Office/Business :: Financial
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Provides: pyboleto
30 pyboleto.egg-info/SOURCES.txt
@@ -0,0 +1,30 @@
+MANIFEST.in
+README
+README.rst
+setup.cfg
+setup.py
+pyboleto/__init__.py
+pyboleto/data.py
+pyboleto/pdf.py
+pyboleto.egg-info/PKG-INFO
+pyboleto.egg-info/SOURCES.txt
+pyboleto.egg-info/dependency_links.txt
+pyboleto.egg-info/entry_points.txt
+pyboleto.egg-info/not-zip-safe
+pyboleto.egg-info/requires.txt
+pyboleto.egg-info/top_level.txt
+pyboleto/bank/__init__.py
+pyboleto/bank/bancodobrasil.py
+pyboleto/bank/bradesco.py
+pyboleto/bank/caixa.py
+pyboleto/bank/real.py
+pyboleto/media/logo_bancobradesco.jpg
+pyboleto/media/logo_bancocaixa.jpg
+pyboleto/media/logo_bancoreal.jpg
+pyboleto/media/logo_bb.jpg
+pyboleto/scripts/__init__.py
+pyboleto/scripts/print_sample_data.py
+pyboleto/tests/__init__.py
+pyboleto/tests/test_banco_bradesco.py
+pyboleto/tests/test_banco_caixa.py
+pyboleto/tests/test_banco_real.py
1  pyboleto.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
3  pyboleto.egg-info/entry_points.txt
@@ -0,0 +1,3 @@
+[console_scripts]
+print_boleto_data = pyboleto.scripts.print_sample_data:print_test
+
1  pyboleto.egg-info/not-zip-safe
@@ -0,0 +1 @@
+
1  pyboleto.egg-info/requires.txt
@@ -0,0 +1 @@
+reportlab>=2.5
1  pyboleto.egg-info/top_level.txt
@@ -0,0 +1 @@
+pyboleto
8 pyboleto/__init__.py
@@ -0,0 +1,8 @@
+VERSION = (0, 1, 10)
+__version__ = '.'.join(map(str, VERSION))
+
+__all__ = [
+ 'data',
+ 'pdf',
+ 'bank',
+]
0  pyboleto/bank/__init__.py
No changes.
126 pyboleto/bank/bancodobrasil.py
@@ -0,0 +1,126 @@
+# -*- coding: utf-8
+from pyboleto.data import BoletoData, custom_property
+import os.path
+
+### CAUTION - NÃO TESTADO ###
+class BoletoBB( BoletoData ):
+ '''
+ Gera Dados necessários para criação de boleto para o Banco do Brasil
+ '''
+
+ def __init__(self, format_convenio, format_nnumero, *args, **kwargs):
+ '''
+ Construtor para boleto do Banco deo Brasil
+
+ Args:
+ format_convenio Formato do convenio 6, 7 ou 8
+ format_nnumero Formato nosso numero 1 ou 2
+ '''
+ super(BoletoBB , self).__init__(*args, **kwargs)
+
+ self.codigo_banco = "001"
+ self.carteira = 18
+ self.logo_image_path = os.path.dirname(__file__) + \
+ "/../media/logo_bb.jpg"
+
+ # Size of convenio 6, 7 or 8
+ self.format_convenio = format_convenio
+
+ # Nosso Numero format. 1 or 2
+ # 1: Nosso Numero with 5 positions
+ # 2: Nosso Numero with 17 positions
+ self.format_nnumero = format_nnumero
+
+ def format_nosso_numero(self):
+ return "%s-%s" % (
+ self.nosso_numero,
+ self.dv_nosso_numero
+ )
+
+ # Nosso numero (sem dv) sao 11 digitos
+ def _get_nosso_numero(self):
+ return self.convenio + self._nosso_numero
+
+ def _set_nosso_numero(self,val):
+ val = str(val)
+ if self.format_convenio is 6:
+ if self.format_nnumero is 1:
+ nn = val.zfill(5)
+ elif self.format_nnumero is 2:
+ nn = val.zfill(17)
+ elif self.format_convenio is 7:
+ nn = val.zfill(10)
+ elif self.format_convenio is 8:
+ nn = val.zfill(9)
+ self._nosso_numero = nn
+
+ nosso_numero = property(_get_nosso_numero, _set_nosso_numero)
+
+ def _get_convenio(self):
+ return self._convenio
+
+ def _set_convenio(self, val):
+ self._convenio = str(val).ljust(self.format_convenio, '0')
+ convenio = property(_get_convenio, _set_convenio)
+
+ @property
+ def agencia_conta_cedente(self):
+ return "%s-%s / %s-%s" % (
+ self.agencia_cedente,
+ self.modulo11(self.agencia_cedente),
+ self.conta_cedente,
+ self.modulo11(self.conta_cedente)
+ )
+
+ @property
+ def dv_nosso_numero(self):
+ return self.modulo11(self.nosso_numero)
+
+ agencia_cedente = custom_property('agencia_cedente', 4)
+
+ conta_cedente = custom_property('conta_cedente', 8)
+
+ # Numero para o codigo de barras com 44 digitos
+ @property
+ def barcode(self):
+ if self.format_convenio in (7, 8):
+ num = "%3s%1s%1s%4s%10s%6s%s%s" % (
+ self.codigo_banco,
+ self.moeda,
+ 'X',
+ self.fator_vencimento,
+ self.formata_valor(self.valor_documento,10),
+ '000000',
+ self.nosso_numero,
+ self.carteira
+ )
+ elif self.format_convenio is 6:
+ if self.format_nnumero is 1:
+ num = "%3s%1s%1s%4s%10s%s%s%s%s" % (
+ self.codigo_banco,
+ self.moeda,
+ 'X',
+ self.fator_vencimento,
+ self.formata_valor(self.valor_documento,10),
+ self.nosso_numero,
+ self.agencia_cedente,
+ self.conta_cedente,
+ self.carteira
+ )
+ if self.format_nnumero is 2:
+ num = "%3s%1s%1s%4s%10s%s%2s" % (
+ self.codigo_banco,
+ self.moeda,
+ 'X',
+ self.fator_vencimento,
+ self.formata_valor(self.valor_documento,10),
+ self.nosso_numero,
+ '21' # numero do serviço
+ )
+
+
+ dv = self.modulo11(num.replace('X', '', 1))
+
+ num = num.replace('X', str(dv), 1)
+ return num
+
64 pyboleto/bank/bradesco.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8
+from pyboleto.data import BoletoData, custom_property
+import os.path
+
+### CAUTION - NÃO TESTADO ###
+class BoletoBradesco( BoletoData ):
+ '''
+ Gera Dados necessários para criação de boleto para o banco Bradesco
+ '''
+
+ def __init__(self, *args, **kwargs):
+ super(BoletoBradesco , self).__init__(*args, **kwargs)
+
+ self.codigo_banco = "237"
+ self.logo_image_path = os.path.dirname(__file__) + \
+ "/../media/logo_bancobradesco.jpg"
+
+ def format_nosso_numero(self):
+ return "%s/%s-%s" % (
+ self.carteira,
+ self.nosso_numero,
+ self.dv_nosso_numero
+ )
+
+ # Nosso numero (sem dv) sao 11 digitos
+ nosso_numero = custom_property('nosso_numero', 11)
+
+ @property
+ def dv_nosso_numero(self):
+ resto2 = self.modulo11(self.nosso_numero,7,1)
+ digito = 11 - resto2
+ if digito == 10:
+ dv = 'P'
+ elif digito == 11:
+ dv = 0
+ else:
+ dv = digito
+ return dv
+
+ agencia_cedente = custom_property('agencia_cedente', 4)
+
+ conta_cedente = custom_property('conta_cedente', 7)
+
+ # Numero para o codigo de barras com 44 digitos
+ @property
+ def barcode(self):
+ num = "%3s%1s%1s%4s%10s%4s%2s%11s%7s%1s" % (
+ self.codigo_banco,
+ self.moeda,
+ 'X',
+ self.fator_vencimento,
+ self.formata_valor(self.valor_documento,10),
+ self.agencia_cedente.split('-')[0],
+ self.carteira,
+ self.nosso_numero,
+ self.conta_cedente.split('-')[0],
+ '0'
+ )
+
+ dv = self.calculate_dv_barcode(num.replace('X', '', 1))
+
+ num = num.replace('X', str(dv), 1)
+ return num
+
74 pyboleto/bank/caixa.py
@@ -0,0 +1,74 @@
+#-*- coding: utf-8 -*-
+from pyboleto.data import BoletoData, custom_property
+import os.path
+
+### CAUTION - NÃO TESTADO ###
+class BoletoCaixa( BoletoData ):
+ '''
+ Gera Dados necessários para criação de boleto para o banco Caixa
+ Economica Federal
+ '''
+
+ def __init__(self, *args, **kwargs):
+ super(BoletoCaixa , self).__init__(*args, **kwargs)
+
+ self.codigo_banco = "104"
+ self.logo_image_path = os.path.dirname(__file__) + \
+ "/../media/logo_bancocaixa.jpg"
+
+ '''
+ Carteira SR: 80, 81 ou 82 -
+ Carteira CR: 90 (Confirmar com gerente qual usar)
+ '''
+ self.inicio_nosso_numero = '80'
+
+ # Nosso numero (sem dv) sao 10 digitos
+ def _nosso_numero_get(self):
+ return self._nosso_numero
+ '''
+ Nosso Número sem DV, máximo 8 chars
+ '''
+ def _nosso_numero_set(self, val):
+ try:
+ self._nosso_numero = self.inicio_nosso_numero + \
+ self.formata_numero(val, 8)
+ except AttributeError:
+ pass
+
+ nosso_numero = property(_nosso_numero_get, _nosso_numero_set)
+
+ @property
+ def dv_nosso_numero(self):
+ resto2 = self.modulo11(self.nosso_numero.split('-')[0],9,1)
+ digito = 11 - resto2
+ if digito == 10 or digito == 11:
+ dv = 0
+ else:
+ dv = digito
+ return dv
+
+ '''
+ agencia do cedente sem DV
+ '''
+ agencia_cedente = custom_property('agencia_cedente', 4)
+
+ conta_cedente = custom_property('conta_cedente', 11)
+
+ # Numero para o codigo de barras com 44 digitos
+ @property
+ def barcode(self):
+ num = "%3s%1s%1s%4s%10s%10s%4s%11s" % (
+ self.codigo_banco,
+ self.moeda,
+ 'X',
+ self.fator_vencimento,
+ self.formata_valor(self.valor_documento,10),
+ self.nosso_numero,
+ self.agencia_cedente,
+ self.conta_cedente.split('-')[0],
+ )
+ dv = self.calculate_dv_barcode(num.replace('X', '', 1))
+
+ num = num.replace('X', str(dv), 1)
+ return num
+
50 pyboleto/bank/real.py
@@ -0,0 +1,50 @@
+from pyboleto.data import BoletoData
+import os.path
+
+class BoletoReal( BoletoData ):
+
+ def __init__(self, *args, **kwargs):
+ super(BoletoReal , self).__init__(*args, **kwargs)
+
+ self.codigo_banco = "356"
+ self.logo_image_path = os.path.dirname(__file__) + \
+ "/../media/logo_bancoreal.jpg"
+
+ @property
+ def agencia_conta_cedente(self):
+ dv = self.digitao_cobranca
+ s = "%s/%s-%s" % (self.agencia_cedente, self.conta_cedente, dv)
+ return s
+
+ @property
+ def digitao_cobranca(self):
+ num = "%s%s%s" % (
+ self.nosso_numero,
+ self.agencia_cedente,
+ self.conta_cedente
+ )
+ dv = self.modulo10(num)
+ return dv
+
+ def calculate_dv_barcode(self, line):
+ dv = self.modulo11(line)
+ return dv
+
+ @property
+ def barcode(self):
+ num = "%3s%1s%1s%4s%10s%4s%7s%1s%13s" % ( \
+ self.codigo_banco, \
+ self.moeda,
+ 'X',
+ self.fator_vencimento,
+ self.formata_valor(self.valor_documento,10),
+ self.agencia_cedente,
+ self.conta_cedente,
+ self.digitao_cobranca,
+ self.nosso_numero,
+ )
+ dv = self.calculate_dv_barcode(num.replace('X', '', 1))
+
+ num = num.replace('X', str(dv), 1)
+ return num
+
320 pyboleto/data.py
@@ -0,0 +1,320 @@
+# -*- coding: utf-8 -*-
+import datetime
+import re
+from decimal import Decimal
+
+class BoletoException(Exception):
+ def __init__(self, message ):
+ Exception.__init__(self, message)
+
+def custom_property(name, num_length):
+ '''
+ Function to create properties on boleto
+
+ It accepts a number with or without a DV and zerofills it
+ '''
+ internal_attr = '_%s'%name
+
+ def _set_attr(self,val):
+ val = val.split('-')
+
+ if len(val) is 1:
+ val[0] = str(val[0]).zfill(num_length)
+ setattr(self, internal_attr, ''.join(val))
+
+ elif len(val) is 2:
+ val[0] = str(val[0]).zfill(num_length)
+ setattr(self, internal_attr, '-'.join(val))
+
+ else:
+ raise BoletoException('Wrong value format')
+
+ return property(
+ lambda self: getattr(self, internal_attr),
+ _set_attr,
+ lambda self: delattr(self, internal_attr),
+ name
+ )
+
+class BoletoData(object):
+
+ def __init__(self, *args, **kwargs):
+ self.aceite = "N"
+ self.agencia_cedente = ""
+ self.carteira = ""
+ self.cedente = ""
+ self.codigo_banco = ""
+ self.conta_cedente = ""
+ self.data_documento = ""
+ self.data_processamento = datetime.date.today()
+ self.data_vencimento = ""
+ self.demonstrativo = []
+ self.especie = "R$"
+ self.especie_documento = ""
+ self.instrucoes = []
+ self.local_pagamento = "Pagável em qualquer banco até o vencimento"
+ self.logo_image_path = ""
+ self.moeda = "9"
+ self.numero_documento = ""
+ self.quantidade = ""
+ self.sacado_nome = ""
+ self.sacado_cidade = ""
+ self.sacado_uf = ""
+ self.sacado_endereco = ""
+ self.sacado_bairro = ""
+ self.sacado_cep = ""
+
+ @property
+ def barcode(self):
+ '''
+ Returns string used to generate barcodes
+
+ It should be implemented by derived class
+ '''
+ raise NotImplementedError(
+ 'This method has not been implemented by this class'
+ )
+
+ @property
+ def dv_nosso_numero(self):
+ '''
+ Returns nosso número DV
+
+ It should be implemented by derived class
+ '''
+ raise NotImplementedError(
+ 'This method has not been implemented by this class'
+ )
+
+ def calculate_dv_barcode(self, line):
+ '''
+ Calculates de DV for barcode
+
+ It should be implemented by derived class
+ '''
+ resto2 = self.modulo11(line,9,1)
+ if resto2 in [0, 1, 10]:
+ dv = 1
+ else:
+ dv = 11 - resto2
+ return dv
+
+ def format_nosso_numero(self):
+ '''
+ Return Formatted Nosso Número
+
+ It should be implemented by derived class
+ '''
+ return self.nosso_numero
+
+ nosso_numero = custom_property('nosso_numero', 13)
+
+ agencia_cedente = custom_property('agencia_cedente', 4)
+
+ conta_cedente = custom_property('conta_cedente', 7)
+
+ def _get_valor(self):
+ try:
+ return "%.2f" % self._valor
+ except AttributeError:
+ pass
+ def _set_valor(self, val):
+ if type(val) is Decimal:
+ self._valor = val
+ else:
+ self._valor = Decimal(str(val), 2)
+ valor = property(_get_valor, _set_valor)
+
+ def _get_valor_documento(self):
+ try:
+ return "%.2f" % self._valor_documento
+ except AttributeError:
+ pass
+ def _set_valor_documento(self, val):
+ if type(val) is Decimal:
+ self._valor_documento = val
+ else:
+ self._valor_documento = Decimal(str(val), 2)
+ valor_documento = property(
+ _get_valor_documento,
+ _set_valor_documento
+ )
+
+ def _instrucoes_get(self):
+ try:
+ return self._instrucoes
+ except AttributeError:
+ pass
+ def _instrucoes_set(self, list_inst):
+ if len(list_inst) > 7:
+ raise BoletoException(
+ u'Número de linhas de instruções maior que 7')
+ for line in list_inst:
+ if len(line) > 90:
+ raise BoletoException(
+ u'Linha de instruções possui mais que 90 caracteres')
+ self._instrucoes = list_inst
+ instrucoes = property(_instrucoes_get, _instrucoes_set)
+
+ def _demonstrativo_get(self):
+ try:
+ return self._demonstrativo
+ except AttributeError:
+ pass
+ def _demonstrativo_set(self,list_dem):
+ if len(list_dem) > 12:
+ raise BoletoException(
+ u'Número de linhas de demonstrativo maior que 12')
+ for line in list_dem:
+ if len(line) > 90:
+ raise BoletoException(
+ u'Linha de demonstrativo possui mais que 90 caracteres')
+ self._demonstrativo = list_dem
+ demonstrativo = property(_demonstrativo_get, _demonstrativo_set)
+
+ def _sacado_get(self):
+ if not hasattr(self, '_sacado'):
+ self.sacado = [
+ self.sacado_nome,
+ self.sacado_endereco,
+ '%s - %s - %s - %s' % (
+ self.sacado_bairro,
+ self.sacado_cidade,
+ self.sacado_uf,
+ self.sacado_cep
+ )
+ ]
+ return self._sacado
+ def _sacado_set(self, list_sacado):
+ if len(list_sacado) > 3:
+ raise BoletoException(u'Número de linhas do sacado maior que 3')
+ for line in list_sacado:
+ if len(line) > 80:
+ raise BoletoException(
+ u'Linha de sacado possui mais que 80 caracteres')
+ self._sacado = list_sacado
+ sacado = property(_sacado_get, _sacado_set)
+
+ @property
+ def fator_vencimento(self):
+ date_ref = datetime.date(2000,7,3) # Fator = 1000
+ delta = self.data_vencimento - date_ref
+ fator = delta.days + 1000
+ return fator
+
+ @property
+ def agencia_conta_cedente(self):
+ return "%s/%s" % (self.agencia_cedente, self.conta_cedente)
+
+ @property
+ def codigo_dv_banco(self):
+ cod = "%s-%s" % (self.codigo_banco, self.modulo11(self.codigo_banco))
+ return cod
+
+ @property
+ def linha_digitavel(self):
+ '''
+ Monta a linha que o cliente pode utilizar para digitar se o código
+ de barras não puder ser lido
+ Posição Conteúdo
+ 1 a 3 Número do banco
+ 4 Código da Moeda - 9 para Real
+ 5 Digito verificador do Código de Barras
+ 6 a 19 Valor (12 inteiros e 2 decimais)
+ 20 a 44 Campo Livre definido por cada banco
+ '''
+ linha = self.barcode
+ if not linha:
+ BoletoException("Boleto doesn't have a barcode")
+
+ p1 = linha[0:4]
+ p2 = linha[19:24]
+ p3 = self.modulo10("%s%s"%(p1,p2))
+ p4 = "%s%s%s" %(p1,p2,p3)
+ p5 = p4[0:5]
+ p6 = p4[5:]
+ campo1 = "%s.%s" %(p5,p6)
+
+ p1 = linha[24:34]
+ p2 = self.modulo10(p1)
+ p3 = "%s%s" %(p1,p2)
+ p4 = p3[0:5]
+ p5 = p3[5:]
+ campo2 = "%s.%s" %(p4,p5)
+
+ p1 = linha[34:44]
+ p2 = self.modulo10(p1)
+ p3 = "%s%s" %(p1,p2)
+ p4 = p3[0:5]
+ p5 = p3[5:]
+ campo3 = "%s.%s" %(p4,p5)
+ campo4 = linha[4]
+ campo5 = linha[5:19]
+
+ return "%s %s %s %s %s" %(campo1,campo2,campo3,campo4,campo5)
+
+ @staticmethod
+ def formata_numero(numero, tamanho):
+ if len(numero) > tamanho:
+ raise BoletoException(
+ u'Tamanho em caracteres do número está maior que o permitido' )
+ return numero.zfill(tamanho)
+
+ @staticmethod
+ def formata_texto(texto, tamanho):
+ if len(texto) > tamanho:
+ raise BoletoException(
+ u'Tamanho em caracteres do texto está maior que o permitido' )
+ return texto.ljust(tamanho)
+
+ def formata_valor(self,nfloat, tamanho):
+ try:
+ txt = nfloat.replace( '.', '' )
+ txt = self.formata_numero(txt, tamanho)
+ return txt
+ except AttributeError:
+ pass
+
+ @staticmethod
+ def modulo10(num):
+ soma = 0
+ peso = 2
+ for i in range(len(num)-1,-1,-1):
+ parcial = int(num[i]) * peso
+ if parcial > 9:
+ s = "%d" % parcial
+ parcial = int(s[0])+int(s[1])
+ soma += parcial
+ if peso == 2:
+ peso = 1
+ else:
+ peso = 2
+
+ resto10 = soma % 10
+ if resto10 == 0:
+ modulo10 = 0
+ else:
+ modulo10 = 10 - resto10
+
+ return modulo10
+
+ @staticmethod
+ def modulo11(num,base=9,r=0):
+ soma=0
+ fator=2
+ for i in range(len(str(num))).__reversed__():
+ parcial10 = int(num[i]) * fator
+ soma += parcial10
+ if fator == base:
+ fator = 1
+ fator += 1
+ if r == 0:
+ soma = soma * 10
+ digito = soma % 11
+ if digito == 10:
+ digito = 0
+ return digito
+ if r == 1:
+ resto = soma % 11
+ return resto
+
BIN  pyboleto/media/logo_bancobradesco.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  pyboleto/media/logo_bancocaixa.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  pyboleto/media/logo_bancoreal.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  pyboleto/media/logo_bb.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
762 pyboleto/pdf.py
@@ -0,0 +1,762 @@
+# -*- coding: utf-8 -*-
+from reportlab.pdfgen import canvas
+from reportlab.lib.units import mm, cm
+from reportlab.lib.colors import black, white
+from reportlab.graphics.barcode.common import I2of5
+import reportlab.lib.pagesizes
+import datetime
+
+class BoletoPDF:
+
+ def __init__(self, file_descr, landscape = False ):
+ self.width = 190*mm
+ self.widthCanhoto = 70*mm
+ self.heightLine = 6.5*mm
+ self.space = 2
+ self.fontSizeTitle = 6
+ self.fontSizeValue = 9
+ self.deltaTitle = self.heightLine - (self.fontSizeTitle + 1)
+ self.deltaFont = self.fontSizeValue + 1;
+
+ if landscape:
+ pagesize = reportlab.lib.pagesizes.landscape(
+ reportlab.lib.pagesizes.A4
+ )
+ else:
+ pagesize = reportlab.lib.pagesizes.A4
+
+ self.pdfCanvas = canvas.Canvas( file_descr, pagesize = pagesize )
+ self.pdfCanvas.setStrokeColor( black )
+
+ def drawReciboSacadoCanhoto(self, boletoDados, x, y ):
+ self.pdfCanvas.saveState();
+ self.pdfCanvas.translate( x, y );
+
+ linhaInicial = 12
+
+ # Horizontal Lines
+ self.pdfCanvas.setLineWidth(2)
+ self.__horizontalLine( 0, 0, self.widthCanhoto )
+
+ self.pdfCanvas.setLineWidth(1)
+ self.__horizontalLine( 0, (linhaInicial + 0)*self.heightLine,
+ self.widthCanhoto )
+ self.__horizontalLine( 0, (linhaInicial + 1)*self.heightLine,
+ self.widthCanhoto )
+
+ self.pdfCanvas.setLineWidth(2)
+ self.__horizontalLine( 0, (linhaInicial + 2)*self.heightLine,
+ self.widthCanhoto )
+
+ # Vertical Lines
+ self.pdfCanvas.setLineWidth(1)
+ self.__verticalLine( self.widthCanhoto - (35*mm),
+ (linhaInicial + 0) * self.heightLine, self.heightLine )
+ self.__verticalLine( self.widthCanhoto - (35*mm),
+ (linhaInicial + 1) * self.heightLine, self.heightLine )
+
+ self.pdfCanvas.setFont( 'Helvetica-Bold', 6 )
+ self.pdfCanvas.drawRightString( self.widthCanhoto,
+ 0 * self.heightLine + 3,
+ 'Recibo do Sacado'
+ )
+
+ # Titles
+ self.pdfCanvas.setFont('Helvetica', 6 )
+ self.deltaTitle = self.heightLine - (6 + 1)
+
+ self.pdfCanvas.drawString(
+ self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.deltaTitle,
+ 'Nosso Número'
+ )
+ self.pdfCanvas.drawString(
+ self.widthCanhoto - (35*mm) + self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.deltaTitle,
+ 'Vencimento'
+ )
+ self.pdfCanvas.drawString(
+ self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.deltaTitle,
+ 'Agência/Código Cedente'
+ )
+ self.pdfCanvas.drawString(
+ self.widthCanhoto - (35*mm) + self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.deltaTitle,
+ 'Valor Documento'
+ )
+
+
+ # Values
+ self.pdfCanvas.setFont('Helvetica', 9 )
+ heighFont = 9 + 1;
+
+ valorDocumento = self._formataValorParaExibir(
+ boletoDados.valor_documento
+ )
+
+ self.pdfCanvas.drawString(
+ self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.space,
+ boletoDados.format_nosso_numero()
+ )
+ self.pdfCanvas.drawString(
+ self.widthCanhoto - (35*mm) + self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.space,
+ boletoDados.data_vencimento.strftime('%d/%m/%Y')
+ )
+ self.pdfCanvas.drawString(
+ self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.space,
+ boletoDados.agencia_conta_cedente
+ )
+ self.pdfCanvas.drawString(
+ self.widthCanhoto - (35*mm) + self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.space,
+ valorDocumento
+ )
+
+ demonstrativo = boletoDados.demonstrativo[0:12]
+ for i in range(len(demonstrativo)):
+ self.pdfCanvas.drawString(
+ 2*self.space,
+ (((linhaInicial - 1)*self.heightLine)) - (i * heighFont),
+ demonstrativo[i][0:55]
+ )
+
+ self.pdfCanvas.restoreState();
+
+ return ( self.widthCanhoto,
+ ((linhaInicial+2)*self.heightLine) )
+
+ def drawReciboSacado(self, boletoDados, x, y ):
+ self.pdfCanvas.saveState();
+ self.pdfCanvas.translate( x, y );
+
+ linhaInicial = 16
+
+ # Horizontal Lines
+ self.pdfCanvas.setLineWidth(1)
+ self.__horizontalLine( 0,
+ linhaInicial * self.heightLine, self.width )
+ self.__horizontalLine( 0,
+ (linhaInicial + 1) * self.heightLine, self.width )
+
+ self.pdfCanvas.setLineWidth(2)
+ self.__horizontalLine( 0,
+ (linhaInicial + 2) * self.heightLine, self.width )
+
+ # Vertical Lines
+ self.pdfCanvas.setLineWidth(1)
+ self.__verticalLine(
+ self.width - (35*mm),
+ (linhaInicial + 0) * self.heightLine,
+ 2 * self.heightLine
+ )
+ self.__verticalLine(
+ self.width - (35*mm) - (30*mm),
+ (linhaInicial + 0) * self.heightLine,
+ 2 * self.heightLine
+ )
+ self.__verticalLine(
+ self.width - (35*mm) - (30*mm) - (40*mm),
+ (linhaInicial + 0) * self.heightLine,
+ 2 * self.heightLine
+ )
+
+ # Head
+ self.pdfCanvas.setLineWidth(2)
+ self.__verticalLine( 40*mm,
+ (linhaInicial + 2) * self.heightLine, self.heightLine )
+ self.__verticalLine( 60*mm,
+ (linhaInicial + 2) * self.heightLine, self.heightLine )
+
+ if boletoDados.logo_image_path:
+ self.pdfCanvas.drawImage(
+ boletoDados.logo_image_path,
+ 0, (linhaInicial + 2) * self.heightLine + 3,
+ 40*mm,
+ self.heightLine,
+ preserveAspectRatio=True,
+ anchor='sw'
+ )
+ self.pdfCanvas.setFont( 'Helvetica-Bold', 18 )
+ self.pdfCanvas.drawCentredString(
+ 50*mm,
+ (linhaInicial + 2) * self.heightLine + 3,
+ boletoDados.codigo_dv_banco
+ )
+ self.pdfCanvas.setFont( 'Helvetica-Bold', 10 )
+ self.pdfCanvas.drawRightString(
+ self.width,
+ (linhaInicial + 2) * self.heightLine + 3,
+ 'Recibo do Sacado'
+ )
+
+ # Titles
+ self.pdfCanvas.setFont('Helvetica', 6 )
+ self.deltaTitle = self.heightLine - (6 + 1)
+
+ self.pdfCanvas.drawRightString(
+ self.width,
+ self.heightLine,
+ 'Autenticação Mecânica'
+ )
+
+ self.pdfCanvas.drawString(
+ 0,
+ (((linhaInicial + 1)*self.heightLine)) + self.deltaTitle,
+ 'Cedente'
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) - (30*mm) - (40*mm) + self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.deltaTitle,
+ 'Agência/Código Cedente'
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) - (30*mm) + self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.deltaTitle,
+ 'Data Documento'
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) + self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.deltaTitle,
+ 'Vencimento'
+ )
+
+ self.pdfCanvas.drawString(
+ 0,
+ (((linhaInicial + 0)*self.heightLine)) + self.deltaTitle,
+ 'Sacado'
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) - (30*mm) - (40*mm) + self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.deltaTitle,
+ 'Nosso Número'
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) - (30*mm) + self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.deltaTitle,
+ 'N. do documento'
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) + self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.deltaTitle,
+ 'Valor Documento'
+ )
+
+ self.pdfCanvas.drawString(
+ 0,
+ (((linhaInicial - 1)*self.heightLine-3*cm)) + self.deltaTitle,
+ 'Demonstrativo'
+ )
+
+ # Values
+ self.pdfCanvas.setFont('Helvetica', 9 )
+ heighFont = 9 + 1;
+
+ self.pdfCanvas.drawString(
+ 0 + self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.space,
+ boletoDados.cedente
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) - (30*mm) - (40*mm) + self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.space,
+ boletoDados.agencia_conta_cedente
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) - (30*mm) + self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.space,
+ boletoDados.data_documento.strftime('%d/%m/%Y')
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) + self.space,
+ (((linhaInicial + 1)*self.heightLine)) + self.space,
+ boletoDados.data_vencimento.strftime('%d/%m/%Y')
+ )
+
+ valorDocumento = self._formataValorParaExibir(
+ boletoDados.valor_documento
+ )
+
+ self.pdfCanvas.drawString(
+ 0 + self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.space,
+ boletoDados.sacado[0]
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) - (30*mm) - (40*mm) + self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.space,
+ boletoDados.format_nosso_numero()
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) - (30*mm) + self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.space,
+ boletoDados.numero_documento
+ )
+ self.pdfCanvas.drawString(
+ self.width - (35*mm) + self.space,
+ (((linhaInicial + 0)*self.heightLine)) + self.space,
+ valorDocumento
+ )
+
+ self.pdfCanvas.setFont('Courier', 9 )
+ demonstrativo = boletoDados.demonstrativo[0:25]
+ for i in range(len(demonstrativo)):
+ self.pdfCanvas.drawString(
+ 2*self.space,
+ (-3*cm+((linhaInicial - 1)*self.heightLine)) - (i * heighFont),
+ demonstrativo[i]
+ )
+
+ self.pdfCanvas.setFont('Helvetica', 9 )
+
+ self.pdfCanvas.restoreState();
+
+ return (self.width, ((linhaInicial+2)*self.heightLine));
+
+ def drawHorizontalCorteLine(self, x, y, width ):
+ self.pdfCanvas.saveState();
+ self.pdfCanvas.translate( x, y );
+
+ self.pdfCanvas.setLineWidth(1)
+ self.pdfCanvas.setDash(1,2)
+ self.__horizontalLine(0, 0, width)
+
+ self.pdfCanvas.restoreState();
+
+ def drawVerticalCorteLine(self, x, y, height ):
+ self.pdfCanvas.saveState();
+ self.pdfCanvas.translate( x, y );
+
+ self.pdfCanvas.setLineWidth(1)
+ self.pdfCanvas.setDash(1,2)
+ self.__verticalLine(0, 0, height)
+
+ self.pdfCanvas.restoreState();
+
+ def drawReciboCaixa(self, boletoDados, x, y ):
+ self.pdfCanvas.saveState();
+
+ self.pdfCanvas.translate( x, y );
+
+ # De baixo para cima posicao 0,0 esta no canto inferior esquerdo
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeTitle )
+
+ y = 1.5*self.heightLine;
+ self.pdfCanvas.drawRightString(
+ self.width,
+ (1.5*self.heightLine)+self.deltaTitle-1,
+ 'Autenticação Mecânica / Ficha de Compensação'
+ )
+
+
+ # Primeira linha depois do codigo de barra
+ y += self.heightLine;
+ self.pdfCanvas.setLineWidth(2)
+ self.__horizontalLine( 0, y, self.width )
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y+self.space, 'Código de baixa'
+ )
+ self.pdfCanvas.drawString(0, y + self.space, 'Sacador / Avalista' )
+
+ y += self.heightLine
+ self.pdfCanvas.drawString(0, y + self.deltaTitle, 'Sacado' )
+ sacado = boletoDados.sacado
+
+
+ # Linha grossa dividindo o Sacado
+ y += self.heightLine
+ self.pdfCanvas.setLineWidth(2)
+ self.__horizontalLine( 0, y, self.width )
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeValue )
+ for i in range(len(sacado)):
+ self.pdfCanvas.drawString(
+ 15*mm,
+ (y - 10) - (i * self.deltaFont),
+ sacado[i]
+ )
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeTitle )
+
+
+ # Linha vertical limitando todos os campos da direita
+ self.pdfCanvas.setLineWidth(1)
+ self.__verticalLine( self.width - (45*mm), y, 9 * self.heightLine )
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y + self.deltaTitle,
+ '(=) Valor cobrado'
+ )
+
+
+ # Campos da direita
+ y += self.heightLine
+ self.__horizontalLine( self.width - (45*mm), y, 45*mm )
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y + self.deltaTitle,
+ '(+) Outros acréscimos'
+ )
+
+ y += self.heightLine
+ self.__horizontalLine( self.width - (45*mm), y, 45*mm )
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y + self.deltaTitle,
+ '(+) Mora/Multa'
+ )
+
+ y += self.heightLine
+ self.__horizontalLine( self.width - (45*mm), y, 45*mm )
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y + self.deltaTitle,
+ '(-) Outras deduções'
+ )
+
+ y += self.heightLine
+ self.__horizontalLine( self.width - (45*mm), y, 45*mm )
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y + self.deltaTitle,
+ '(-) Descontos/Abatimentos'
+ )
+ self.pdfCanvas.drawString(
+ 0,
+ y + self.deltaTitle,
+ 'Instruções'
+ )
+
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeValue )
+ instrucoes = boletoDados.instrucoes
+ for i in range(len(instrucoes)):
+ self.pdfCanvas.drawString(
+ 2*self.space,
+ y - (i * self.deltaFont),
+ instrucoes[i]
+ )
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeTitle )
+
+
+ # Linha horizontal com primeiro campo Uso do Banco
+ y += self.heightLine
+ self.__horizontalLine( 0, y, self.width )
+ self.pdfCanvas.drawString(0, y + self.deltaTitle, 'Uso do banco' )
+
+ self.__verticalLine((30)*mm, y, 2*self.heightLine)
+ self.pdfCanvas.drawString(
+ (30*mm)+self.space,
+ y + self.deltaTitle,
+ 'Carteira'
+ )
+
+ self.__verticalLine((30+20)*mm, y, self.heightLine)
+ self.pdfCanvas.drawString(
+ ((30+20)*mm)+self.space,
+ y + self.deltaTitle,
+ 'Espécie'
+ )
+
+ self.__verticalLine(
+ (30+20+20)*mm,
+ y,
+ 2*self.heightLine
+ )
+ self.pdfCanvas.drawString(
+ ((30+40)*mm)+self.space,
+ y + self.deltaTitle,
+ 'Quantidade'
+ )
+
+ self.__verticalLine(
+ (30+20+20+20+20)*mm, y, 2*self.heightLine)
+ self.pdfCanvas.drawString(
+ ((30+40+40)*mm)+self.space, y + self.deltaTitle, 'Valor' )
+
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y + self.deltaTitle,
+ '(=) Valor documento'
+ )
+
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeValue )
+ self.pdfCanvas.drawString(
+ (30*mm)+self.space,
+ y + self.space,
+ boletoDados.carteira
+ )
+ self.pdfCanvas.drawString(
+ ((30+20)*mm)+self.space,
+ y + self.space,
+ boletoDados.especie
+ )
+ self.pdfCanvas.drawString(
+ ((30+20+20)*mm)+self.space,
+ y + self.space,
+ boletoDados.quantidade
+ )
+ valor = self._formataValorParaExibir(boletoDados.valor)
+ self.pdfCanvas.drawString(
+ ((30+20+20+20+20)*mm)+self.space,
+ y + self.space,
+ valor
+ )
+ valorDocumento = self._formataValorParaExibir(
+ boletoDados.valor_documento
+ )
+ self.pdfCanvas.drawRightString(
+ self.width - 2*self.space,
+ y + self.space,
+ valorDocumento
+ )
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeTitle )
+
+
+ # Linha horizontal com primeiro campo Data documento
+ y += self.heightLine
+ self.__horizontalLine( 0, y, self.width )
+ self.pdfCanvas.drawString(
+ 0,
+ y + self.deltaTitle,
+ 'Data do documento'
+ )
+ self.pdfCanvas.drawString(
+ (30*mm)+self.space,
+ y + self.deltaTitle,
+ 'N. do documento'
+ )
+ self.pdfCanvas.drawString(
+ ((30+40)*mm)+self.space,
+ y + self.deltaTitle,
+ 'Espécie doc'
+ )
+ self.__verticalLine(
+ (30+20+20+20)*mm,
+ y,
+ self.heightLine
+ )
+ self.pdfCanvas.drawString(
+ ((30+40+20)*mm)+self.space,
+ y + self.deltaTitle,
+ 'Aceite'
+ )
+ self.pdfCanvas.drawString(
+ ((30+40+40)*mm)+self.space,
+ y + self.deltaTitle,
+ 'Data processamento'
+ )
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y + self.deltaTitle,
+ 'Nosso número'
+ )
+
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeValue )
+ self.pdfCanvas.drawString(
+ 0,
+ y + self.space,
+ boletoDados.data_documento.strftime('%d/%m/%Y')
+ )
+ self.pdfCanvas.drawString(
+ (30*mm)+self.space,
+ y + self.space,
+ boletoDados.numero_documento
+ )
+ self.pdfCanvas.drawString(
+ ((30+40)*mm)+self.space,
+ y + self.space,
+ boletoDados.especie_documento
+ )
+ self.pdfCanvas.drawString(
+ ((30+40+20)*mm)+self.space,
+ y + self.space,
+ boletoDados.aceite
+ )
+ self.pdfCanvas.drawString(
+ ((30+40+40)*mm)+self.space,
+ y + self.space,
+ boletoDados.data_processamento.strftime('%d/%m/%Y')
+ )
+ self.pdfCanvas.drawRightString(
+ self.width - 2*self.space,
+ y + self.space,
+ boletoDados.format_nosso_numero()
+ )
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeTitle )
+
+
+ # Linha horizontal com primeiro campo Cedente
+ y += self.heightLine
+ self.__horizontalLine( 0, y, self.width )
+ self.pdfCanvas.drawString(0, y + self.deltaTitle, 'Cedente' )
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y + self.deltaTitle,
+ 'Agência/Código cedente'
+ )
+
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeValue )
+ self.pdfCanvas.drawString(0, y + self.space, boletoDados.cedente )
+ self.pdfCanvas.drawRightString(
+ self.width - 2*self.space,
+ y + self.space,
+ boletoDados.agencia_conta_cedente
+ )
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeTitle )
+
+
+ # Linha horizontal com primeiro campo Local de Pagamento
+ y += self.heightLine
+ self.__horizontalLine( 0, y, self.width )
+ self.pdfCanvas.drawString(
+ 0,
+ y + self.deltaTitle,
+ 'Local de pagamento'
+ )
+ self.pdfCanvas.drawString(
+ self.width - (45*mm) + self.space,
+ y + self.deltaTitle,
+ 'Vencimento'
+ )
+
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeValue )
+ self.pdfCanvas.drawString(
+ 0,
+ y + self.space,
+ boletoDados.local_pagamento
+ )
+ self.pdfCanvas.drawRightString(
+ self.width - 2*self.space,
+ y + self.space,
+ boletoDados.data_vencimento.strftime('%d/%m/%Y')
+ )
+ self.pdfCanvas.setFont('Helvetica', self.fontSizeTitle )
+
+
+ # Linha grossa com primeiro campo logo tipo do banco
+ self.pdfCanvas.setLineWidth(3)
+ y += self.heightLine
+ self.__horizontalLine( 0, y, self.width )
+ self.pdfCanvas.setLineWidth(2)
+ self.__verticalLine(40*mm, y, self.heightLine) # Logo Tipo
+ self.__verticalLine(60*mm, y, self.heightLine) # Numero do Banco
+
+ if boletoDados.logo_image_path:
+ self.pdfCanvas.drawImage(
+ boletoDados.logo_image_path,
+ 0,
+ y + self.space + 1,
+ 40*mm,
+ self.heightLine,
+ preserveAspectRatio=True,
+ anchor='sw'
+ )
+ self.pdfCanvas.setFont('Helvetica-Bold', 18 )
+ self.pdfCanvas.drawCentredString(
+ 50*mm,
+ y + 2*self.space,
+ boletoDados.codigo_dv_banco
+ )
+ self.pdfCanvas.setFont('Helvetica-Bold', 10 )
+ self.pdfCanvas.drawRightString(
+ self.width,
+ y + 2*self.space,
+ boletoDados.linha_digitavel
+ )
+
+
+ # Codigo de barras
+ self._codigoBarraI25(boletoDados.barcode, 2*self.space, 0)
+
+
+ self.pdfCanvas.restoreState();
+
+ return (self.width, (y+self.heightLine) )
+
+ def drawBoletoCarneDuplo(self, boletoDados1, boletoDados2 ):
+ y = 5*mm
+ d = self.drawBoletoCarne(boletoDados1, y)
+ y += d[1] + 6*mm
+ #self.drawHorizontalCorteLine(0, y, d[0])
+ y += 7*mm
+ if( boletoDados2):
+ self.drawBoletoCarne(boletoDados2, y)
+
+ def drawBoletoCarne(self, boletoDados, y ):
+ x = 15*mm
+ d = self.drawReciboSacadoCanhoto(boletoDados, x, y)
+ x += d[0] + 8*mm
+ self.drawVerticalCorteLine(x, y, d[1])
+ x += 8*mm
+ d = self.drawReciboCaixa(boletoDados, x, y)
+ x += d[0]
+ return (x,d[1])
+
+ def drawBoleto(self, boletoDados ):
+ x = 3.5*mm
+ y = 0
+ #y += 2*mm
+ #self.drawHorizontalCorteLine(x, y, self.width)
+ y += 1*mm
+ d = self.drawReciboCaixa(boletoDados, x, y)
+ y += d[1] + (25*mm)
+ self.drawHorizontalCorteLine(x, y, self.width)
+ y += 20*mm
+ d = self.drawReciboSacado(boletoDados, x, y)
+ y += d[1]
+ return (self.width,y)
+
+ def nextPage(self):
+ self.pdfCanvas.showPage()
+
+ def save(self):
+ self.pdfCanvas.save()
+
+ def __horizontalLine( self, x, y, width ):
+ self.pdfCanvas.line( x, y, x+width, y )
+
+ def __verticalLine( self, x, y, width ):
+ self.pdfCanvas.line( x, y, x, y+width )
+
+ def __centreText(self, x, y, text ):
+ self.pdfCanvas.drawCentredString( self.refX+x, self.refY+y, text )
+
+ def __rightText(self, x, y, text ):
+ self.pdfCanvas.drawRightString( self.refX+x, self.refY+y, text )
+
+ def _formataValorParaExibir(self, nfloat):
+ if nfloat:
+ txt = nfloat
+ txt = txt.replace( '.', ',' )
+ else:
+ txt = ""
+ return txt
+
+ def _codigoBarraI25(self, num, x, y ):
+ # http://en.wikipedia.org/wiki/Interleaved_2_of_5
+
+ altura = 13 * mm
+ comprimento = 103 * mm
+
+ tracoFino = 0.254320987654 * mm #Tamanho correto aproximado
+
+ bc = I2of5(num,
+ barWidth = tracoFino,
+ ratio = 3,
+ barHeight = altura,
+ bearers = 0,
+ quiet = 0,
+ checksum = 0
+ )
+
+ # Recalcula o tamanho do tracoFino para que o cod de barras tenha o
+ # comprimento correto
+ tracoFino = (tracoFino * comprimento)/bc.width
+ bc.__init__(num,
+ barWidth = tracoFino
+ )
+
+ bc.drawOn(self.pdfCanvas, x, y)
+
0  pyboleto/scripts/__init__.py
No changes.
208 pyboleto/scripts/print_sample_data.py
@@ -0,0 +1,208 @@
+# -*- coding: utf-8 -*-
+from pyboleto.bank.real import BoletoReal
+from pyboleto.bank.bradesco import BoletoBradesco
+from pyboleto.bank.caixa import BoletoCaixa
+from pyboleto.bank.bancodobrasil import BoletoBB
+from pyboleto.pdf import BoletoPDF
+import datetime
+
+def print_bb():
+ listaDados = []
+ for i in range(2):
+ d = BoletoBB(7,2)
+ d.nosso_numero = '87654'
+ d.numero_documento = '27.030195.10'
+ d.convenio = '7777777'
+ d.especie_documento = 'DM'
+
+ d.carteira = '18'
+ d.cedente = 'Empresa Empresa Empresa Empresa Empresa LTDA'
+ d.agencia_cedente = '9999'
+ d.conta_cedente = '99999'
+
+ d.data_vencimento = datetime.date(2010, 3, 27)
+ d.data_documento = datetime.date(2010, 02, 12)
+ d.data_processamento = datetime.date(2010, 02, 12)
+
+ d.instrucoes = [
+ "- Linha 1",
+ "- Sr Caixa, cobrar multa de 2% após o vencimento",
+ "- Receber até 10 dias após o vencimento",
+ ]
+ d.demonstrativo = [
+ "- Serviço Teste R$ 5,00",
+ "- Total R$ 5,00",
+ ]
+ d.valor_documento = 255.00
+
+ d.sacado = [
+ "Cliente Teste %d" % (i+1),
+ "Rua Desconhecida, 00/0000 - Não Sei - Cidade - Cep. 00000-000",
+ ""
+ ]
+ listaDados.append( d )
+
+ print "Normal"
+ boleto = BoletoPDF( 'boleto-bb-formato-normal-teste.pdf' )
+ for i in range(len(listaDados)):
+ print i
+ boleto.drawBoleto(listaDados[i])
+ boleto.nextPage()
+ boleto.save()
+
+
+
+def print_test():
+ listaDadosReal = []
+ for i in range(2):
+ d = BoletoReal()
+ d.carteira = '57' # Contrato firmado com o Banco Real
+ d.cedente = 'Empresa Empresa Empresa Empresa Empresa LTDA'
+ d.agencia_cedente = '0531'
+ d.conta_cedente = '5705853'
+
+ d.data_vencimento = datetime.date(2010, 3, 27)
+ d.data_documento = datetime.date(2010, 02, 12)
+ d.data_processamento = datetime.date(2010, 02, 12)
+
+ d.instrucoes = [
+ "- Linha 1",
+ "- Sr Caixa, cobrar multa de 2% após o vencimento",
+ "- Receber até 10 dias após o vencimento",
+ ]
+ d.demonstrativo = [
+ "- Serviço Teste R$ 5,00",
+ "- Total R$ 5,00",
+ ]
+ d.valor_documento = 5.00
+
+ d.nosso_numero = "%d" % (i+2)
+ d.numero_documento = "%d" % (i+2)
+ d.sacado = [
+ "Cliente Teste %d" % (i+1),
+ "Rua Desconhecida, 00/0000 - Não Sei - Cidade - Cep. 00000-000",
+ ""
+ ]
+ listaDadosReal.append( d )
+
+ listaDadosBradesco = []
+ for i in range(2):
+ d = BoletoBradesco()
+ d.carteira = '06' # Contrato firmado com o Banco Bradesco
+ d.cedente = 'Empresa Empresa Empresa Empresa Empresa LTDA'
+ d.agencia_cedente = '0278-0'
+ d.conta_cedente = '43905-3'
+
+ d.data_vencimento = datetime.date(2011, 1, 25)
+ d.data_documento = datetime.date(2010, 02, 12)
+ d.data_processamento = datetime.date(2010, 02, 12)
+
+ d.instrucoes = [
+ "- Linha 1",
+ "- Sr Caixa, cobrar multa de 2% após o vencimento",
+ "- Receber até 10 dias após o vencimento",
+ ]
+ d.demonstrativo = [
+ "- Serviço Teste R$ 5,00",
+ "- Total R$ 5,00",
+ ]
+ d.valor_documento = 2158.41
+
+ d.nosso_numero = "1112011668"
+ d.numero_documento = "1112011668"
+ d.sacado = [
+ "Cliente Teste %d" % (i+1),
+ "Rua Desconhecida, 00/0000 - Não Sei - Cidade - Cep. 00000-000",
+ ""
+ ]
+ listaDadosBradesco.append( d )
+
+ listaDadosCaixa = []
+ for i in range(2):
+ d = BoletoCaixa()
+ d.carteira = 'SR' # Contrato firmado com o Banco Bradesco
+ d.cedente = 'Empresa Empresa Empresa Empresa Empresa LTDA'
+ d.agencia_cedente = '1565'
+ d.conta_cedente = '414-3'
+
+ d.data_vencimento = datetime.date(2010, 3, 27)
+ d.data_documento = datetime.date(2010, 02, 12)
+ d.data_processamento = datetime.date(2010, 02, 12)
+
+ d.instrucoes = [
+ "- Linha 1",
+ "- Sr Caixa, cobrar multa de 2% após o vencimento",
+ "- Receber até 10 dias após o vencimento",
+ ]
+ d.demonstrativo = [
+ "- Serviço Teste R$ 5,00",
+ "- Total R$ 5,00",
+ ]
+ d.valor_documento = 255.00
+
+ d.nosso_numero = "%d" % (i+2)
+ d.numero_documento = "%d" % (i+2)
+ d.sacado = [
+ "Cliente Teste %d" % (i+1),
+ "Rua Desconhecida, 00/0000 - Não Sei - Cidade - Cep. 00000-000",
+ ""
+ ]
+ listaDadosCaixa.append( d )
+
+
+ # Bradesco Formato carne - duas paginas por folha A4
+ print "Carne"
+ boleto = BoletoPDF( 'boleto-bradesco-formato-carne-teste.pdf', True )
+ for i in range(0,len(listaDadosBradesco),2):
+ print i, i+1
+ boleto.drawBoletoCarneDuplo(
+ listaDadosBradesco[i],
+ listaDadosBradesco[i+1]
+ )
+ boleto.nextPage()
+ boleto.save()
+
+ # Bradesco Formato normal - uma pagina por folha A4
+ print "Normal"
+ boleto = BoletoPDF( 'boleto-bradesco-formato-normal-teste.pdf' )
+ for i in range(len(listaDadosBradesco)):
+ print i
+ boleto.drawBoleto(listaDadosBradesco[i])
+ boleto.nextPage()
+ boleto.save()
+
+ # Real Formato normal - uma pagina por folha A4
+ print "Normal"
+ boleto = BoletoPDF( 'boleto-real-formato-normal-teste.pdf' )
+ for i in range(len(listaDadosReal)):
+ print i
+ boleto.drawBoleto(listaDadosReal[i])
+ boleto.nextPage()
+ boleto.save()
+
+ # Caixa Formato normal - uma pagina por folha A4
+ print "Carne"
+ boleto = BoletoPDF( 'boleto-caixa-formato-carne-teste.pdf', True )
+ for i in range(0,len(listaDadosCaixa),2):
+ print i, i+1
+ boleto.drawBoletoCarneDuplo(
+ listaDadosCaixa[i],
+ listaDadosCaixa[i+1]
+ )
+ boleto.nextPage()
+ boleto.save()
+
+ # Caixa Formato normal - uma pagina por folha A4
+ print "Normal"
+ boleto = BoletoPDF( 'boleto-caixa-formato-normal-teste.pdf' )
+ for i in range(len(listaDadosCaixa)):
+ print i
+ boleto.drawBoleto(listaDadosCaixa[i])
+ boleto.nextPage()
+ boleto.save()
+
+ print "Ok"
+
+if __name__ == "__main__":
+ print_test()
+ print_bb()
0  pyboleto/tests/__init__.py
No changes.
39 pyboleto/tests/test_banco_bradesco.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+import unittest
+import datetime
+
+from pyboleto.bank.bradesco import BoletoBradesco
+
+class TestBancoBradesco(unittest.TestCase):
+ def setUp(self):
+ d = BoletoBradesco()
+ d.carteira = '06'
+ d.agencia_cedente = '278-0'
+ d.conta_cedente = '039232-4'
+ d.data_vencimento = datetime.date(2011, 2, 5)
+ d.data_documento = datetime.date(2011, 1, 18)
+ d.data_processamento = datetime.date(201, 1, 18)
+ d.valor_documento = 8280.00
+ d.nosso_numero = '2125525'
+ d.numero_documento = '2125525'
+ self.dados = d
+
+ def test_linha_digitavel(self):
+ self.assertEqual(self.dados.linha_digitavel,
+ '23790.27804 60000.212559 25003.923205 4 48690000828000'
+ )
+
+ def test_codigo_de_barras(self):
+ self.assertEqual(self.dados.barcode,
+ '23794486900008280000278060000212552500392320'
+ )
+
+ def test_agencia(self):
+ self.assertEqual(self.dados.agencia_cedente, '0278-0')
+
+ def test_conta(self):
+ self.assertEqual(self.dados.conta_cedente, '0039232-4')
+
+if __name__ == '__main__':
+ unittest.main()
+
37 pyboleto/tests/test_banco_caixa.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+import unittest
+import datetime
+
+from pyboleto.bank.caixa import BoletoCaixa
+
+class TestBancoCaixa(unittest.TestCase):
+ def setUp(self):
+ d = BoletoCaixa()
+ d.carteira = 'SR'
+ d.inicio_nosso_numero = '80'
+ d.agencia_cedente = '1565'
+ d.conta_cedente = '414-3'
+ d.data_vencimento = datetime.date(2011, 2, 5)
+ d.data_documento = datetime.date(2011, 1, 18)
+ d.data_processamento = datetime.date(201, 1, 18)
+ d.valor_documento = 355.00
+ d.nosso_numero = '19525086'
+ d.numero_documento = '19525086'
+ self.dados = d
+
+ def test_linha_digitavel(self):
+ self.assertEqual(self.dados.linha_digitavel,
+ '10498.01952 25086.156509 00000.004143 7 48690000035500'
+ )
+
+ def test_tamanho_codigo_de_barras(self):
+ self.assertEqual(len(self.dados.barcode), 44)
+
+ def test_codigo_de_barras(self):
+ self.assertEqual(self.dados.barcode,
+ '10497486900000355008019525086156500000000414'
+ )
+
+if __name__ == '__main__':
+ unittest.main()
+
33 pyboleto/tests/test_banco_real.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+import unittest
+import datetime
+
+from pyboleto.bank.real import BoletoReal
+
+class TestBancoBradesco(unittest.TestCase):
+ def setUp(self):
+ d = BoletoReal()
+ d.carteira = '06'
+ d.agencia_cedente = '0531'
+ d.conta_cedente = '5705853'
+ d.data_vencimento = datetime.date(2011, 2, 5)
+ d.data_documento = datetime.date(2011, 1, 18)
+ d.data_processamento = datetime.date(201, 1, 18)
+ d.valor_documento = 355.00
+ d.nosso_numero = '123'
+ d.numero_documento = '123'
+ self.dados = d
+
+ def test_linha_digitavel(self):
+ self.assertEqual(self.dados.linha_digitavel,
+ '35690.53154 70585.390001 00000.001230 8 48690000035500'
+ )
+
+ def test_codigo_de_barras(self):
+ self.assertEqual(self.dados.barcode,
+ '35698486900000355000531570585390000000000123'
+ )
+
+if __name__ == '__main__':
+ unittest.main()
+
13 setup.cfg
@@ -0,0 +1,13 @@
+[build_sphinx]
+all_files = 1
+build-dir = docs/_build
+source-dir = docs/
+
+[egg_info]
+tag_build =
+tag_date = 0
+tag_svn_revision = 0
+
+[upload_sphinx]
+upload-dir = docs/_build/html
+
42 setup.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+from setuptools import setup, find_packages
+
+setup(
+ name = 'pyboleto',
+ version = __import__('pyboleto').__version__,
+ author = 'Eduardo Cereto Carvalho',
+ author_email = 'eduardocereto@gmail.com',
+ url = 'https://bitbucket.org/eduardo.cereto/pyboleto/',
+ packages = find_packages(),
+ include_package_data = True,
+ zip_safe = False,
+ install_requires = [
+ 'reportlab>=2.5',
+ ],
+ provides = [
+ 'pyboleto'
+ ],
+ license = 'BSD',
+ description = 'Python Library to create boletos',
+ long_description = open('README.rst', 'r').read(),
+ download_url = 'http://pypi.python.org/pypi/pyboleto',
+ entry_points = {
+ 'console_scripts':[
+ 'print_boleto_data = pyboleto.scripts.print_sample_data:print_test',
+ ],
+ },
+ classifiers = [
+ 'Development Status :: 2 - Pre-Alpha',
+ 'Operating System :: OS Independent',
+ 'Framework :: Django',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'License :: OSI Approved :: BSD License',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2.7',
+ 'Topic :: Office/Business :: Financial',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ ],
+)
+
Please sign in to comment.
Something went wrong with that request. Please try again.