brcobranca 2.0.6 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +30 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +48 -0
- data/History.txt +13 -1
- data/LICENSE +20 -0
- data/README.rdoc +12 -5
- data/Rakefile +33 -37
- data/VERSION +1 -0
- data/brcobranca.gemspec +26 -35
- data/lib/brcobranca/arquivos/logos/{bb.jpg → bancobrasil.jpg} +0 -0
- data/lib/brcobranca/arquivos/logos/banespa.jpg +0 -0
- data/lib/brcobranca/arquivos/logos/caixa.jpg +0 -0
- data/lib/brcobranca/boleto/banco_brasil.rb +150 -77
- data/lib/brcobranca/boleto/base.rb +146 -75
- data/lib/brcobranca/boleto/bradesco.rb +69 -0
- data/lib/brcobranca/boleto/caixa.rb +100 -0
- data/lib/brcobranca/boleto/hsbc.rb +95 -0
- data/lib/brcobranca/boleto/itau.rb +133 -0
- data/lib/brcobranca/boleto/real.rb +74 -0
- data/lib/brcobranca/boleto/template/base.rb +13 -0
- data/lib/brcobranca/boleto/template/rghost.rb +136 -62
- data/lib/brcobranca/boleto/unibanco.rb +115 -0
- data/lib/brcobranca/calculo.rb +132 -0
- data/lib/brcobranca/calculo_data.rb +42 -0
- data/lib/brcobranca/currency.rb +3 -4
- data/lib/brcobranca/formatacao.rb +102 -0
- data/lib/brcobranca/limpeza.rb +19 -0
- data/lib/brcobranca/retorno/base.rb +1 -2
- data/lib/brcobranca/retorno/retorno_cbr643.rb +42 -40
- data/lib/brcobranca/version.rb +3 -0
- data/lib/brcobranca.rb +93 -16
- data/spec/brcobranca/banco_bradesco_spec.rb +63 -50
- data/spec/brcobranca/banco_brasil_spec.rb +102 -136
- data/spec/brcobranca/banco_caixa_spec.rb +166 -0
- data/spec/brcobranca/banco_hsbc_spec.rb +83 -76
- data/spec/brcobranca/banco_real_spec.rb +54 -37
- data/spec/brcobranca/banco_unibanco_spec.rb +69 -52
- data/spec/brcobranca/base_spec.rb +24 -79
- data/spec/brcobranca/boletos_em_lote_spec.rb +46 -0
- data/spec/brcobranca/core_ext_spec.rb +24 -114
- data/spec/brcobranca/currency_spec.rb +1 -0
- data/spec/brcobranca/{banco_itau_spec.rb → itau_spec.rb} +112 -67
- data/spec/brcobranca/retorno_cbr643_spec.rb +13 -12
- data/spec/brcobranca/rghost_spec.rb +8 -7
- data/spec/brcobranca_spec.rb +16 -6
- data/spec/spec_helper.rb +11 -8
- metadata +107 -58
- data/Manifest.txt +0 -51
- data/PostInstall.txt +0 -4
- data/lib/brcobranca/boleto/banco_banespa.rb +0 -85
- data/lib/brcobranca/boleto/banco_bradesco.rb +0 -44
- data/lib/brcobranca/boleto/banco_hsbc.rb +0 -77
- data/lib/brcobranca/boleto/banco_itau.rb +0 -115
- data/lib/brcobranca/boleto/banco_real.rb +0 -70
- data/lib/brcobranca/boleto/banco_unibanco.rb +0 -79
- data/lib/brcobranca/boleto/template/util.rb +0 -32
- data/lib/brcobranca/config.rb +0 -9
- data/lib/brcobranca/core_ext.rb +0 -279
- data/spec/brcobranca/banco_banespa_spec.rb +0 -195
- data/spec/brcobranca/template/rghost_spec.rb +0 -65
- data/spec/brcobranca/template/util_spec.rb +0 -42
- data/spec/rcov.opts +0 -2
- data/spec/spec.opts +0 -6
- data/tasks/rcov.rake +0 -12
- data/tasks/rspec.rake +0 -21
@@ -0,0 +1,74 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module Brcobranca
|
3
|
+
module Boleto
|
4
|
+
class Real < Base # Banco REAL
|
5
|
+
|
6
|
+
validates_length_of :agencia, :maximum => 4, :message => "deve ser menor ou igual a 4 dígitos."
|
7
|
+
validates_length_of :conta_corrente, :maximum => 7, :message => "deve ser menor ou igual a 7 dígitos."
|
8
|
+
|
9
|
+
validates_each :numero_documento do |record, attr, value|
|
10
|
+
record.errors.add attr, 'deve ser menor ou igual a 13 dígitos.' if (value.to_s.size > 13) && (record.carteira.to_i == 57)
|
11
|
+
record.errors.add attr, 'deve ser menor ou igual a 7 dígitos.' if (value.to_s.size > 7) && (record.carteira.to_i != 57)
|
12
|
+
end
|
13
|
+
|
14
|
+
## Nova instancia do Real
|
15
|
+
# @param (see Brcobranca::Boleto::Base#initialize)
|
16
|
+
def initialize(campos={})
|
17
|
+
campos = {:carteira => "57"}.merge!(campos)
|
18
|
+
super(campos)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Codigo do banco emissor (3 dígitos sempre)
|
22
|
+
def banco
|
23
|
+
"356"
|
24
|
+
end
|
25
|
+
|
26
|
+
# Número seqüencial utilizado para identificar o boleto.
|
27
|
+
#
|
28
|
+
# NUMERO DO BANCO : COM 7 DIGITOS P/ COBRANCA REGISTRADA e ATE 13 DIGITOS P/ COBRANCA SEM REGISTRO
|
29
|
+
#
|
30
|
+
# @return [String] 7 ou 13 caracteres numéricos.
|
31
|
+
def numero_documento
|
32
|
+
quantidade = (self.carteira.to_i == 57) ? 13 : 7
|
33
|
+
@numero_documento.to_s.rjust(quantidade,'0')
|
34
|
+
end
|
35
|
+
|
36
|
+
# Nosso número para exibir no boleto.
|
37
|
+
# @return [String]
|
38
|
+
# @example
|
39
|
+
# boleto.nosso_numero_boleto #=> "4000403005-6"
|
40
|
+
def nosso_numero_boleto
|
41
|
+
"#{self.numero_documento}-#{self.nosso_numero_dv}"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Número do convênio/contrato do cliente para exibir no boleto.
|
45
|
+
# @return [String]
|
46
|
+
# @example
|
47
|
+
# boleto.agencia_conta_boleto #=> "0548-7 / 0001448-6"
|
48
|
+
def agencia_conta_boleto
|
49
|
+
"#{self.agencia}-#{self.agencia_dv} / #{self.conta_corrente}-#{self.conta_corrente_dv}"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Dígito verificador do nosso número.
|
53
|
+
# @return [String] 1 caracteres numéricos.
|
54
|
+
def agencia_conta_corrente_nosso_numero_dv
|
55
|
+
"#{self.numero_documento}#{self.agencia}#{self.conta_corrente}".modulo10
|
56
|
+
end
|
57
|
+
|
58
|
+
# Segunda parte do código de barras.
|
59
|
+
#
|
60
|
+
# Montagem é baseada no tipo de carteira, com registro e sem registro(57)
|
61
|
+
#
|
62
|
+
# @return [String] 25 caracteres numéricos.
|
63
|
+
def codigo_barras_segunda_parte
|
64
|
+
case self.carteira.to_i
|
65
|
+
when 57
|
66
|
+
"#{self.agencia}#{self.conta_corrente}#{self.agencia_conta_corrente_nosso_numero_dv}#{self.numero_documento}"
|
67
|
+
else
|
68
|
+
# TODO verificar com o banco, pois não consta na documentação
|
69
|
+
"000000#{self.agencia}#{self.conta_corrente}#{self.agencia_conta_corrente_nosso_numero_dv}#{self.numero_documento}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'rghost'
|
3
5
|
rescue LoadError
|
@@ -19,135 +21,207 @@ module Brcobranca
|
|
19
21
|
module Template
|
20
22
|
# Templates para usar com Rghost
|
21
23
|
module Rghost
|
24
|
+
extend self
|
22
25
|
include RGhost unless self.include?(RGhost)
|
23
26
|
|
24
27
|
# Gera o boleto em usando o formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc]
|
25
|
-
#
|
26
|
-
#
|
27
|
-
|
28
|
-
|
28
|
+
#
|
29
|
+
# @return [Stream]
|
30
|
+
# @see http://wiki.github.com/shairontoledo/rghost/supported-devices-drivers-and-formats Veja mais formatos na documentação do rghost.
|
31
|
+
# @see Rghost#modelo_generico Recebe os mesmos parâmetros do Rghost#modelo_generico.
|
32
|
+
def to(formato, options={})
|
33
|
+
modelo_generico(self, options.merge!({:formato => formato}))
|
34
|
+
end
|
35
|
+
|
36
|
+
# Gera o boleto em usando o formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc]
|
37
|
+
#
|
38
|
+
# @return [Stream]
|
39
|
+
# @see http://wiki.github.com/shairontoledo/rghost/supported-devices-drivers-and-formats Veja mais formatos na documentação do rghost.
|
40
|
+
# @see Rghost#modelo_generico Recebe os mesmos parâmetros do Rghost#modelo_generico.
|
41
|
+
def lote(boletos, options={})
|
42
|
+
modelo_generico_multipage(boletos, options)
|
29
43
|
end
|
30
44
|
|
31
|
-
#
|
32
|
-
# Retorna um stream pronto para gravaçào
|
45
|
+
# Cria o métodos dinâmicos (to_pdf, to_gif e etc) com todos os fomátos válidos.
|
33
46
|
#
|
34
|
-
#
|
35
|
-
#
|
47
|
+
# @return [Stream]
|
48
|
+
# @see Rghost#modelo_generico Recebe os mesmos parâmetros do Rghost#modelo_generico.
|
49
|
+
# @example
|
50
|
+
# @boleto.to_pdf #=> boleto gerado no formato pdf
|
51
|
+
def method_missing(m, *args)
|
52
|
+
method = m.to_s
|
53
|
+
if method.start_with?("to_")
|
54
|
+
modelo_generico(self, (args.first || {}).merge!({:formato => method[3..-1]}))
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Retorna um stream pronto para gravação em arquivo.
|
63
|
+
#
|
64
|
+
# @return [Stream]
|
65
|
+
# @param [Boleto] Instância de uma classe de boleto.
|
66
|
+
# @param [Hash] options Opção para a criação do boleto.
|
67
|
+
# @option options [Symbol] :resolucao Resolução em pixels.
|
68
|
+
# @option options [Symbol] :formato Formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc]
|
69
|
+
def modelo_generico(boleto, options={})
|
70
|
+
doc=Document.new :paper => :A4 # 210x297
|
71
|
+
|
72
|
+
template_path = File.join(File.dirname(__FILE__),'..','..','arquivos','templates','modelo_generico.eps')
|
73
|
+
|
74
|
+
raise "Não foi possível encontrar o template. Verifique o caminho" unless File.exist?(template_path)
|
75
|
+
|
76
|
+
modelo_generico_template(doc, boleto, template_path)
|
77
|
+
modelo_generico_cabecalho(doc, boleto)
|
78
|
+
modelo_generico_rodape(doc, boleto)
|
79
|
+
|
80
|
+
#Gerando codigo de barra com rghost_barcode
|
81
|
+
doc.barcode_interleaved2of5(boleto.codigo_barras, :width => '10.3 cm', :height => '1.3 cm', :x => '0.7 cm', :y => '5.8 cm' ) if boleto.codigo_barras
|
82
|
+
|
83
|
+
# Gerando stream
|
84
|
+
formato = (options.delete(:formato) || Brcobranca.configuration.formato)
|
85
|
+
resolucao = (options.delete(:resolucao) || Brcobranca.configuration.resolucao)
|
86
|
+
doc.render_stream(formato.to_sym, :resolution => resolucao)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Retorna um stream para multiplos boletos pronto para gravação em arquivo.
|
36
90
|
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
|
91
|
+
# @return [Stream]
|
92
|
+
# @param [Array] Instâncias de classes de boleto.
|
93
|
+
# @param [Hash] options Opção para a criação do boleto.
|
94
|
+
# @option options [Symbol] :resolucao Resolução em pixels.
|
95
|
+
# @option options [Symbol] :formato Formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc]
|
96
|
+
def modelo_generico_multipage(boletos, options={})
|
40
97
|
doc=Document.new :paper => :A4 # 210x297
|
41
98
|
|
42
99
|
template_path = File.join(File.dirname(__FILE__),'..','..','arquivos','templates','modelo_generico.eps')
|
43
100
|
|
44
101
|
raise "Não foi possível encontrar o template. Verifique o caminho" unless File.exist?(template_path)
|
45
102
|
|
103
|
+
boletos.each_with_index do |boleto, index|
|
104
|
+
|
105
|
+
modelo_generico_template(doc, boleto, template_path)
|
106
|
+
modelo_generico_cabecalho(doc, boleto)
|
107
|
+
modelo_generico_rodape(doc, boleto)
|
108
|
+
|
109
|
+
#Gerando codigo de barra com rghost_barcode
|
110
|
+
doc.barcode_interleaved2of5(boleto.codigo_barras, :width => '10.3 cm', :height => '1.3 cm', :x => '0.7 cm', :y => '5.8 cm' ) if boleto.codigo_barras
|
111
|
+
#Cria nova página se não for o último boleto
|
112
|
+
doc.next_page unless index == boletos.length-1
|
113
|
+
|
114
|
+
end
|
115
|
+
# Gerando stream
|
116
|
+
formato = (options.delete(:formato) || Brcobranca.configuration.formato)
|
117
|
+
resolucao = (options.delete(:resolucao) || Brcobranca.configuration.resolucao)
|
118
|
+
doc.render_stream(formato.to_sym, :resolution => resolucao)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Define o template a ser usado no boleto
|
122
|
+
def modelo_generico_template(doc, boleto, template_path)
|
46
123
|
doc.define_template(:template, template_path, :x => '0.3 cm', :y => "0 cm")
|
47
124
|
doc.use_template :template
|
48
125
|
|
49
126
|
doc.define_tags do
|
50
127
|
tag :grande, :size => 13
|
51
128
|
end
|
129
|
+
end
|
52
130
|
|
53
|
-
|
54
|
-
|
55
|
-
|
131
|
+
# Monta o cabeçalho do layout do boleto
|
132
|
+
def modelo_generico_cabecalho(doc, boleto)
|
56
133
|
#INICIO Primeira parte do BOLETO
|
57
134
|
# LOGOTIPO do BANCO
|
58
|
-
doc.image(
|
135
|
+
doc.image(boleto.logotipo, :x => '0.5 cm', :y => '23.85 cm', :zoom => 80)
|
59
136
|
# Dados
|
60
137
|
doc.moveto :x => '5.2 cm' , :y => '23.85 cm'
|
61
|
-
doc.show "#{
|
138
|
+
doc.show "#{boleto.banco}-#{boleto.banco_dv}", :tag => :grande
|
62
139
|
doc.moveto :x => '7.5 cm' , :y => '23.85 cm'
|
63
|
-
doc.show
|
140
|
+
doc.show boleto.codigo_barras.linha_digitavel, :tag => :grande
|
64
141
|
doc.moveto :x => '0.7 cm' , :y => '23 cm'
|
65
|
-
doc.show
|
142
|
+
doc.show boleto.cedente
|
66
143
|
doc.moveto :x => '11 cm' , :y => '23 cm'
|
67
|
-
doc.show
|
144
|
+
doc.show boleto.agencia_conta_boleto
|
68
145
|
doc.moveto :x => '14.2 cm' , :y => '23 cm'
|
69
|
-
doc.show
|
146
|
+
doc.show boleto.especie
|
70
147
|
doc.moveto :x => '15.7 cm' , :y => '23 cm'
|
71
|
-
doc.show
|
148
|
+
doc.show boleto.quantidade
|
72
149
|
doc.moveto :x => '0.7 cm' , :y => '22.2 cm'
|
73
|
-
doc.show
|
150
|
+
doc.show boleto.numero_documento
|
74
151
|
doc.moveto :x => '7 cm' , :y => '22.2 cm'
|
75
|
-
doc.show "#{
|
152
|
+
doc.show "#{boleto.documento_cedente.formata_documento}"
|
76
153
|
doc.moveto :x => '12 cm' , :y => '22.2 cm'
|
77
|
-
doc.show
|
154
|
+
doc.show boleto.data_vencimento.to_s_br
|
78
155
|
doc.moveto :x => '16.5 cm' , :y => '23 cm'
|
79
|
-
doc.show
|
156
|
+
doc.show boleto.nosso_numero_boleto
|
80
157
|
doc.moveto :x => '16.5 cm' , :y => '22.2 cm'
|
81
|
-
doc.show
|
158
|
+
doc.show boleto.valor_documento.to_currency
|
82
159
|
doc.moveto :x => '1.4 cm' , :y => '20.9 cm'
|
83
|
-
doc.show "#{
|
160
|
+
doc.show "#{boleto.sacado} - #{boleto.sacado_documento.formata_documento}"
|
84
161
|
doc.moveto :x => '1.4 cm' , :y => '20.6 cm'
|
85
|
-
doc.show "#{
|
162
|
+
doc.show "#{boleto.sacado_endereco}"
|
86
163
|
#FIM Primeira parte do BOLETO
|
164
|
+
end
|
87
165
|
|
166
|
+
# Monta o corpo e rodapé do layout do boleto
|
167
|
+
def modelo_generico_rodape(doc, boleto)
|
88
168
|
#INICIO Segunda parte do BOLETO BB
|
89
169
|
# LOGOTIPO do BANCO
|
90
|
-
doc.image(
|
170
|
+
doc.image(boleto.logotipo, :x => '0.5 cm', :y => '16.8 cm', :zoom => 80)
|
91
171
|
doc.moveto :x => '5.2 cm' , :y => '16.8 cm'
|
92
|
-
doc.show "#{
|
172
|
+
doc.show "#{boleto.banco}-#{boleto.banco_dv}", :tag => :grande
|
93
173
|
doc.moveto :x => '7.5 cm' , :y => '16.8 cm'
|
94
|
-
doc.show
|
174
|
+
doc.show boleto.codigo_barras.linha_digitavel, :tag => :grande
|
95
175
|
doc.moveto :x => '0.7 cm' , :y => '16 cm'
|
96
|
-
doc.show
|
176
|
+
doc.show boleto.local_pagamento
|
97
177
|
doc.moveto :x => '16.5 cm' , :y => '16 cm'
|
98
|
-
doc.show
|
178
|
+
doc.show boleto.data_vencimento.to_s_br if boleto.data_vencimento
|
99
179
|
doc.moveto :x => '0.7 cm' , :y => '15.2 cm'
|
100
|
-
doc.show
|
180
|
+
doc.show boleto.cedente
|
101
181
|
doc.moveto :x => '16.5 cm' , :y => '15.2 cm'
|
102
|
-
doc.show
|
182
|
+
doc.show boleto.agencia_conta_boleto
|
103
183
|
doc.moveto :x => '0.7 cm' , :y => '14.4 cm'
|
104
|
-
doc.show
|
184
|
+
doc.show boleto.data_documento.to_s_br if boleto.data_documento
|
105
185
|
doc.moveto :x => '4.2 cm' , :y => '14.4 cm'
|
106
|
-
doc.show
|
186
|
+
doc.show boleto.numero_documento
|
107
187
|
doc.moveto :x => '10 cm' , :y => '14.4 cm'
|
108
|
-
doc.show
|
188
|
+
doc.show boleto.especie
|
109
189
|
doc.moveto :x => '11.7 cm' , :y => '14.4 cm'
|
110
|
-
doc.show
|
190
|
+
doc.show boleto.aceite
|
111
191
|
doc.moveto :x => '13 cm' , :y => '14.4 cm'
|
112
|
-
doc.show
|
192
|
+
doc.show boleto.data_processamento.to_s_br if boleto.data_processamento
|
113
193
|
doc.moveto :x => '16.5 cm' , :y => '14.4 cm'
|
114
|
-
doc.show
|
194
|
+
doc.show boleto.nosso_numero_boleto
|
115
195
|
doc.moveto :x => '4.4 cm' , :y => '13.5 cm'
|
116
|
-
doc.show
|
196
|
+
doc.show boleto.carteira
|
117
197
|
doc.moveto :x => '6.4 cm' , :y => '13.5 cm'
|
118
|
-
doc.show
|
198
|
+
doc.show boleto.moeda
|
119
199
|
doc.moveto :x => '8 cm' , :y => '13.5 cm'
|
120
|
-
doc.show
|
200
|
+
doc.show boleto.quantidade
|
121
201
|
doc.moveto :x => '11 cm' , :y => '13.5 cm'
|
122
|
-
doc.show
|
202
|
+
doc.show boleto.valor.to_currency
|
123
203
|
doc.moveto :x => '16.5 cm' , :y => '13.5 cm'
|
124
|
-
doc.show
|
204
|
+
doc.show boleto.valor_documento.to_currency
|
125
205
|
doc.moveto :x => '0.7 cm' , :y => '12.7 cm'
|
126
|
-
doc.show
|
206
|
+
doc.show boleto.instrucao1
|
127
207
|
doc.moveto :x => '0.7 cm' , :y => '12.3 cm'
|
128
|
-
doc.show
|
208
|
+
doc.show boleto.instrucao2
|
129
209
|
doc.moveto :x => '0.7 cm' , :y => '11.9 cm'
|
130
|
-
doc.show
|
210
|
+
doc.show boleto.instrucao3
|
131
211
|
doc.moveto :x => '0.7 cm' , :y => '11.5 cm'
|
132
|
-
doc.show
|
212
|
+
doc.show boleto.instrucao4
|
133
213
|
doc.moveto :x => '0.7 cm' , :y => '11.1 cm'
|
134
|
-
doc.show
|
214
|
+
doc.show boleto.instrucao5
|
135
215
|
doc.moveto :x => '0.7 cm' , :y => '10.7 cm'
|
136
|
-
doc.show
|
216
|
+
doc.show boleto.instrucao6
|
137
217
|
doc.moveto :x => '1.2 cm' , :y => '8.8 cm'
|
138
|
-
doc.show "#{
|
218
|
+
doc.show "#{boleto.sacado} - #{boleto.sacado_documento.formata_documento}" if boleto.sacado && boleto.sacado_documento
|
139
219
|
doc.moveto :x => '1.2 cm' , :y => '8.4 cm'
|
140
|
-
doc.show "#{
|
220
|
+
doc.show "#{boleto.sacado_endereco}"
|
141
221
|
#FIM Segunda parte do BOLETO
|
142
|
-
|
143
|
-
#Gerando codigo de barra com rghost_barcode
|
144
|
-
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
|
145
|
-
|
146
|
-
# Gerando stream
|
147
|
-
options[:tipo] = options[:tipo].to_sym unless options[:tipo].kind_of?(Symbol)
|
148
|
-
doc.render_stream(options[:tipo])
|
149
222
|
end
|
150
|
-
|
223
|
+
|
224
|
+
end #Base
|
151
225
|
end
|
152
226
|
end
|
153
227
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module Brcobranca
|
3
|
+
module Boleto
|
4
|
+
class Unibanco < Base # Banco UNIBANCO
|
5
|
+
|
6
|
+
# Com Registro 4
|
7
|
+
# Sem Registro 5
|
8
|
+
validates_inclusion_of :carteira, :in => %w( 5 4 ), :message => "não existente para este banco."
|
9
|
+
validates_length_of :agencia, :maximum => 4, :message => "deve ser menor ou igual a 4 dígitos."
|
10
|
+
validates_length_of :convenio, :maximum => 7, :message => "deve ser menor ou igual a 7 dígitos."
|
11
|
+
validates_length_of :conta_corrente, :maximum => 7, :message => "deve ser menor ou igual a 7 dígitos."
|
12
|
+
|
13
|
+
validates_each :numero_documento do |record, attr, value|
|
14
|
+
record.errors.add attr, 'deve ser menor ou igual a 14 dígitos.' if (value.to_s.size > 14) && (record.carteira.to_i == 5)
|
15
|
+
record.errors.add attr, 'deve ser menor ou igual a 11 dígitos.' if (value.to_s.size > 11) && (record.carteira.to_i == 4)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Nova instancia do Unibanco
|
19
|
+
# @param (see Brcobranca::Boleto::Base#initialize)
|
20
|
+
def initialize(campos={})
|
21
|
+
campos = {:carteira => "5"}.merge!(campos)
|
22
|
+
super(campos)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Codigo do banco emissor (3 dígitos sempre)
|
26
|
+
#
|
27
|
+
# @return [String] 3 caracteres numéricos.
|
28
|
+
def banco
|
29
|
+
"409"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Número do convênio/contrato do cliente junto ao banco.
|
33
|
+
# @return [String] 7 caracteres numéricos.
|
34
|
+
def convenio=(valor)
|
35
|
+
@convenio = valor.to_s.rjust(7,'0') unless valor.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
# Número seqüencial utilizado para identificar o boleto.
|
39
|
+
#
|
40
|
+
# Carteira 5 = 14 caracteres numéricos.<br/>
|
41
|
+
# Carteira 4 = 11 caracteres numéricos.
|
42
|
+
#
|
43
|
+
# @return [String]
|
44
|
+
def numero_documento
|
45
|
+
case self.carteira.to_i
|
46
|
+
when 5
|
47
|
+
@numero_documento.to_s.rjust(14,'0')
|
48
|
+
else #4
|
49
|
+
@numero_documento.to_s.rjust(11,'0')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Dígito verificador do nosso número.
|
54
|
+
# @return [String] 1 caracteres numéricos.
|
55
|
+
def nosso_numero_dv
|
56
|
+
self.numero_documento.modulo11_2to9
|
57
|
+
end
|
58
|
+
|
59
|
+
# Nosso número para exibir no boleto.
|
60
|
+
# @return [String]
|
61
|
+
# @example
|
62
|
+
# boleto.nosso_numero_boleto #=> "00085068014982-9"
|
63
|
+
def nosso_numero_boleto
|
64
|
+
"#{self.numero_documento}-#{self.nosso_numero_dv}"
|
65
|
+
end
|
66
|
+
|
67
|
+
# Número do convênio/contrato do cliente para exibir no boleto.
|
68
|
+
# @return [String]
|
69
|
+
# @example
|
70
|
+
# boleto.agencia_conta_boleto #=> "0123 / 0100618-5"
|
71
|
+
def agencia_conta_boleto
|
72
|
+
"#{self.agencia} / #{self.conta_corrente}-#{self.conta_corrente_dv}"
|
73
|
+
end
|
74
|
+
|
75
|
+
# Segunda parte do código de barras.
|
76
|
+
#
|
77
|
+
# Cobrança sem registro (CÓDIGO DE BARRAS)<br/>
|
78
|
+
# Posição | Tamanho | Descrição<br/>
|
79
|
+
# 1 a 3 | 3 | número de identificação do Unibanco: 409 (número FIXO)<br/>
|
80
|
+
# 4 | 1 | código da moeda. Real (R$)=9 (número FIXO)<br/>
|
81
|
+
# 5 | 1 | dígito verificador do CÓDIGO DE BARRAS<br/>
|
82
|
+
# 6 a 9 | 4 | fator de vencimento<br/>
|
83
|
+
# 10 a 19 | 10 | valor do título com zeros à esquerda<br/>
|
84
|
+
# 20 | 1 | código para transação CVT: 5 (número FIXO)(5=7744-5)<br/>
|
85
|
+
# 21 a 27 | 7 | número do cliente no CÓDIGO DE BARRAS + dígito verificador<br/>
|
86
|
+
# 28 a 29 | 2 | vago. Usar 00 (número FIXO)<br/>
|
87
|
+
# 30 a 43 | 14 | Número de referência do cliente<br/>
|
88
|
+
# 44 | 1 | Dígito verificador<br/>
|
89
|
+
#
|
90
|
+
# Cobrança com registro (CÓDIGO DE BARRAS)<br/>
|
91
|
+
# Posição | Tamanho | Descrição<br/>
|
92
|
+
# 1 a 3 | 3 | Número de identificação do Unibanco: 409 (número FIXO)<br/>
|
93
|
+
# 4 | 1 | Código da moeda. Real (R$)=9 (número FIXO)<br/>
|
94
|
+
# 5 | 1 | dígito verificador do CÓDIGO DE BARRAS<br/>
|
95
|
+
# 6 a 9 | 4 | fator de vencimento em 4 algarismos, conforme tabela da página 14<br/>
|
96
|
+
# 10 a 19 | 10 | valor do título com zeros à esquerda<br/>
|
97
|
+
# 20 a 21 | 2 | Código para transação CVT: 04 (número FIXO) (04=5539-5)<br/>
|
98
|
+
# 22 a 27 | 6 | data de vencimento (AAMMDD)<br/>
|
99
|
+
# 28 a 32 | 5 | Código da agência + dígito verificador<br/>
|
100
|
+
# 33 a 43 | 11 | “Nosso Número” (NNNNNNNNNNN)<br/>
|
101
|
+
# 44 | 1 Super dígito do “Nosso Número” (calculado com o MÓDULO 11 (de 2 a 9))<br/>
|
102
|
+
#
|
103
|
+
# @return [String] 25 caracteres numéricos.
|
104
|
+
def codigo_barras_segunda_parte
|
105
|
+
case self.carteira.to_i
|
106
|
+
when 5
|
107
|
+
"#{self.carteira}#{self.convenio}00#{self.numero_documento}#{self.nosso_numero_dv}"
|
108
|
+
else # 4
|
109
|
+
data = self.data_vencimento.strftime('%y%m%d')
|
110
|
+
"0#{self.carteira}#{data}#{self.agencia}#{self.agencia_dv}#{self.numero_documento}#{self.nosso_numero_dv}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# @author Kivanio Barbosa
|
3
|
+
module Brcobranca
|
4
|
+
# Métodos auxiliares de cálculos
|
5
|
+
module Calculo
|
6
|
+
# Calcula módulo 10 segundo a BACEN.
|
7
|
+
#
|
8
|
+
# @return [Integer]
|
9
|
+
# @raise [ArgumentError] Caso não seja um número inteiro.
|
10
|
+
def modulo10
|
11
|
+
raise ArgumentError, "Número inválido" unless self.is_number?
|
12
|
+
|
13
|
+
total = 0
|
14
|
+
multiplicador = 2
|
15
|
+
|
16
|
+
self.to_s.split(//).reverse!.each do |caracter|
|
17
|
+
total += (caracter.to_i * multiplicador).soma_digitos
|
18
|
+
multiplicador = multiplicador == 2 ? 1 : 2
|
19
|
+
end
|
20
|
+
|
21
|
+
valor = (10 - (total % 10))
|
22
|
+
valor == 10 ? 0 : valor
|
23
|
+
end
|
24
|
+
|
25
|
+
# Calcula módulo 10 do Banespa.
|
26
|
+
#
|
27
|
+
# @return [Integer]
|
28
|
+
# @raise [ArgumentError] Caso não seja um número inteiro.
|
29
|
+
def modulo_10_banespa
|
30
|
+
raise ArgumentError, "Número inválido" unless self.is_number?
|
31
|
+
|
32
|
+
fatores = [7,3,1,9,7,3,1,9,7,3]
|
33
|
+
total = 0
|
34
|
+
posicao = 0
|
35
|
+
self.to_s.split(//).each do |digito|
|
36
|
+
total += (digito.to_i * fatores[posicao]).to_s.split(//)[-1].to_i
|
37
|
+
posicao = (posicao < (fatores.size - 1)) ? (posicao + 1) : 0
|
38
|
+
end
|
39
|
+
dv = 10 - total.to_s.split(//)[-1].to_i
|
40
|
+
dv == 10 ? 0 : dv
|
41
|
+
end
|
42
|
+
|
43
|
+
# Calcula módulo 11 com multiplicaroes de 9 a 2 segundo a BACEN.
|
44
|
+
#
|
45
|
+
# @return [Integer]
|
46
|
+
def modulo11_9to2
|
47
|
+
total = self.multiplicador([9,8,7,6,5,4,3,2])
|
48
|
+
|
49
|
+
return (total % 11 )
|
50
|
+
end
|
51
|
+
|
52
|
+
# Calcula módulo 11 com multiplicaroes de 2 a 9 segundo a BACEN.
|
53
|
+
#
|
54
|
+
# @return [Integer]
|
55
|
+
def modulo11_2to9
|
56
|
+
total = self.multiplicador([2,3,4,5,6,7,8,9])
|
57
|
+
|
58
|
+
valor = (11 - (total % 11))
|
59
|
+
return [0,10,11].include?(valor) ? 1 : valor
|
60
|
+
end
|
61
|
+
|
62
|
+
# Calcula módulo 11 com multiplicaroes de 9 a 2 trocando retorno <b>10 por X</b>.
|
63
|
+
#
|
64
|
+
# @return [Integer, String] Caso resultado for 10, retorna X.
|
65
|
+
def modulo11_9to2_10_como_x
|
66
|
+
valor = self.modulo11_9to2
|
67
|
+
valor == 10 ? "X" : valor
|
68
|
+
end
|
69
|
+
|
70
|
+
# Calcula módulo 11 com multiplicaroes de 9 a 2 trocando retorno <b>10 por 0</b>.
|
71
|
+
#
|
72
|
+
# @return [Integer]
|
73
|
+
def modulo11_9to2_10_como_zero
|
74
|
+
valor = self.modulo11_9to2
|
75
|
+
valor == 10 ? 0 : valor
|
76
|
+
end
|
77
|
+
|
78
|
+
# Verifica se String só contem caracteres numéricos.
|
79
|
+
#
|
80
|
+
# @return [Boolean]
|
81
|
+
def is_number?
|
82
|
+
self.to_s.empty? ? false : (self.to_s =~ (/\D/)).nil?
|
83
|
+
end
|
84
|
+
|
85
|
+
# Soma dígitos de números inteiros positivos com 2 dígitos ou mais.
|
86
|
+
#
|
87
|
+
# @return [Integer]
|
88
|
+
# @example
|
89
|
+
# 1 #=> 1
|
90
|
+
# 11 (1+1) #=> 2
|
91
|
+
# 13 (1+3) #=> 4
|
92
|
+
def soma_digitos
|
93
|
+
total = case self.to_i
|
94
|
+
when (0..9)
|
95
|
+
self
|
96
|
+
else
|
97
|
+
numero = self.to_s
|
98
|
+
total = 0
|
99
|
+
0.upto(numero.size-1) {|digito| total += numero[digito,1].to_i }
|
100
|
+
total
|
101
|
+
end
|
102
|
+
total.to_i
|
103
|
+
end
|
104
|
+
|
105
|
+
# Faz a multiplicação de um número pelos fatores passados como parâmetro.
|
106
|
+
#
|
107
|
+
# @param [Array]
|
108
|
+
# @return [Integer]
|
109
|
+
# @raise [ArgumentError] Caso não seja um número inteiro.
|
110
|
+
def multiplicador(fatores, &block)
|
111
|
+
raise ArgumentError, "Número inválido" unless self.is_number?
|
112
|
+
|
113
|
+
total = 0
|
114
|
+
multiplicador_posicao = 0
|
115
|
+
|
116
|
+
self.to_s.split(//).reverse!.each do |caracter|
|
117
|
+
fator = fatores[multiplicador_posicao]
|
118
|
+
total += if block_given?
|
119
|
+
yield(caracter, fator)
|
120
|
+
else
|
121
|
+
(caracter.to_i * fator)
|
122
|
+
end
|
123
|
+
multiplicador_posicao = (multiplicador_posicao < (fatores.size - 1)) ? (multiplicador_posicao + 1) : 0
|
124
|
+
end
|
125
|
+
total
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
[ String, Numeric ].each do |klass|
|
131
|
+
klass.class_eval { include Brcobranca::Calculo }
|
132
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# @author Kivanio Barbosa
|
3
|
+
module Brcobranca
|
4
|
+
# Métodos auxiliares de cálculos envolvendo Datas.
|
5
|
+
module CalculoData
|
6
|
+
# 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> desejada.
|
7
|
+
# @return [String] Contendo 4 dígitos
|
8
|
+
# @example
|
9
|
+
# Date.parse(2000-07-04).fator_vencimento #=> 1001
|
10
|
+
def fator_vencimento
|
11
|
+
data_base = Date.parse "1997-10-07"
|
12
|
+
Integer(self - data_base).to_s.rjust(4,'0')
|
13
|
+
end
|
14
|
+
|
15
|
+
# Mostra a data em formato <b>dia/mês/ano</b>
|
16
|
+
# @return [String]
|
17
|
+
# @example
|
18
|
+
# Date.today.to_s_br #=> 20/01/2010
|
19
|
+
def to_s_br
|
20
|
+
self.strftime('%d/%m/%Y')
|
21
|
+
end
|
22
|
+
# Calcula número de dias julianos.
|
23
|
+
#
|
24
|
+
# O cálculo é feito subtraindo-se a data atual, pelo último dia válido do ano anterior,
|
25
|
+
# acrescentando-se o último algarismo do ano atual na quarta posição.
|
26
|
+
#
|
27
|
+
# @return [String] contendo 4 dígitos
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# Date.parse(2009-02-11).to_juliano #=> "0429"
|
31
|
+
def to_juliano
|
32
|
+
ultima_data = Date.parse("#{self.year - 1}-12-31")
|
33
|
+
ultimo_digito_ano = self.to_s[3..3]
|
34
|
+
dias = Integer(self - ultima_data)
|
35
|
+
(dias.to_s + ultimo_digito_ano).rjust(4,'0')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
[ Date ].each do |klass|
|
41
|
+
klass.class_eval { include Brcobranca::CalculoData }
|
42
|
+
end
|
data/lib/brcobranca/currency.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
#
|
2
|
-
# post http://simplesideias.com.br/usando-number_to_currency-em-modelos-no-rails
|
1
|
+
# @author Fernando Vieira do http://simplesideias.com.br
|
3
2
|
module Brcobranca #:nodoc:[all]
|
4
3
|
module Currency #:nodoc:[all]
|
4
|
+
# Implementação feita por Fernando Vieira do http://simplesideias.com.br
|
5
|
+
# post http://simplesideias.com.br/usando-number_to_currency-em-modelos-no-rails
|
5
6
|
BRL = {:delimiter => ".", :separator => ",", :unit => "R$", :precision => 2, :position => "before"}
|
6
7
|
USD = {:delimiter => ',', :separator => ".", :unit => "US$", :precision => 2, :position => "before"}
|
7
8
|
DEFAULT = BRL.merge(:unit => "")
|
@@ -56,8 +57,6 @@ module Brcobranca #:nodoc:[all]
|
|
56
57
|
end
|
57
58
|
end
|
58
59
|
|
59
|
-
# TODO - porque não incluir somente na Numeric?
|
60
|
-
# [ Fixnum, Bignum, Float ].each do |klass|
|
61
60
|
[ Numeric].each do |klass|
|
62
61
|
klass.class_eval { include Brcobranca::Currency::Number }
|
63
62
|
end
|