module ActsAsBoleto def self.included(base) base.extend ClassMethods end module ClassMethods def acts_as_boleto extend ActsAsBoleto::SingletonMethods include ActsAsBoleto::InstanceMethods end end module SingletonMethods end module InstanceMethods def gera_boleto codigobanco = @dadosboleto[:banco] nummoeda = "9" fator_vencimento = fator_vencimento(@dadosboleto[:data_vencimento]) # Linha digitavel # valor tem 10 digitos, sem virgula valor = formata_numero(@dadosboleto[:valor_boleto],10,0,"valor") # convenio tem 6 digitos convenio = formata_numero(@dadosboleto[:convenio],6,0,"convenio") # agencia é sempre 4 digitos agencia = formata_numero(@dadosboleto[:agencia],4,0) # conta é sempre 8 digitos conta = formata_numero(@dadosboleto[:conta],8,0) carteira = @dadosboleto[:carteira] if (@dadosboleto[:formatacao_nosso_numero] == "1") # 12 dígitos nossonumero = formata_numero(@dadosboleto[:nosso_numero],5,0) dv = modulo_11("#{codigobanco}#{nummoeda}#{fator_vencimento}#{valor}#{convenio}#{nossonumero}#{agencia}#{conta}#{carteira}") linha = "#{codigobanco}#{nummoeda}#{dv}#{fator_vencimento}#{valor}#{convenio}#{nossonumero}#{agencia}#{conta}#{carteira}" # recolocando o nosso numero com DV nossonumero = convenio.to_s + nossonumero.to_s + "-" + modulo_11("#{convenio}#{nossonumero}").to_s agencia_codigo = "#{agencia}-#{modulo_11(agencia)} / #{conta}-#{modulo_11(conta)}" end if (@dadosboleto[:formatacao_nosso_numero] == "2") # 17 dígitos nservico = "21" nossonumero = formata_numero(@dadosboleto[:nosso_numero],17,0) dv = modulo_11("#{codigobanco}#{nummoeda}#{fator_vencimento}#{valor}#{convenio}#{nossonumero}#{nservico}") linha = "#{codigobanco}#{nummoeda}#{dv}#{fator_vencimento}#{valor}#{convenio}#{nossonumero}#{nservico}" agencia_codigo = agencia + "-" + modulo_11(agencia) + " / " + conta + "-" + modulo_11(conta) end @dadosboleto[:codigo_barras] = linha @dadosboleto[:linha_digitavel] = monta_linha_digitavel(linha) @dadosboleto[:agencia_codigo] = agencia_codigo @dadosboleto[:nosso_numero] = nossonumero end #Fator vencimento, phpboleto def fator_vencimento(data) data = data.split("/",3) ano = data[2] mes = data[1] dia = data[0] return (_dateToDays("1997","10","07").abs - _dateToDays(ano, mes, dia)) end def _dateToDays(year,month,day) month = month.to_i day = day.to_i century = year[0,2].to_i year = year[2, 2].to_i if (month > 2) month -= 3 else month += 9 if (year) year-= 1 else year = 99 century -=1 end end # TODO: converter isso return ( ((146097 * century).to_f / 4 ).to_f + ((1461 * year).to_f / 4 ).to_f + ((153 * month + 2).to_f / 5 ).to_f + day + 1721119).to_f end #retira as virgulas #formata o numero #preenche com zeros def formata_numero(numero,loop,insert,tipo = "geral") numero = numero.to_s insert = insert.to_s if (tipo == "geral") numero = numero.gsub(",","") while numero.size < loop numero = insert + numero end end if tipo == "valor" numero = numero.gsub(",","") while numero.size 9 digito = 1 end end return digito elsif r == 1 resto = soma % 11 return resto end end def monta_linha_digitavel(linha) # 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 inteeeiros e 2 decimais) # 20 a 44 Campo Livre definido por cada banco # 1. Campo - composto pelo código do banco, código da moéda, as cinco primeiras posições # do campo livre e DV (modulo10) deste campo p1 = linha[0, 4] p2 = linha[19, 5] p3 = modulo_10("#{p1}#{p2}") p4 = "#{p1}#{p2}#{p3}" p5 = p4[0, 5] p6 = p4[5,p4.size] campo1 = "#{p5}.#{p6}" # 2. Campo - composto pelas posiçoes 6 a 15 do campo livre # e livre e DV (modulo10) deste campo p1 = linha[24, 10] p2 = modulo_10(p1) p3 = "#{p1}#{p2}" p4 = p3[0, 5] p5 = p3[5,p5.size] campo2 = "#{p4}.#{p5}" # 3. Campo composto pelas posicoes 16 a 25 do campo livre # e livre e DV (modulo10) deste campo p1 = linha[34, 10] p2 = modulo_10(p1) p3 = "#{p1}#{p2}" p4 = p3[0, 5] p5 = p3[5,p3.size] campo3 = "#{p4}.#{p5}" # 4. Campo - digito verificador do codigo de barras campo4 = linha[4, 1] # 5. Campo composto pelo valor nominal pelo valor nominal do documento, sem # indicacao de zeros a esquerda e sem edicao (sem ponto e virgula). Quando se # tratar de valor zerado, a representacao deve ser 000 (tres zeros). campo5 = linha[5, 14] return "#{campo1} #{campo2} #{campo3} #{campo4} #{campo5}" end end end