# encoding: utf-8 module BoletoBancario module Core # Implementação de emissão de boleto bancário pelo Bradesco. # # === Documentação Implementada # # A documentação na qual essa implementação foi baseada está localizada na pasta # 'documentacoes_dos_boletos/bradesco' dentro dessa biblioteca. # # === Contrato das classes de emissão de boletos # # Para ver o "contrato" da Emissão de Boletos (geração de código de barras, linha digitável, etc) veja # a classe BoletoBancario::Core::Boleto. # # === Carteiras suportadas # # Segue abaixo as carteiras suportadas do bradesco seguindo a documentação: # # _________________________________________________________________________ # | Carteira | Descrição | Testada/Homologada no banco | # | 03 | Sem registro | Esperando Contribuição | # | 06 | Sem registro | Esperando Contribuição | # | 09 | Com registro | Esperando Contribuição | # | 19 | Com registro | Esperando Contribuição | # | 21 | Cobrança Interna com registro | Esperando Contribuição | # | 22 | Cobrança Interna sem registro | Esperando Contribuição | # -------------------------------------------------------------------------- # # OBS.: Seja um contribuidor dessa gem. Contribua para homologar os boletos e as # devidas carteiras junto ao banco Bradesco. # # === Exemplos # # O recomendado é criar uma subclasse de BoletoBancario::Bradesco # # class Bradesco < BoletoBancario::Bradesco # end # # E a partir daí usar a sua classe para emitir o boleto: # # Bradesco.new do |boleto| # boleto.conta_corrente = '89755' # boleto.agencia = '0097' # boleto.carteira = '03' # boleto.numero_documento = '12345678' # boleto.codigo_cedente = '909014' # end # # === Validações # # A classe Bradesco possui suas próprias validações. # Primeiramente, antes de renderizar qualquer boleto você precisar verificar se esse boleto é válido: # # @bradesco = Bradesco.new # if @bradesco.valid? # # render @bradesco # else # # ... # end # # Se você quiser sobrescrever alguma validação dessa classe a gem de boleto bancário # possui alguns modos de fazer isso. # # === Sobrescrevendo validações # # Caso você precise mudar as validações, você pode sobrescrever alguns métodos que possuem "Magic numbers". # Foi colocado dessa forma, já que os bancos mudam bastante esse tipo de validação. # Por exemplo, atualmente a conta corrente é validado com '5' como máximo de tamanho. # Caso você queira que valide como 6, mude conforme abaixo: # # class Bradesco < BoletoBancario::Bradesco # def self.tamanho_maximo_conta_corrente # 6 # end # end # # Obs.: Mudar as regras de validação podem influenciar na emissão do boleto em si. # Você precisará analisar o efeito no #codigo_de_barras, #nosso_numero e na # #linha_digitável (ambos podem ser sobreescritos também). # # Caso exista algum cenário de sobrescrita de validação contate o dono dessa gem pelo github e conte um # pouco mais sobre esses cenários. # class Bradesco < Boleto # Tamanho máximo de uma conta corrente no Banco Bradesco. # Método criado justamente para ficar documentado o tamanho máximo aceito até a data corrente. # # @return [Fixnum] 7 # def self.tamanho_maximo_conta_corrente 7 end # Tamanho máximo de uma agência no Banco Bradesco. # Método criado justamente para ficar documentado o tamanho máximo aceito até a data corrente. # # @return [Fixnum] 4 # def self.tamanho_maximo_agencia 4 end # Tamanho máximo do número do documento emitido no Boleto. # O tamanho máximo é justamente 8 porque no código de barras só é permitido 8 posições para este campo. # # Método criado justamente para ficar documentado o tamanho máximo aceito até a data corrente. # # @return [Fixnum] 11 # def self.tamanho_maximo_numero_documento 11 end # Carteiras suportadas. # # Método criado para validar se a carteira informada é suportada. # # @return [Array] # def self.carteiras_suportadas %w[03 06 09 19 21 22] end validates :agencia, :digito_agencia, :conta_corrente, :digito_conta_corrente, presence: true # Validações para os campos abaixo: # # * Agencia # * Conta corrente # * Número do documento # * Carteira # # Se você quiser sobrescrever os metodos, ficará a sua responsabilidade. # Basta você sobrescrever os métodos de validação: # # class Bradesco < BoletoBancario::Core::Bradesco # def self.tamanho_maximo_agencia # 5 # end # # def self.tamanho_maximo_conta_corrente # 6 # end # # def self.tamanho_maximo_numero_documento # 9 # end # # def self.carteiras_suportadas # %w[03 06 09 19 21 22] # end # end # # Obs.: Mudar as regras de validação podem influenciar na emissão do boleto em si. # Você precisará analisar o efeito no #codigo_de_barras, #nosso_numero e na # #linha_digitável (ambos podem ser sobreescritos também). # validates :agencia, length: { maximum: tamanho_maximo_agencia }, if: :deve_validar_agencia? validates :conta_corrente, length: { maximum: tamanho_maximo_conta_corrente }, if: :deve_validar_conta_corrente? validates :numero_documento, length: { maximum: tamanho_maximo_numero_documento }, if: :deve_validar_numero_documento? validates :carteira, inclusion: { in: ->(object) { object.class.carteiras_suportadas } }, if: :deve_validar_carteira? # @return [String] 7 caracteres # def conta_corrente @conta_corrente.to_s.rjust(7, '0') if @conta_corrente.present? end # @return [String] 4 caracteres # def agencia @agencia.to_s.rjust(4, '0') if @agencia.present? end # @return [String] 11 caracteres # def numero_documento @numero_documento.to_s.rjust(11, '0') if @numero_documento.present? end # @return [String] 2 caracteres # def carteira @carteira.to_s.rjust(2, '0') if @carteira.present? end # Número da Carteira de Cobrança, que a empresa opera no Banco. # No caso da Cobrança Interna será: # # 21 – Cobrança Interna Com Registro # 22 – Cobrança Interna sem registro # # Para as demais carteiras, retornar o número da carteira. # def carteira_formatada if cobranca_interna_formatada.present? cobranca_interna_formatada else carteira end end # @return [String] Código do Banco descrito na documentação. # def codigo_banco '237' end # Dígito do código do banco. Precisa mostrar esse dígito no boleto. # # @return [String] Dígito do código do banco descrito na documentação. # def digito_codigo_banco '2' end # Dígito do código da agência. Precisa mostrar esse dígito no boleto. # # @return [String] Dígito da agência calculado usando o Modulo11FatorDe9a2. # def digito_agencia Modulo11FatorDe9a2.new(agencia) end # Dígito da conta corrente. Precisa mostrar esse dígito no boleto. # # @return [String] Dígito da conta corrente calculado apartir do Modulo11FatorDe9a2. # def digito_conta_corrente Modulo11FatorDe9a2.new(conta_corrente) end # Campo preenchido com: # # - Agência com 4 caracteres - digito da agência / Conta de Cobrança com 7 caracteres - Digito da Conta # # Exemplo: 9999-D/9999999-D # # Obs.: Preencher com zeros a Esquerda quando necessário. # # @return [String] Agência e Código do Cedente que será exibido no boleto # def agencia_codigo_cedente "#{agencia}-#{digito_agencia} / #{conta_corrente}-#{digito_conta_corrente}" end # Nosso Número descrito na documentação (Pag. 53). # # Carteira com 2 (dois) caracteres / N.Número com 11 (onze) caracteres + digito. # # Exemplo: 99 / 99999999999-D # def nosso_numero "#{carteira}/#{numero_documento}-#{digito_nosso_numero}" end # Para o cálculo do dígito, será necessário acrescentar o número da carteira à esquerda # antes do Nosso Número (número do documento), e aplicar o módulo 11, com fatores de 2 a 7. # # Para mais detalhes de como o cálculo é feito veja a classe Modulo11FatorDe2a7. # # @return [String] Retorno do cálculo do módulo 11 na base 7 (2,3,4,5,6,7) # def digito_nosso_numero Modulo11FatorDe2a7.new("#{carteira}#{numero_documento}") end # === Código de barras do banco # # ___________________________________________________________________________________________________ # | Posição | Tamanho | Descrição | # |----------|---------|-----------------------------------------------------------------------------| # | 20-23 | 04 | Agência (Sem o digito, completar com zeros a esquerda se necessário) | # | 24-25 | 02 | Carteira | # | 26-36 | 11 | Número do Documento - Número do Nosso Número (Sem o digito verificador) | # | 37-43 | 07 | Conta Corrente (Sem o digito, completar com zeros a esquerda se necessário) | # | 44 | 01 | Zero | # ---------------------------------------------------------------------------------------------------- # def codigo_de_barras_do_banco "#{agencia}#{carteira}#{numero_documento}#{conta_corrente}0" end # @api private # Retorna a mensagem que devera aparecer no campo carteira para cobranca interna. # # @return [String] # def cobranca_interna_formatada cobranca_interna = { '21' => '21 – Cobrança Interna Com Registro', '22' => '22 – Cobrança Interna sem registro' } cobranca_interna[carteira.to_s] end end end end