Source code for pyboleto.data

# -*- coding: utf-8 -*-
import datetime
import re
from decimal import Decimal

[docs]class BoletoException(Exception): def __init__(self, message ): Exception.__init__(self, message)
[docs]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 )
[docs]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
[docs] 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
[docs] 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' )
[docs] 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
[docs] 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
[docs] 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
[docs] def agencia_conta_cedente(self): return "%s/%s" % (self.agencia_cedente, self.conta_cedente)
@property
[docs] def codigo_dv_banco(self): cod = "%s-%s" % (self.codigo_banco, self.modulo11(self.codigo_banco)) return cod
@property
[docs] 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
[docs] 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
[docs] 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)
[docs] def formata_valor(self,nfloat, tamanho): try: txt = nfloat.replace( '.', '' ) txt = self.formata_numero(txt, tamanho) return txt except AttributeError: pass
@staticmethod
[docs] 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
[docs] 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

Project Versions