class BoletoBanrisul(Boleto): conta_cedente = CustomProperty('conta_cedente', 6) nosso_numero = CustomProperty('nosso_numero', 8) def __init__(self): Boleto.__init__(self) self.codigo_banco = "041" self.logo_image = "logo_banrisul.jpg" @property def campo_livre(self): content = '21%04d%07d%08d40' % (int(self.agencia_cedente), int(self.conta_cedente), int(self.nosso_numero)) return '%s%s' % (content, self._dv_campo_livre(content)) # From http://jrimum.org/bopepo/browser/trunk/src/br/com/nordestefomento/ # jrimum/bopepo/campolivre/AbstractCLBanrisul.java def _dv_campo_livre(self, campo_livre): dv = self.modulo10(campo_livre) while True: rest_mod_11 = self.modulo11(campo_livre + str(dv), 7, 1) if rest_mod_11 != 1: break dv += 1 dv %= 10 return str(dv) + str(11 - rest_mod_11)
class BoletoCaixaSigcb(Boleto): ''' Gera Dados necessários para criação de boleto para o banco Caixa Economica Federal ''' agencia_cedente = CustomProperty('agencia_cedente', 4) conta_cedente = CustomProperty('conta_cedente', 6) nosso_numero = CustomProperty('nosso_numero', 17) def __init__(self): super(BoletoCaixaSigcb, self).__init__() self.codigo_banco = "104" self.local_pagamento = ("Preferencialmente nas Casas Lotéricas e " "Agências da Caixa") self.logo_image = "logo_bancocaixa.jpg" @property def campo_livre(self): # 24 digits content = "%6s%1s%3s%1s%3s%1s%9s" % ( self.conta_cedente.split('-')[0], self.modulo11( self.conta_cedente.split('-')[0]), self.nosso_numero[2:5], self.nosso_numero[0:1], self.nosso_numero[5:8], self.nosso_numero[1:2], self.nosso_numero[8:17]) dv_content = self.modulo11(content) return "%24s%1s" % (content, dv_content) def format_nosso_numero(self): return self.nosso_numero
class BoletoItau(Boleto): '''Implementa Boleto Itaú Gera Dados necessários para criação de boleto para o banco Itau Todas as carteiras com excessão das que utilizam 15 dígitos: (106,107, 195,196,198) ''' # Nosso numero (sem dv) com 8 digitos nosso_numero = CustomProperty('nosso_numero', 8) # Conta (sem dv) com 5 digitos conta_cedente = CustomProperty('conta_cedente', 5) # Agência (sem dv) com 4 digitos agencia_cedente = CustomProperty('agencia_cedente', 4) carteira = CustomProperty('carteira', 3) def __init__(self): super(BoletoItau, self).__init__() self.codigo_banco = "341" self.logo_image = "logo_itau.jpg" self.especie_documento = 'DM' @property def dv_nosso_numero(self): composto = "%4s%5s%3s%8s" % (self.agencia_cedente, self.conta_cedente, self.carteira, self.nosso_numero) return self.modulo10(composto) @property def dv_agencia_conta_cedente(self): agencia_conta = "%s%s" % (self.agencia_cedente, self.conta_cedente) return self.modulo10(agencia_conta) @property def agencia_conta_cedente(self): return "%s/%s-%s" % (self.agencia_cedente, self.conta_cedente, self.dv_agencia_conta_cedente) def format_nosso_numero(self): return "%3s/%8s-%1s" % (self.carteira, self.nosso_numero, self.dv_nosso_numero) @property def campo_livre(self): content = "%3s%8s%1s%4s%5s%1s%3s" % (self.carteira, self.nosso_numero, self.dv_nosso_numero, self.agencia_cedente, self.conta_cedente, self.dv_agencia_conta_cedente, '000' ) return content
class BoletoHsbcComRegistro(Boleto): ''' Gera Dados necessários para criação de boleto para o banco HSBC com registro ''' # Nosso numero (sem dv) sao 10 digitos nosso_numero = CustomProperty('nosso_numero', 10) def __init__(self): super(BoletoHsbcComRegistro, self).__init__() self.codigo_banco = "399" self.logo_image = "logo_bancohsbc.jpg" self.carteira = 'CSB' self.especie_documento = 'PD' @property def dv_nosso_numero(self): resto = self.modulo11(self.nosso_numero, 7, 1) if resto == 0 or resto == 1: return 0 else: return 11 - resto @property def campo_livre(self): content = "%10s%1s%4s%7s001" % (self.nosso_numero, self.dv_nosso_numero, self.agencia_cedente.split('-')[0], self.conta_cedente.split('-')[0]) return content
class BoletoSantander(Boleto): ''' Gera Dados necessários para criação de boleto para o banco Santander ''' nosso_numero = CustomProperty('nosso_numero', 12) #: Também chamado de "ponto de venda" agencia_cedente = CustomProperty('agencia_cedente', 4) #: Também chamdo de código do cedente, se for uma conta de 9 dígitos #: ignorar os 2 primeiros conta_cedente = CustomProperty('conta_cedente', 7) def __init__(self): super(BoletoSantander, self).__init__() self.codigo_banco = "033" self.logo_image = "logo_santander.jpg" self.carteira = '102' # IOS - somente para Seguradoras (Se 7% informar 7, limitado 9%) # Demais clientes usar 0 (zero) self.ios = "0" def format_nosso_numero(self): return "%s-%s" % ( self.nosso_numero, self._dv_nosso_numero() ) def _dv_nosso_numero(self): return str(self.modulo11(self.nosso_numero, 9, 0)) @property def campo_livre(self): content = "".join([ '9', self.conta_cedente, self.nosso_numero, self._dv_nosso_numero(), self.ios, self.carteira, ]) return content
class BoletoCaixa(Boleto): ''' Gera Dados necessários para criação de boleto para o banco Caixa Economica Federal ''' conta_cedente = CustomProperty('conta_cedente', 11) ''' Este numero tem o inicio fixo Carteira SR: 80, 81 ou 82 Carteira CR: 90 (Confirmar com gerente qual usar) ''' nosso_numero = CustomProperty('nosso_numero', 10) def __init__(self): super(BoletoCaixa, self).__init__() self.codigo_banco = "104" self.local_pagamento = "Preferencialmente nas Casas Lotéricas e \ Agências da Caixa" self.logo_image = "logo_bancocaixa.jpg" @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 @property def campo_livre(self): content = "%10s%4s%11s" % (self.nosso_numero, self.agencia_cedente, self.conta_cedente.split('-')[0]) return content def format_nosso_numero(self): return self.nosso_numero + '-' + str(self.dv_nosso_numero)
class BoletoBradesco(Boleto): ''' Gera Dados necessários para criação de boleto para o banco Bradesco ''' nosso_numero = CustomProperty('nosso_numero', 11) agencia_cedente = CustomProperty('agencia_cedente', 4) conta_cedente = CustomProperty('conta_cedente', 7) def __init__(self): super(BoletoBradesco, self).__init__() self.codigo_banco = "237" self.logo_image = "logo_bancobradesco.jpg" self.carteira = '06' def format_nosso_numero(self): return "%s/%s-%s" % (self.carteira, self.nosso_numero, self.dv_nosso_numero) @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 @property def campo_livre(self): content = "%4s%2s%11s%7s%1s" % (self.agencia_cedente.split('-')[0], self.carteira, self.nosso_numero, self.conta_cedente.split('-')[0], '0') return content
class BoletoHsbc(Boleto): ''' Gera Dados necessários para criação de boleto para o banco HSBC ''' numero_documento = CustomProperty('numero_documento', 13) def __init__(self): super(BoletoHsbc, self).__init__() self.codigo_banco = "399" self.logo_image = "logo_bancohsbc.jpg" self.carteira = 'CNR' def format_nosso_numero(self): nosso_numero = self.nosso_numero # Primeiro DV nosso_numero += str(self.modulo11(nosso_numero)) # Cobrança com vencimento = 4 nosso_numero += "4" # Segundo DV sum_params = int(nosso_numero) + int(self.conta_cedente) sum_params += int(self.data_vencimento.strftime('%d%m%y')) sum_params = str(sum_params) nosso_numero += str(self.modulo11(sum_params)) return nosso_numero @property def data_vencimento_juliano(self): data_vencimento = str(self.data_vencimento.timetuple().tm_yday) data_vencimento += str(self.data_vencimento.year)[-1:] return data_vencimento.zfill(4) @property def campo_livre(self): content = "%7s%13s%4s2" % (self.conta_cedente, self.nosso_numero, self.data_vencimento_juliano) return content
class BoletoSicredi(Boleto): ''' Gera Dados necessários para criação de boleto para o Banco Sicredi ''' agencia_cedente = CustomProperty('agencia_cedente', 4) conta_cedente = CustomProperty('conta_cedente', 8) posto = CustomProperty('posto', 2) convenio = CustomProperty('convenio', 4) # Nosso numero (sem dv) com 8 digitos nosso_numero = CustomProperty('nosso_numero', 8) def __init__(self): ''' Construtor para boleto do Banco Sicredi Args: format_convenio Formato do convenio 6, 7 ou 8 format_nnumero Formato nosso numero 1 ou 2 ''' super(BoletoSicredi, self).__init__() self.codigo_banco = "748" self.carteira = 3 self.posto = "05" self.logo_image = "logo_sicredi.jpg" # Size of convenio 6, 7 or 8 self.format_convenio = 5 # Nosso Numero format. 1 or 2 # 1: Nosso Numero with 5 positions # 2: Nosso Numero with 17 positions self.format_nnumero = 1 # self.nosso_numero def format_ano(self): ano = str(self.data_vencimento.strftime('%y')) ano = ano.zfill(2) return ano def format_nosso_numero(self): # 14 ano + 2 : Nosso Número deve ser apresentado no formato # AA/BXXXXX-D, onde: return "%s/2%s-%s" % (self.format_ano(), self.nosso_numero, self.dv_nosso_numero) # Nosso numero (sem dv) sao 11 digitos def _get_nosso_numero(self): return self._nosso_numero def _set_nosso_numero(self, val): val = str(val) if self.format_convenio == 5: if self.format_nnumero == 1: nn = val.zfill(5) elif self.format_nnumero == 2: nn = val.zfill(17) elif self.format_convenio == 7: nn = val.zfill(10) elif self.format_convenio == 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).rjust(self.format_convenio, '0') convenio = property(_get_convenio, _set_convenio) @property def agencia_conta_cedente(self): return "%s.%s.%s" % (self.agencia_cedente, self.posto, self.convenio) @property def dv_nosso_numero(self): dv = "%s%s%s%s2%s" % (self.agencia_cedente, self.posto, self.convenio, self.format_ano(), self.nosso_numero) dv = self.modulo11(dv) return dv @property def campo_livre(self): content = str("") if self.format_nnumero == 1: # "3027050000414205586") # 14 ano + 2 : Nosso Número deve ser apresentado no formato # AA/BXXXXX-D, onde: content = "%s1%s2%s%s%s%s%s10" % (self.carteira, self.format_ano( ), self.nosso_numero, self.dv_nosso_numero, self.agencia_cedente, self.posto, self.convenio) n = self.modulo11(content) if n > 9: n = 1 content += str(n) return str(content) @property def codigo_dv_banco(self): cod = "%s-X" % self.codigo_banco return cod
class BoletoBB(Boleto): ''' Gera Dados necessários para criação de boleto para o Banco do Brasil ''' agencia_cedente = CustomProperty('agencia_cedente', 4) conta_cedente = CustomProperty('conta_cedente', 8) def __init__(self, format_convenio, format_nnumero): ''' Construtor para boleto do Banco deo Brasil Args: format_convenio Formato do convenio 4, 6, 7 ou 8 format_nnumero Formato nosso numero 1 ou 2 (apenas para convenio 6) ''' super(BoletoBB, self).__init__() self.codigo_banco = "001" self.carteira = 18 self.logo_image = "logo_bb.jpg" # Size of convenio 4, 6, 7 or 8 self.format_convenio = format_convenio # Nosso Numero format. 1 or 2 # Used only for convenio=6 # 1: Nosso Numero with 5 positions # 2: Nosso Numero with 17 positions self.format_nnumero = format_nnumero self._convenio = "" self._nosso_numero = "" def format_nosso_numero(self): if self.format_convenio == 7: return "%7s%10s" % (self.convenio, self.nosso_numero) else: return "%s%s-%s" % (self.convenio, self.nosso_numero, self.dv_nosso_numero) # Nosso numero (sem dv) sao 11 digitos def _get_nosso_numero(self): return self._nosso_numero def _set_nosso_numero(self, val): val = str(val) if self.format_convenio == 4: nn = val.zfill(7) elif self.format_convenio == 6: if self.format_nnumero == 1: nn = val.zfill(5) elif self.format_nnumero == 2: nn = val.zfill(17) elif self.format_convenio == 7: nn = val.zfill(10) elif self.format_convenio == 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): ''' This function uses a modified version of modulo11 ''' num = self.convenio + self.nosso_numero base = 2 fator = 9 soma = 0 for c in reversed(num): soma += int(c) * fator if fator == base: fator = 10 fator -= 1 r = soma % 11 if r == 10: return 'X' return r @property def campo_livre(self): if self.format_convenio == 4: content = "%s%s%s%s%s" % (self.convenio, self.nosso_numero, self.agencia_cedente, self.conta_cedente, self.carteira) elif self.format_convenio in (7, 8): content = "000000%s%s%s" % (self.convenio, self.nosso_numero, self.carteira) elif self.format_convenio == 6: if self.format_nnumero == 1: content = "%s%s%s%s%s" % (self.convenio, self.nosso_numero, self.agencia_cedente, self.conta_cedente, self.carteira) if self.format_nnumero == 2: content = "%s%s%s" % (self.convenio, self.nosso_numero, '21' ) # numero do serviço return content
class Boleto(object): """Interface para implementações específicas de bancos Esta classe geralmente nunca será usada diretamente. Geralmente o usuário irá usar uma das subclasses com a implementação específica de cada banco. As classes dentro do pacote :mod:`pyboleto.bank` extendem essa classe para implementar as especificações de cada banco. Portanto as especificações dentro desta classe são genéricas seguindo as normas da FEBRABAN. Todos os parâmetros devem ser passados como ``**kwargs`` para o construtor ou então devem ser passados depois, porém antes de imprimir o boleto. eg:: bData = Boleto(agencia='123', valor='650') bData.cedente = u'João Ninguém' bData.cedente_cidade = u'Rio de Janeiro' bData.cedente_uf = u'RJ' # Assim por diante até preencher todos os campos obrigatórios. **Parâmetros obrigatórios**: :param aceite: 'N' para o caixa não acetitar o boleto após a validade ou 'A' para aceitar. *(default: 'N')* :param agencia_cedente: Tamanho pode variar com o banco. :param carteira: Depende do Banco. :param cedente: Nome do Cedente :param cedente_cidade: :param cedente_uf: :param cedente_logradouro: Endereço do Cedente :param cedente_bairro: :param cedente_cep: :param cedente_documento: CPF ou CNPJ do Cedente. :param conta_cedente: Conta do Cedente sem o dígito verificador. :param data_documento: :type data_documento: `datetime.date` :param data_processamento: :type data_processamento: `datetime.date` :param data_vencimento: :type data_vencimento: `datetime.date` :param numero_documento: Número Customizado para controle. Pode ter até 13 caracteres dependendo do banco. :param sacado_nome: Nome do Sacado :param sacado_documento: CPF ou CNPJ do Sacado :param sacado_cidade: :param sacado_uf: :param sacado_endereco: Endereco do Sacado :param sacado_bairro: :param sacado_cep: **Parâmetros não obrigatórios**: :param quantidade: :param especie: Nunca precisa mudar essa opção *(default: 'R$')* :param especie_documento: :param local_pagamento: *(default: 'Pagável em qualquer banco até o vencimento')* :param moeda: Nunca precisa mudar essa opção *(default: '9')* """ nosso_numero = CustomProperty('nosso_numero', 13) """Nosso Número geralmente tem 13 posições Algumas subclasses podem alterar isso dependendo das normas do banco """ agencia_cedente = CustomProperty('agencia_cedente', 4) """Agência do Cedente geralmente tem 4 posições Algumas subclasses podem alterar isso dependendo das normas do banco """ conta_cedente = CustomProperty('conta_cedente', 7) """Conta do Cedente geralmente tem 7 posições Algumas subclasses podem alterar isso dependendo das normas do banco """ def __init__(self, **kwargs): # otherwise the printed value might diffent from the value in # the barcode. self.aceite = kwargs.pop('aceite', "N") self.agencia_cedente = kwargs.pop('agencia_cedente', "") self.carteira = kwargs.pop('carteira', "") self.cedente = kwargs.pop('cedente', "") self.cedente_cidade = kwargs.pop('cedente_cidade', "") self.cedente_uf = kwargs.pop('cedente_uf', "") self.cedente_logradouro = kwargs.pop('cedente_logradouro', "") self.cedente_bairro = kwargs.pop('cedente_bairro', "") self.cedente_cep = kwargs.pop('cedente_cep', "") self.cedente_documento = kwargs.pop('cedente_documento', "") self.codigo_banco = kwargs.pop('codigo_banco', "") self.conta_cedente = kwargs.pop('conta_cedente', "") self.data_documento = kwargs.pop('data_documento', "") self.data_processamento = kwargs.pop('data_processamento', datetime.date.today()) self.data_vencimento = kwargs.pop('data_vencimento', "") self.especie = kwargs.pop('especie', "R$") self.especie_documento = kwargs.pop('especie_documento', "") self.local_pagamento = kwargs.pop( 'local_pagamento', "Pagável em qualquer banco até o vencimento") self.logo_image = kwargs.pop('logo_image', "") self.moeda = kwargs.pop('moeda', "9") self.numero_documento = kwargs.pop('numero_do_documento', "") self.quantidade = kwargs.pop('quantidade', "") self.sacado_nome = kwargs.pop('sacado_nome', "") self.sacado_documento = kwargs.pop('sacado_documento', "") self.sacado_cidade = kwargs.pop('sacado_cidade', "") self.sacado_uf = kwargs.pop('sacado_uf', "") self.sacado_endereco = kwargs.pop('sacado_endereco', "") self.sacado_bairro = kwargs.pop('sacado_bairro', "") self.sacado_cep = kwargs.pop('sacado_cep', "") if kwargs: raise TypeError("Paramêtro(s) desconhecido: %r" % (kwargs, )) self._cedente_endereco = None self._demonstrativo = [] self._instrucoes = [] self._sacado = None self._valor = None self._valor_documento = None @property def barcode(self): """Essa função sempre é a mesma para todos os bancos. Então basta implementar o método :func:`barcode` para o pyboleto calcular a linha digitável. Posição # Conteúdo 01 a 03 03 Número do banco 04 01 Código da Moeda - 9 para Real 05 01 Digito verificador do Código de Barras 06 a 09 04 Data de vencimento em dias partis de 07/10/1997 10 a 19 10 Valor do boleto (8 inteiros e 2 decimais) 20 a 44 25 Campo Livre definido por cada banco Total 44 """ for attr, length, data_type in [ ('codigo_banco', 3, str), ('moeda', 1, str), ('data_vencimento', None, datetime.date), ('valor_documento', -1, str), ('campo_livre', 25, str), ]: value = getattr(self, attr) if not isinstance(value, data_type): raise TypeError( "%s.%s must be a %s, got %r (type %s)" % (self.__class__.__name__, attr, data_type.__name__, value, type(value).__name__)) if (data_type == str and length != -1 and len(value) != length): raise ValueError( "%s.%s must have a length of %d, not %r (len: %d)" % (self.__class__.__name__, attr, length, value, len(value))) due_date_days = (self.data_vencimento - _EPOCH).days if not (9999 >= due_date_days >= 0): raise TypeError("Invalid date, must be between 1997/07/01 and " "2024/11/15") num = "%s%1s%04d%010d%24s" % ( self.codigo_banco, self.moeda, due_date_days, Decimal(self.valor_documento) * 100, self.campo_livre) dv = self.calculate_dv_barcode(num) barcode = num[:4] + str(dv) + num[4:] if len(barcode) != 44: raise BoletoException( 'The barcode must have 44 characteres, found %d' % len(barcode)) return barcode @property def campo_livre(self): """Must be overriden by child class property :exception NotImplementedError: Needs to be implemented by derived class """ raise NotImplementedError( 'This method has not been implemented by this class') def calculate_dv_barcode(self, line): """Calcula DV para código de barras Está é uma implementação genérica mas pode ser reimplementada pela classe derivada dependendo das definições de cada bancoGeralmente é implementado pela classe derivada. """ 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): """ Geralmente é implementado pela classe derivada. Usada para formatar como o noso número será impresso no boleto. Às vezes é o mesmo do `numero_documento` e às vezes contém outros campos juntos. """ return self.nosso_numero def _cedente_endereco_get(self): if self._cedente_endereco is None: self._cedente_endereco = '%s - %s - %s - %s - %s' % ( self.cedente_logradouro, self.cedente_bairro, self.cedente_cidade, self.cedente_uf, self.cedente_cep) return self._cedente_endereco def _cedente_endereco_set(self, endereco): if len(endereco) > 80: raise BoletoException( u'Linha de endereço possui mais que 80 caracteres') self._cedente_endereco = endereco cedente_endereco = property(_cedente_endereco_get, _cedente_endereco_set) """Endereço do Cedente com no máximo 80 caracteres""" def _get_valor(self): if self._valor is not None: return "%.2f" % self._valor def _set_valor(self, val): if type(val) is Decimal: self._valor = val else: self._valor = Decimal(str(val)) valor = property(_get_valor, _set_valor) """Valor convertido para :class:`Decimal`. Geralmente valor e valor_documento são o mesmo número. :type: Decimal """ def _get_valor_documento(self): if self._valor_documento is not None: return "%.2f" % self._valor_documento def _set_valor_documento(self, val): if type(val) is Decimal: self._valor_documento = val else: self._valor_documento = Decimal(str(val)) valor_documento = property(_get_valor_documento, _set_valor_documento) """Valor do Documento convertido para :class:`Decimal`. De preferência para passar um valor em :class:`Decimal`, se não for passado outro tipo será feito um cast para :class:`Decimal`. """ def _instrucoes_get(self): return self._instrucoes def _instrucoes_set(self, list_inst): if isinstance(list_inst, str): list_inst = list_inst.splitlines() 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) """Instruções para o caixa do banco que recebe o bilhete Máximo de 7 linhas com 90 caracteres cada. Geralmente contém instruções para aplicar multa ou não aceitar caso tenha passado a data de validade. """ def _demonstrativo_get(self): return self._demonstrativo def _demonstrativo_set(self, list_dem): if isinstance(list_dem, str): list_dem = list_dem.splitlines() 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) """Texto que vai impresso no corpo do Recibo do Sacado Máximo de 12 linhas com 90 caracteres cada. """ def _sacado_get(self): """Tenta usar o sacado que foi setado ou constroi um Se você não especificar um sacado o boleto tentará construir um sacado a partir de outras proriedades setadas. Para facilitar você deve sempre setar essa propriedade. """ if self._sacado is None: self.sacado = [ '%s - CPF/CNPJ: %s' % (self.sacado_nome, self.sacado_documento), 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') self._sacado = list_sacado sacado = property(_sacado_get, _sacado_set) """Campo sacado composto por até 3 linhas. A primeira linha precisa ser o nome do sacado. As outras duas linhas devem ser usadas para o endereço do sacado. """ @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 digitável a partir do barcode Esta é a linha que o cliente pode utilizar para digitar se o código de barras não estiver legível. """ linha = self.barcode if not linha: raise BoletoException("Boleto doesn't have a barcode") def monta_campo(campo): campo_dv = "%s%s" % (campo, self.modulo10(campo)) return "%s.%s" % (campo_dv[0:5], campo_dv[5:]) return ' '.join([ monta_campo(linha[0:4] + linha[19:24]), monta_campo(linha[24:34]), monta_campo(linha[34:44]), linha[4], linha[5:19] ]) @staticmethod def modulo11(num, base=9, r=0): return modulo11(num, base, r) @staticmethod def modulo10(num): return modulo10(num)