kivanio-brcobranca 2.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +21 -0
- data/Manifest.txt +48 -0
- data/README.rdoc +72 -0
- data/Rakefile +32 -0
- data/brcobranca.gemspec +47 -0
- data/lib/brcobranca/arquivos/logos/bb.jpg +0 -0
- data/lib/brcobranca/arquivos/logos/bradesco.jpg +0 -0
- data/lib/brcobranca/arquivos/logos/hsbc.jpg +0 -0
- data/lib/brcobranca/arquivos/logos/itau.jpg +0 -0
- data/lib/brcobranca/arquivos/logos/real.jpg +0 -0
- data/lib/brcobranca/arquivos/logos/unibanco.jpg +0 -0
- data/lib/brcobranca/arquivos/templates/modelo_generico.eps +0 -0
- data/lib/brcobranca/boleto/banco_bradesco.rb +31 -0
- data/lib/brcobranca/boleto/banco_brasil.rb +79 -0
- data/lib/brcobranca/boleto/banco_hsbc.rb +63 -0
- data/lib/brcobranca/boleto/banco_itau.rb +105 -0
- data/lib/brcobranca/boleto/banco_real.rb +56 -0
- data/lib/brcobranca/boleto/banco_unibanco.rb +65 -0
- data/lib/brcobranca/boleto/base.rb +148 -0
- data/lib/brcobranca/boleto/template/rghost.rb +151 -0
- data/lib/brcobranca/boleto/template/util.rb +30 -0
- data/lib/brcobranca/config.rb +9 -0
- data/lib/brcobranca/core_ext.rb +269 -0
- data/lib/brcobranca/currency.rb +70 -0
- data/lib/brcobranca/retorno/base.rb +43 -0
- data/lib/brcobranca/retorno/retorno_cbr643.rb +44 -0
- data/lib/brcobranca.rb +27 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +71 -0
- data/test/arquivos/CBR64310.RET +28 -0
- data/test/test_banco_bradesco.rb +87 -0
- data/test/test_banco_brasil.rb +276 -0
- data/test/test_banco_hsbc.rb +81 -0
- data/test/test_banco_itau.rb +103 -0
- data/test/test_banco_real.rb +112 -0
- data/test/test_banco_unibanco.rb +92 -0
- data/test/test_base.rb +162 -0
- data/test/test_core_ext.rb +227 -0
- data/test/test_currency.rb +51 -0
- data/test/test_helper.rb +5 -0
- data/test/test_retorno_cbr643.rb +66 -0
- data/website/index.html +89 -0
- data/website/index.txt +46 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +159 -0
- data/website/template.html.erb +57 -0
- metadata +164 -0
@@ -0,0 +1,148 @@
|
|
1
|
+
module Brcobranca
|
2
|
+
module Boleto
|
3
|
+
# Classe base para todas as classes de boletos
|
4
|
+
class Base
|
5
|
+
# <b>REQUERIDO</b>: Codigo do banco emissor (3 dígitos sempre)
|
6
|
+
attr_accessor :banco
|
7
|
+
# <b>REQUERIDO</b>: Número do convênio/contrato do cliente junto ao banco emissor
|
8
|
+
attr_accessor :convenio
|
9
|
+
# <b>REQUERIDO</b>: Tipo de moeda utilizada (Real(R$) e igual a 9)
|
10
|
+
attr_accessor :moeda
|
11
|
+
# <b>REQUERIDO</b>: Carteira utilizada
|
12
|
+
attr_accessor :carteira
|
13
|
+
# <b>OPCIONAL</b>: Variacao da carteira(opcional para a maioria dos bancos)
|
14
|
+
attr_accessor :variacao
|
15
|
+
# <b>OPCIONAL</b>: Data de processamento do boleto, geralmente igual a data_documento
|
16
|
+
attr_accessor :data_processamento
|
17
|
+
# <b>REQUERIDO</b>: Número de dias a vencer
|
18
|
+
attr_accessor :dias_vencimento
|
19
|
+
# <b>REQUERIDO</b>: Quantidade de boleto(padrão = 1)
|
20
|
+
attr_accessor :quantidade
|
21
|
+
# <b>REQUERIDO</b>: Valor do boleto
|
22
|
+
attr_accessor :valor
|
23
|
+
# <b>REQUERIDO</b>: Número da agencia
|
24
|
+
attr_accessor :agencia
|
25
|
+
# <b>REQUERIDO</b>: Número da conta corrente
|
26
|
+
attr_accessor :conta_corrente
|
27
|
+
# <b>REQUERIDO</b>: Nome do proprietario da conta corrente
|
28
|
+
attr_accessor :cedente
|
29
|
+
# <b>REQUERIDO</b>: Documento do proprietario da conta corrente (CPF ou CNPJ)
|
30
|
+
attr_accessor :documento_cedente
|
31
|
+
# <b>OPCIONAL</b>: Número sequencial utilizado identificar o boleto
|
32
|
+
attr_accessor :numero_documento
|
33
|
+
# <b>REQUERIDO</b>: Símbolo da moeda utilizada (R$ no brasil)
|
34
|
+
attr_accessor :especie
|
35
|
+
# <b>REQUERIDO</b>: Tipo do documento (Geralmente DM que quer dizer Duplicata Mercantil)
|
36
|
+
attr_accessor :especie_documento
|
37
|
+
# <b>REQUERIDO</b>: Data em que foi emitido o boleto
|
38
|
+
attr_accessor :data_documento
|
39
|
+
# <b>OPCIONAL</b>: Código utilizado para identificar o tipo de serviço cobrado
|
40
|
+
attr_accessor :codigo_servico
|
41
|
+
# <b>OPCIONAL</b>: Utilizado para mostrar alguma informação ao sacado
|
42
|
+
attr_accessor :instrucao1
|
43
|
+
# <b>OPCIONAL</b>: Utilizado para mostrar alguma informação ao sacado
|
44
|
+
attr_accessor :instrucao2
|
45
|
+
# <b>OPCIONAL</b>: Utilizado para mostrar alguma informação ao sacado
|
46
|
+
attr_accessor :instrucao3
|
47
|
+
# <b>OPCIONAL</b>: Utilizado para mostrar alguma informação ao sacado
|
48
|
+
attr_accessor :instrucao4
|
49
|
+
# <b>OPCIONAL</b>: Utilizado para mostrar alguma informação ao sacado
|
50
|
+
attr_accessor :instrucao5
|
51
|
+
# <b>OPCIONAL</b>: Utilizado para mostrar alguma informação ao sacado
|
52
|
+
attr_accessor :instrucao6
|
53
|
+
# <b>OPCIONAL</b>: Utilizado para mostrar alguma informação ao sacado
|
54
|
+
attr_accessor :instrucao7
|
55
|
+
# <b>REQUERIDO</b>: Informação sobre onde o sacado podera efetuar o pagamento
|
56
|
+
attr_accessor :local_pagamento
|
57
|
+
# <b>REQUERIDO</b>: Informa se o banco deve aceitar o boleto após o vencimento ou não( S ou N, quase sempre S)
|
58
|
+
attr_accessor :aceite
|
59
|
+
# <b>REQUERIDO</b>: Nome da pessoa que receberá o boleto
|
60
|
+
attr_accessor :sacado
|
61
|
+
# <b>OPCIONAL</b>: Endereco da pessoa que receberá o boleto
|
62
|
+
attr_accessor :sacado_endereco
|
63
|
+
# <b>REQUERIDO</b>: Documento da pessoa que receberá o boleto
|
64
|
+
attr_accessor :sacado_documento
|
65
|
+
|
66
|
+
# Responsável por definir dados iniciais quando se cria uma nova intância da classe Base.
|
67
|
+
def initialize(campos={})
|
68
|
+
padrao = { :moeda => "9", :data_documento => Date.today, :dias_vencimento => 1, :quantidade => 1,
|
69
|
+
:especie_documento => "DM", :especie => "R$", :aceite => "S", :valor => 0.0,
|
70
|
+
:local_pagamento => "QUALQUER BANCO ATÉ O VENCIMENTO"}
|
71
|
+
|
72
|
+
campos = padrao.merge!(campos)
|
73
|
+
campos.each do |campo, valor|
|
74
|
+
instance_variable_set "@#{campo}", valor if self.respond_to?(campo)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Retorna dígito verificador do banco, calculado com modulo11 de 9 para 2
|
79
|
+
def banco_dv
|
80
|
+
self.banco.modulo11_9to2
|
81
|
+
end
|
82
|
+
|
83
|
+
# Retorna dígito verificador da agência, calculado com modulo11 de 9 para 2
|
84
|
+
def agencia_dv
|
85
|
+
self.agencia.modulo11_9to2
|
86
|
+
end
|
87
|
+
|
88
|
+
# Retorna dígito verificador da conta corrente, calculado com modulo11 de 9 para 2
|
89
|
+
def conta_corrente_dv
|
90
|
+
self.conta_corrente.modulo11_9to2
|
91
|
+
end
|
92
|
+
|
93
|
+
# Retorna dígito verificador do nosso número, calculado com modulo11 de 9 para 2
|
94
|
+
def nosso_numero_dv
|
95
|
+
self.numero_documento.modulo11_9to2
|
96
|
+
end
|
97
|
+
|
98
|
+
# Número sequencial utilizado para distinguir os boletos na agência
|
99
|
+
def nosso_numero
|
100
|
+
self.numero_documento
|
101
|
+
end
|
102
|
+
|
103
|
+
# Retorna o valor total do documento: <b>quantidate * valor</b> ou <b>zero(0)</b> caso não consiga efetuar o cálculo.
|
104
|
+
def valor_documento
|
105
|
+
begin
|
106
|
+
self.quantidade * self.valor.to_f
|
107
|
+
rescue
|
108
|
+
0
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Retorna data de vencimento baseado na <b>data_documento + dias_vencimento</b> ou <b>false</b> caso não consiga efetuar o cálculo.
|
113
|
+
def data_vencimento
|
114
|
+
begin
|
115
|
+
return false unless self.data_documento.kind_of?(Date)
|
116
|
+
(self.data_documento + self.dias_vencimento.to_i)
|
117
|
+
rescue
|
118
|
+
false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Retorna uma String com 44 caracteres representando o codigo de barras do boleto
|
123
|
+
# O código de barra para cobrança contém 44 posições dispostas da seguinte forma:
|
124
|
+
# Posição Tamanho Conteúdo
|
125
|
+
# 01 a 03 3 Identificação do Banco
|
126
|
+
# 04 a 04 1 Código da Moeda (Real = 9, Outras=0)
|
127
|
+
# 05 a 05 1 Dígito verificador do Código de Barras
|
128
|
+
# 06 a 09 4 Fator de Vencimento (Vide Nota)
|
129
|
+
# 10 a 19 10 Valor
|
130
|
+
# 20 a 44 25 Campo Livre
|
131
|
+
# As posições do campo livre ficam a critério de cada Banco arrecadador.
|
132
|
+
def codigo_barras
|
133
|
+
codigo = monta_codigo_43_digitos
|
134
|
+
return nil unless codigo
|
135
|
+
return nil if codigo.size != 43
|
136
|
+
codigo_dv = codigo.modulo11_2to9
|
137
|
+
|
138
|
+
"#{codigo[0..3]}#{codigo_dv}#{codigo[4..42]}"
|
139
|
+
end
|
140
|
+
|
141
|
+
# Responsável por montar uma String com 43 caracteres que será usado na criação do código de barras
|
142
|
+
# Este metodo precisa ser reescrito para cada classe de boleto a ser criada.
|
143
|
+
def monta_codigo_43_digitos
|
144
|
+
"Sobreescreva este método na classe referente ao banco que você esta criando"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
begin
|
2
|
+
require 'rghost'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'Por favor execute `sudo gem install rghost` para usar o brcobranca'
|
5
|
+
end
|
6
|
+
begin
|
7
|
+
require 'rghost_barcode'
|
8
|
+
rescue LoadError
|
9
|
+
puts 'Por favor execute `sudo gem install rghost_barcode` para usar o brcobranca'
|
10
|
+
end
|
11
|
+
|
12
|
+
module Brcobranca
|
13
|
+
module Boleto
|
14
|
+
module Template
|
15
|
+
# Templates para usar com Rghost
|
16
|
+
module Rghost
|
17
|
+
include RGhost unless self.include?(RGhost)
|
18
|
+
|
19
|
+
# Gera o boleto em usando o formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc]
|
20
|
+
# Veja mais formatos na documentação do rghost: http://wiki.github.com/shairontoledo/rghost/supported-devices-drivers-and-formats
|
21
|
+
def to(formato)
|
22
|
+
modelo_generico(:tipo => formato)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Responsável por setar os valores necessários no template genérico
|
26
|
+
# Retorna um stream pronto para gravaçào
|
27
|
+
#
|
28
|
+
# O tipo do arquivo gerado pode ser modificado incluindo a configuração a baixo dentro da sua aplicação:
|
29
|
+
# Brcobranca::Config::OPCOES[:tipo] = 'pdf'
|
30
|
+
#
|
31
|
+
# Ou pode ser passado como paramentro:
|
32
|
+
# :tipo => 'pdf'
|
33
|
+
def modelo_generico(options={})
|
34
|
+
doc=Document.new :paper => :A4 # 210x297
|
35
|
+
|
36
|
+
template_path = File.join(File.dirname(__FILE__),'..','..','arquivos','templates','modelo_generico.eps')
|
37
|
+
|
38
|
+
raise "Não foi possível encontrar o template. Verifique o caminho" unless File.exist?(template_path)
|
39
|
+
|
40
|
+
doc.define_template(:template, template_path, :x => '0.3 cm', :y => "0 cm")
|
41
|
+
doc.use_template :template
|
42
|
+
|
43
|
+
doc.define_tags do
|
44
|
+
tag :grande, :size => 13
|
45
|
+
end
|
46
|
+
|
47
|
+
# Busca logo automaticamente
|
48
|
+
logo = monta_logo
|
49
|
+
|
50
|
+
#INICIO Primeira parte do BOLETO
|
51
|
+
# LOGOTIPO do BANCO
|
52
|
+
doc.image(logo, :x => '0.5 cm', :y => '23.85 cm', :zoom => 80) if logo
|
53
|
+
# Dados
|
54
|
+
doc.moveto :x => '5.2 cm' , :y => '23.85 cm'
|
55
|
+
doc.show "#{self.banco}-#{self.banco_dv}", :tag => :grande
|
56
|
+
doc.moveto :x => '7.5 cm' , :y => '23.85 cm'
|
57
|
+
doc.show self.codigo_barras.linha_digitavel, :tag => :grande
|
58
|
+
doc.moveto :x => '0.7 cm' , :y => '23 cm'
|
59
|
+
doc.show self.cedente
|
60
|
+
doc.moveto :x => '11 cm' , :y => '23 cm'
|
61
|
+
doc.show "#{self.agencia}-#{self.agencia_dv}/#{self.conta_corrente}-#{self.conta_corrente_dv}"
|
62
|
+
doc.moveto :x => '14.2 cm' , :y => '23 cm'
|
63
|
+
doc.show self.especie
|
64
|
+
doc.moveto :x => '15.7 cm' , :y => '23 cm'
|
65
|
+
doc.show self.quantidade
|
66
|
+
doc.moveto :x => '0.7 cm' , :y => '22.2 cm'
|
67
|
+
doc.show self.numero_documento
|
68
|
+
doc.moveto :x => '7 cm' , :y => '22.2 cm'
|
69
|
+
doc.show "#{self.sacado_documento.formata_documento}"
|
70
|
+
doc.moveto :x => '12 cm' , :y => '22.2 cm'
|
71
|
+
doc.show self.data_vencimento.to_s_br
|
72
|
+
doc.moveto :x => '16.5 cm' , :y => '23 cm'
|
73
|
+
doc.show self.nosso_numero
|
74
|
+
doc.moveto :x => '16.5 cm' , :y => '22.2 cm'
|
75
|
+
doc.show self.valor_documento.to_currency
|
76
|
+
doc.moveto :x => '1.4 cm' , :y => '20.9 cm'
|
77
|
+
doc.show "#{self.sacado} - #{self.sacado_documento.formata_documento}"
|
78
|
+
doc.moveto :x => '1.4 cm' , :y => '20.6 cm'
|
79
|
+
doc.show "#{self.sacado_endereco}"
|
80
|
+
#FIM Primeira parte do BOLETO
|
81
|
+
|
82
|
+
#INICIO Segunda parte do BOLETO BB
|
83
|
+
# LOGOTIPO do BANCO
|
84
|
+
doc.image(logo, :x => '0.5 cm', :y => '16.8 cm', :zoom => 80) if logo
|
85
|
+
doc.moveto :x => '5.2 cm' , :y => '16.8 cm'
|
86
|
+
doc.show "#{self.banco}-#{self.banco_dv}", :tag => :grande if self.banco && self.banco_dv
|
87
|
+
doc.moveto :x => '7.5 cm' , :y => '16.8 cm'
|
88
|
+
doc.show self.codigo_barras.linha_digitavel, :tag => :grande if self.codigo_barras && self.codigo_barras.linha_digitavel
|
89
|
+
doc.moveto :x => '0.7 cm' , :y => '16 cm'
|
90
|
+
doc.show self.local_pagamento if self.local_pagamento
|
91
|
+
doc.moveto :x => '16.5 cm' , :y => '16 cm'
|
92
|
+
doc.show self.data_vencimento.to_s_br if self.data_vencimento
|
93
|
+
doc.moveto :x => '0.7 cm' , :y => '15.2 cm'
|
94
|
+
doc.show self.cedente if self.cedente
|
95
|
+
doc.moveto :x => '16.5 cm' , :y => '15.2 cm'
|
96
|
+
doc.show "#{self.agencia}-#{self.agencia_dv}/#{self.conta_corrente}-#{self.conta_corrente_dv}"
|
97
|
+
doc.moveto :x => '0.7 cm' , :y => '14.4 cm'
|
98
|
+
doc.show self.data_documento.to_s_br if self.data_documento
|
99
|
+
doc.moveto :x => '4.2 cm' , :y => '14.4 cm'
|
100
|
+
doc.show self.numero_documento if self.numero_documento
|
101
|
+
doc.moveto :x => '10 cm' , :y => '14.4 cm'
|
102
|
+
doc.show self.especie if self.especie
|
103
|
+
doc.moveto :x => '11.7 cm' , :y => '14.4 cm'
|
104
|
+
doc.show self.aceite if self.aceite
|
105
|
+
doc.moveto :x => '13 cm' , :y => '14.4 cm'
|
106
|
+
doc.show self.data_processamento.to_s_br if self.data_processamento
|
107
|
+
doc.moveto :x => '16.5 cm' , :y => '14.4 cm'
|
108
|
+
doc.show self.nosso_numero
|
109
|
+
doc.moveto :x => '4.4 cm' , :y => '13.5 cm'
|
110
|
+
doc.show self.carteira if self.carteira
|
111
|
+
doc.moveto :x => '6.4 cm' , :y => '13.5 cm'
|
112
|
+
doc.show self.moeda if self.moeda
|
113
|
+
doc.moveto :x => '8 cm' , :y => '13.5 cm'
|
114
|
+
doc.show self.quantidade if self.quantidade
|
115
|
+
doc.moveto :x => '11 cm' , :y => '13.5 cm'
|
116
|
+
doc.show self.valor.to_currency if self.valor
|
117
|
+
doc.moveto :x => '16.5 cm' , :y => '13.5 cm'
|
118
|
+
doc.show self.valor_documento.to_currency if self.valor_documento
|
119
|
+
doc.moveto :x => '0.7 cm' , :y => '12.7 cm'
|
120
|
+
doc.show self.instrucao1 if self.instrucao1
|
121
|
+
doc.moveto :x => '0.7 cm' , :y => '12.3 cm'
|
122
|
+
doc.show self.instrucao2 if self.instrucao2
|
123
|
+
doc.moveto :x => '0.7 cm' , :y => '11.9 cm'
|
124
|
+
doc.show self.instrucao3 if self.instrucao3
|
125
|
+
doc.moveto :x => '0.7 cm' , :y => '11.5 cm'
|
126
|
+
doc.show self.instrucao4 if self.instrucao4
|
127
|
+
doc.moveto :x => '0.7 cm' , :y => '11.1 cm'
|
128
|
+
doc.show self.instrucao5 if self.instrucao5
|
129
|
+
doc.moveto :x => '0.7 cm' , :y => '10.7 cm'
|
130
|
+
doc.show self.instrucao6 if self.instrucao6
|
131
|
+
doc.moveto :x => '1.2 cm' , :y => '8.8 cm'
|
132
|
+
doc.show "#{self.sacado} - #{self.sacado_documento.formata_documento}" if self.sacado && self.sacado_documento
|
133
|
+
doc.moveto :x => '1.2 cm' , :y => '8.4 cm'
|
134
|
+
doc.show "#{self.sacado_endereco}" if self.sacado_endereco
|
135
|
+
#FIM Segunda parte do BOLETO
|
136
|
+
|
137
|
+
#Gerando codigo de barra com rghost_barcode
|
138
|
+
doc.barcode_interleaved2of5(self.codigo_barras, :width => '10.3 cm', :height => '1.3 cm', :x => '0.7 cm', :y => '5.8 cm' ) if self.codigo_barras
|
139
|
+
|
140
|
+
# Gerando stream
|
141
|
+
unless options[:tipo]
|
142
|
+
options[:tipo] = Brcobranca::Config::OPCOES[:tipo]
|
143
|
+
end
|
144
|
+
|
145
|
+
options[:tipo] = options[:tipo].to_sym unless options[:tipo].kind_of?(Symbol)
|
146
|
+
doc.render_stream(options[:tipo])
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Brcobranca
|
2
|
+
module Boleto
|
3
|
+
module Template
|
4
|
+
# Métodos auxiliares de montagem de template
|
5
|
+
module Util
|
6
|
+
# Responsável por definir a logotipo usada no template genérico,
|
7
|
+
# retorna o caminho para o <b>logotipo</b> ou <b>false</b> caso nao consiga encontrar o logotipo.
|
8
|
+
def monta_logo
|
9
|
+
case self.class.to_s
|
10
|
+
when "BancoBrasil"
|
11
|
+
imagem = 'bb.jpg'
|
12
|
+
when "BancoItau"
|
13
|
+
imagem = 'itau.jpg'
|
14
|
+
when "BancoHsbc"
|
15
|
+
imagem = 'hsbc.jpg'
|
16
|
+
when "BancoReal"
|
17
|
+
imagem = 'real.jpg'
|
18
|
+
when "BancoBradesco"
|
19
|
+
imagem = 'bradesco.jpg'
|
20
|
+
when "BancoUnibanco"
|
21
|
+
imagem = 'unibanco.jpg'
|
22
|
+
else
|
23
|
+
return false
|
24
|
+
end
|
25
|
+
File.join(File.dirname(__FILE__),'..','..','arquivos','logos',imagem)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Brcobranca
|
2
|
+
# Módulo de configuração.
|
3
|
+
module Config
|
4
|
+
# Opções disponíveis:
|
5
|
+
# Brcobranca::Config::OPCOES[:tipo] - Pode ser pdf, jpg e ps.
|
6
|
+
# Brcobranca::Config::OPCOES[:gerador] - Somente rghost até o momento
|
7
|
+
OPCOES = {:tipo => 'pdf', :gerador => 'rghost'}
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
module Brcobranca
|
2
|
+
# Métodos auxiliares de formatação
|
3
|
+
module Formatacao
|
4
|
+
# Formata como CPF
|
5
|
+
def to_br_cpf
|
6
|
+
(self.kind_of?(String) ? self : self.to_s).gsub(/^(.{3})(.{3})(.{3})(.{2})$/,'\1.\2.\3-\4')
|
7
|
+
end
|
8
|
+
|
9
|
+
# Formata como CEP
|
10
|
+
def to_br_cep
|
11
|
+
(self.kind_of?(String) ? self : self.to_s).gsub(/^(.{5})(.{3})$/,'\1-\2')
|
12
|
+
end
|
13
|
+
|
14
|
+
# Formata como CNPJ
|
15
|
+
def to_br_cnpj
|
16
|
+
(self.kind_of?(String) ? self : self.to_s).gsub(/^(.{2})(.{3})(.{3})(.{4})(.{2})$/,'\1.\2.\3/\4-\5')
|
17
|
+
end
|
18
|
+
|
19
|
+
# Gera formatação automatica do documento baseado no tamanho do campo.
|
20
|
+
def formata_documento
|
21
|
+
case (self.kind_of?(String) ? self : self.to_s).size
|
22
|
+
when 8 then self.to_br_cep
|
23
|
+
when 11 then self.to_br_cpf
|
24
|
+
when 14 then self.to_br_cnpj
|
25
|
+
else
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Remove caracteres que não sejam numéricos do tipo MOEDA
|
31
|
+
def limpa_valor_moeda
|
32
|
+
return self unless self.kind_of?(String) && self.moeda?
|
33
|
+
self.somente_numeros
|
34
|
+
end
|
35
|
+
|
36
|
+
# Remove caracteres que não sejam numéricos
|
37
|
+
def somente_numeros
|
38
|
+
return self unless self.kind_of?(String)
|
39
|
+
self.gsub(/\D/,'')
|
40
|
+
end
|
41
|
+
|
42
|
+
# Completa zeros a esquerda.
|
43
|
+
# Ex. numero="123" :tamanho=>3 | numero="123"
|
44
|
+
# Ex. numero="123" :tamanho=>4 | numero="0123"
|
45
|
+
# Ex. numero="123" :tamanho=>5 | numero="00123"
|
46
|
+
def zeros_esquerda(options={})
|
47
|
+
valor_inicial = self.kind_of?(String) ? self : self.to_s
|
48
|
+
return valor_inicial if (valor_inicial !~ /\S/)
|
49
|
+
digitos = options[:tamanho] || valor_inicial.size
|
50
|
+
|
51
|
+
diferenca = (digitos - valor_inicial.size)
|
52
|
+
|
53
|
+
return valor_inicial if (diferenca <= 0)
|
54
|
+
return (("0" * diferenca) + valor_inicial )
|
55
|
+
end
|
56
|
+
|
57
|
+
# Monta a linha digitável padrão para todos os bancos segundo a BACEN.
|
58
|
+
# Retorna + nil + para Codigo de Barras em branco,
|
59
|
+
# Codigo de Barras com tamanho diferente de 44 dígitos e
|
60
|
+
# Codigo de Barras que não tenham somente caracteres numéricos.
|
61
|
+
# A linha digitável será composta por cinco campos:
|
62
|
+
# 1º campo
|
63
|
+
# Composto pelo código de Banco, código da moeda, as cinco primeiras posições do campo livre
|
64
|
+
# e o dígito verificador deste campo;
|
65
|
+
# 2º campo
|
66
|
+
# Composto pelas posições 6ª a 15ª do campo livre e o dígito verificador deste campo;
|
67
|
+
# 3º campo
|
68
|
+
# Composto pelas posições 16ª a 25ª do campo livre e o dígito verificador deste campo;
|
69
|
+
# 4º campo
|
70
|
+
# Composto pelo dígito verificador do código de barras, ou seja, a 5ª posição do código de
|
71
|
+
# barras;
|
72
|
+
# 5º campo
|
73
|
+
# Composto pelo fator de vencimento com 4(quatro) caracteres e o valor do documento com
|
74
|
+
# 10(dez) caracteres, sem separadores e sem edição.
|
75
|
+
# Entre cada campo deverá haver espaço equivalente a 2 (duas) posições, sendo a 1ª
|
76
|
+
# interpretada por um ponto (.) e a 2ª por um espaço em branco.
|
77
|
+
def linha_digitavel
|
78
|
+
valor_inicial = self.kind_of?(String) ? self : self.to_s
|
79
|
+
return nil if (valor_inicial !~ /\S/) || valor_inicial.size != 44 || (!valor_inicial.scan(/\D/).empty?)
|
80
|
+
|
81
|
+
dv_1 = ("#{valor_inicial[0..3]}#{valor_inicial[19..23]}").modulo10
|
82
|
+
campo_1_dv = "#{valor_inicial[0..3]}#{valor_inicial[19..23]}#{dv_1}"
|
83
|
+
campo_linha_1 = "#{campo_1_dv[0..4]}.#{campo_1_dv[5..9]}"
|
84
|
+
|
85
|
+
dv_2 = "#{valor_inicial[24..33]}".modulo10
|
86
|
+
campo_2_dv = "#{valor_inicial[24..33]}#{dv_2}"
|
87
|
+
campo_linha_2 = "#{campo_2_dv[0..4]}.#{campo_2_dv[5..10]}"
|
88
|
+
|
89
|
+
dv_3 = "#{valor_inicial[34..43]}".modulo10
|
90
|
+
campo_3_dv = "#{valor_inicial[34..43]}#{dv_3}"
|
91
|
+
campo_linha_3 = "#{campo_3_dv[0..4]}.#{campo_3_dv[5..10]}"
|
92
|
+
|
93
|
+
campo_linha_4 = "#{valor_inicial[4..4]}"
|
94
|
+
|
95
|
+
campo_linha_5 = "#{valor_inicial[5..18]}"
|
96
|
+
|
97
|
+
"#{campo_linha_1} #{campo_linha_2} #{campo_linha_3} #{campo_linha_4} #{campo_linha_5}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# métodos auxiliares de cálculos
|
102
|
+
module Calculo
|
103
|
+
# Método padrão para cálculo de módulo 10 segundo a BACEN.
|
104
|
+
def modulo10
|
105
|
+
valor_inicial = self.kind_of?(String) ? self : self.to_s
|
106
|
+
return nil if (valor_inicial !~ /\S/)
|
107
|
+
|
108
|
+
total = 0
|
109
|
+
multiplicador = 2
|
110
|
+
|
111
|
+
valor_inicial.split(//).reverse!.each do |caracter|
|
112
|
+
total += (caracter.to_i * multiplicador).soma_digitos
|
113
|
+
multiplicador = multiplicador == 2 ? 1 : 2
|
114
|
+
end
|
115
|
+
|
116
|
+
valor = (10 - (total % 10))
|
117
|
+
valor == 10 ? 0 : valor
|
118
|
+
end
|
119
|
+
|
120
|
+
# Método padrão para cálculo de módulo 11 com multiplicaroes de 9 a 2 segundo a BACEN.
|
121
|
+
# Usado no DV do Nosso Numero, Agência e Cedente.
|
122
|
+
# Retorna + nil + para todos os parametros que nao forem String
|
123
|
+
# Retorna + nil + para String em branco
|
124
|
+
def modulo11_9to2
|
125
|
+
valor_inicial = self.kind_of?(String) ? self : self.to_s
|
126
|
+
return nil if (valor_inicial !~ /\S/)
|
127
|
+
|
128
|
+
multiplicadores = [9,8,7,6,5,4,3,2]
|
129
|
+
total = 0
|
130
|
+
multiplicador_posicao = 0
|
131
|
+
|
132
|
+
valor_inicial.split(//).reverse!.each do |caracter|
|
133
|
+
multiplicador_posicao = 0 if (multiplicador_posicao == 8)
|
134
|
+
total += (caracter.to_i * multiplicadores[multiplicador_posicao])
|
135
|
+
multiplicador_posicao += 1
|
136
|
+
end
|
137
|
+
|
138
|
+
return (total % 11 )
|
139
|
+
end
|
140
|
+
|
141
|
+
# Método padrão para cálculo de módulo 11 com multiplicaroes de 2 a 9 segundo a BACEN.
|
142
|
+
# Usado no DV do Código de Barras.
|
143
|
+
# Retorna + nil + para todos os parametros que não forem String
|
144
|
+
# Retorna + nil + para String em branco
|
145
|
+
def modulo11_2to9
|
146
|
+
valor_inicial = self.kind_of?(String) ? self : self.to_s
|
147
|
+
return nil if (valor_inicial !~ /\S/)
|
148
|
+
|
149
|
+
multiplicadores = [2,3,4,5,6,7,8,9]
|
150
|
+
total = 0
|
151
|
+
multiplicador_posicao = 0
|
152
|
+
|
153
|
+
valor_inicial.split(//).reverse!.each do |caracter|
|
154
|
+
multiplicador_posicao = 0 if (multiplicador_posicao == 8)
|
155
|
+
total += (caracter.to_i * multiplicadores[multiplicador_posicao])
|
156
|
+
multiplicador_posicao += 1
|
157
|
+
end
|
158
|
+
|
159
|
+
valor = (11 - (total % 11))
|
160
|
+
return [0,10,11].include?(valor) ? 1 : valor
|
161
|
+
end
|
162
|
+
|
163
|
+
# Retorna o dígito verificador de <b>modulo 11(9-2)</b> trocando retorno <b>10 por X</b>.
|
164
|
+
# Usado por alguns bancos.
|
165
|
+
def modulo11_9to2_10_como_x
|
166
|
+
valor = self.modulo11_9to2
|
167
|
+
valor == 10 ? "X" : valor
|
168
|
+
end
|
169
|
+
|
170
|
+
# Retorna o dígito verificador de <b>modulo 11(9-2)</b> trocando retorno <b>10 por 0</b>.
|
171
|
+
# Usado por alguns bancos.
|
172
|
+
def modulo11_9to2_10_como_zero
|
173
|
+
valor = self.modulo11_9to2
|
174
|
+
valor == 10 ? 0 : valor
|
175
|
+
end
|
176
|
+
|
177
|
+
# Soma números inteiros positivos com 2 dígitos ou mais
|
178
|
+
# Retorna <b>0(zero)</b> caso seja impossível.
|
179
|
+
# Ex. 1 = 1
|
180
|
+
# Ex. 11 = (1+1) = 2
|
181
|
+
# Ex. 13 = (1+3) = 4
|
182
|
+
def soma_digitos
|
183
|
+
valor_inicial = self.kind_of?(Fixnum) ? self : self.to_i
|
184
|
+
return 0 if valor_inicial == 0
|
185
|
+
return valor_inicial if valor_inicial <= 9
|
186
|
+
|
187
|
+
valor_inicial = valor_inicial.to_s
|
188
|
+
total = 0
|
189
|
+
|
190
|
+
0.upto(valor_inicial.size-1) {|digito| total += valor_inicial[digito,1].to_i }
|
191
|
+
|
192
|
+
return total
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Métodos auxiliares de verificação e validação.
|
197
|
+
module Validacao
|
198
|
+
# Verifica se o valor é moeda.
|
199
|
+
# Ex. +1.232.33
|
200
|
+
# Ex. -1.232.33
|
201
|
+
# Ex. 1.232.33
|
202
|
+
def moeda?
|
203
|
+
return false unless self.kind_of?(String)
|
204
|
+
self =~ /^(\+|-)?\d+((\.|,)\d{3}*)*((\.|,)\d{2}*)$/ ? true : false
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# Métodos auxiliares de limpeza.
|
209
|
+
module Limpeza
|
210
|
+
# Retorna uma String contendo exatamente o valor FLOAT
|
211
|
+
def limpa_valor_moeda
|
212
|
+
return self unless self.kind_of?(Float)
|
213
|
+
valor_inicial = self.to_s
|
214
|
+
(valor_inicial + ("0" * (2 - valor_inicial.split(/\./).last.size ))).somente_numeros
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Métodos auxiliares de cálculos envolvendo <b>Datas</b>.
|
219
|
+
module CalculoData
|
220
|
+
# Calcula o número de dias corridos entre a <b>data base ("Fixada" em 07.10.1997)</b> e a <b>data de vencimento</b> desejado:
|
221
|
+
# VENCIMENTO 04/07/2000
|
222
|
+
# DATA BASE - 07/10/1997
|
223
|
+
# FATOR DE VENCIMENTO 1001
|
224
|
+
def fator_vencimento
|
225
|
+
data_base = Date.parse "1997-10-07"
|
226
|
+
(self - data_base).to_i
|
227
|
+
end
|
228
|
+
|
229
|
+
# Mostra a data em formato <b>dia/mês/ano</b>
|
230
|
+
def to_s_br
|
231
|
+
self.strftime('%d/%m/%Y')
|
232
|
+
end
|
233
|
+
# Retorna string contendo número de dias julianos:
|
234
|
+
# O cálculo é feito subtraindo-se a data atual, pelo último dia válido do ano anterior,
|
235
|
+
# acrescentando-se o último algarismo do ano atual na quarta posição.
|
236
|
+
# Deve retornar string com 4 digitos.
|
237
|
+
# Ex. Data atual = 11/02/2009
|
238
|
+
# Data válida ano anterior = 31/12/2008
|
239
|
+
# (Data atual - Data válida ano anterior) = 42
|
240
|
+
# último algarismo do ano atual = 9
|
241
|
+
# String atual 42+9 = 429
|
242
|
+
# Completa zero esquerda para formar 4 digitos = "0429"
|
243
|
+
def to_juliano
|
244
|
+
ultima_data = Date.parse("#{self.year - 1}-12-31")
|
245
|
+
ultimo_digito_ano = self.to_s[3..3]
|
246
|
+
dias = (self - ultima_data)
|
247
|
+
(dias.to_s + ultimo_digito_ano).zeros_esquerda(:tamanho => 4)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class String #:nodoc:[all]
|
253
|
+
include Brcobranca::Formatacao
|
254
|
+
include Brcobranca::Validacao
|
255
|
+
include Brcobranca::Calculo
|
256
|
+
end
|
257
|
+
|
258
|
+
class Integer #:nodoc:[all]
|
259
|
+
include Brcobranca::Formatacao
|
260
|
+
include Brcobranca::Calculo
|
261
|
+
end
|
262
|
+
|
263
|
+
class Float #:nodoc:[all]
|
264
|
+
include Brcobranca::Limpeza
|
265
|
+
end
|
266
|
+
|
267
|
+
class Date #:nodoc:[all]
|
268
|
+
include Brcobranca::CalculoData
|
269
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Implementação feita por Nando Vieira do http://simplesideias.com.br
|
2
|
+
# post http://simplesideias.com.br/usando-number_to_currency-em-modelos-no-rails
|
3
|
+
module Brcobranca #:nodoc:[all]
|
4
|
+
module Currency #:nodoc:[all]
|
5
|
+
BRL = {:delimiter => ".", :separator => ",", :unit => "R$", :precision => 2, :position => "before"}
|
6
|
+
USD = {:delimiter => ',', :separator => ".", :unit => "US$", :precision => 2, :position => "before"}
|
7
|
+
DEFAULT = BRL.merge(:unit => "")
|
8
|
+
|
9
|
+
module String #:nodoc:[all]
|
10
|
+
def to_number(options={})
|
11
|
+
return self.gsub(/,/, '.').to_f if self.numeric?
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def numeric?
|
16
|
+
self =~ /^(\+|-)?[0-9]+((\.|,)[0-9]+)?$/ ? true : false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Number #:nodoc:[all]
|
21
|
+
def to_currency(options = {})
|
22
|
+
number = self
|
23
|
+
default = Brcobranca::Currency::DEFAULT.stringify_keys
|
24
|
+
options = default.merge(options.stringify_keys)
|
25
|
+
precision = options["precision"] || default["precision"]
|
26
|
+
unit = options["unit"] || default["unit"]
|
27
|
+
position = options["position"] || default["position"]
|
28
|
+
separator = precision > 0 ? options["separator"] || default["separator"] : ""
|
29
|
+
delimiter = options["delimiter"] || default["delimiter"]
|
30
|
+
|
31
|
+
begin
|
32
|
+
parts = number.with_precision(precision).split('.')
|
33
|
+
number = parts[0].to_i.with_delimiter(delimiter) + separator + parts[1].to_s
|
34
|
+
position == "before" ? unit + number : number + unit
|
35
|
+
rescue
|
36
|
+
number
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def with_delimiter(delimiter=",", separator=".")
|
41
|
+
number = self
|
42
|
+
begin
|
43
|
+
parts = number.to_s.split(separator)
|
44
|
+
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
|
45
|
+
parts.join separator
|
46
|
+
rescue
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def with_precision(precision=3)
|
52
|
+
number = self
|
53
|
+
"%01.#{precision}f" % number
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Fixnum #:nodoc:[all]
|
60
|
+
include Brcobranca::Currency::Number
|
61
|
+
end
|
62
|
+
class Bignum #:nodoc:[all]
|
63
|
+
include Brcobranca::Currency::Number
|
64
|
+
end
|
65
|
+
class Float #:nodoc:[all]
|
66
|
+
include Brcobranca::Currency::Number
|
67
|
+
end
|
68
|
+
class String #:nodoc:[all]
|
69
|
+
include Brcobranca::Currency::String
|
70
|
+
end
|