boleto_bancario 0.0.1.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Changelog.markdown +6 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/Planning.markdown +131 -0
- data/README.markdown +208 -0
- data/Rakefile +9 -0
- data/TODO.markdown +5 -0
- data/boleto_bancario.gemspec +25 -0
- data/documentacoes_dos_boletos/Bradesco/Manual_BRADESCO.PDF +0 -0
- data/lib/boleto_bancario/calculos/digitos.rb +35 -0
- data/lib/boleto_bancario/calculos/fator_vencimento.rb +87 -0
- data/lib/boleto_bancario/calculos/fatores_de_multiplicacao.rb +67 -0
- data/lib/boleto_bancario/calculos/linha_digitavel.rb +158 -0
- data/lib/boleto_bancario/calculos/modulo10.rb +83 -0
- data/lib/boleto_bancario/calculos/modulo11.rb +54 -0
- data/lib/boleto_bancario/calculos/modulo11_fator_de2a7.rb +97 -0
- data/lib/boleto_bancario/calculos/modulo11_fator_de2a9.rb +83 -0
- data/lib/boleto_bancario/calculos/modulo11_fator_de2a9_resto_zero.rb +29 -0
- data/lib/boleto_bancario/calculos/modulo11_fator_de9a2_resto_x.rb +101 -0
- data/lib/boleto_bancario/core/banco_brasil.rb +532 -0
- data/lib/boleto_bancario/core/boleto.rb +525 -0
- data/lib/boleto_bancario/core/bradesco.rb +285 -0
- data/lib/boleto_bancario/core/itau.rb +455 -0
- data/lib/boleto_bancario/core/santander.rb +274 -0
- data/lib/boleto_bancario/version.rb +4 -0
- data/lib/boleto_bancario.rb +83 -0
- data/spec/boleto_bancario/calculos/digitos_spec.rb +19 -0
- data/spec/boleto_bancario/calculos/fator_vencimento_spec.rb +59 -0
- data/spec/boleto_bancario/calculos/fatores_de_multiplicacao_spec.rb +69 -0
- data/spec/boleto_bancario/calculos/linha_digitavel_spec.rb +57 -0
- data/spec/boleto_bancario/calculos/modulo10_spec.rb +49 -0
- data/spec/boleto_bancario/calculos/modulo11_fator_de2a7_spec.rb +43 -0
- data/spec/boleto_bancario/calculos/modulo11_fator_de2a9_resto_zero_spec.rb +39 -0
- data/spec/boleto_bancario/calculos/modulo11_fator_de2a9_spec.rb +61 -0
- data/spec/boleto_bancario/calculos/modulo11_fator_de9a2_resto_x_spec.rb +37 -0
- data/spec/boleto_bancario/calculos/modulo11_spec.rb +19 -0
- data/spec/boleto_bancario/core/banco_brasil_spec.rb +383 -0
- data/spec/boleto_bancario/core/boleto_spec.rb +102 -0
- data/spec/boleto_bancario/core/bradesco_spec.rb +170 -0
- data/spec/boleto_bancario/core/itau_spec.rb +336 -0
- data/spec/boleto_bancario/core/santander_spec.rb +135 -0
- data/spec/shared_examples/boleto_bancario_shared_example.rb +164 -0
- data/spec/spec_helper.rb +14 -0
- metadata +221 -0
@@ -0,0 +1,158 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'active_support/core_ext/object'
|
3
|
+
|
4
|
+
module BoletoBancario
|
5
|
+
module Calculos
|
6
|
+
# Representação numérica do código de barras, mais conhecida como linha digitável! :p
|
7
|
+
#
|
8
|
+
# A representação numérica do código de barras é composta, por cinco campos.
|
9
|
+
# Sendo os três primeiros campos, amarrados por DAC's (dígitos verificadores),
|
10
|
+
# todos calculados pelo módulo 10.
|
11
|
+
#
|
12
|
+
# <b>OBS.:</b> Para mais detalhes deste cálculo, veja a descrição em Modulo10.
|
13
|
+
#
|
14
|
+
# === Linha Digitável
|
15
|
+
#
|
16
|
+
# A linha digitável contêm exatamente 47 posições nessa sequência:
|
17
|
+
#
|
18
|
+
# _____________________________________________________________________________________________________________
|
19
|
+
# |Campo | Posição | Tamanho | Descrição |
|
20
|
+
# |------|----------|---------|--------------------------------------------------------------------------------|
|
21
|
+
# | 1º | 01-03 | 03 | Código do banco (posições 1 a 3 do código de barras) |
|
22
|
+
# | | 04 | 01 | Código da moeda (posição 4 do código de barras) |
|
23
|
+
# | | 05-09 | 5 | Cinco primeiras posições do campo livre (posições 20 a 24 do código de barras) |
|
24
|
+
# | | 10 | 1 | Dígito verificador do primeiro campo (Módulo10) |
|
25
|
+
# |------------------------------------------------------------------------------------------------------------|
|
26
|
+
# | 2º | 11-20 | 10 | 6º a 15º posições do campo livre (posições 25 a 34 do código de barras) |
|
27
|
+
# | | 21 | 01 | Dígito verificador do segundo campo (Módulo10) |
|
28
|
+
# |------------------------------------------------------------------------------------------------------------|
|
29
|
+
# | 3º | 22-31 | 10 | 16º a 25º posições do campo livre (posições 35 a 44 do código de barras) |
|
30
|
+
# | | 32 | 01 | Dígito verificador do terceiro campo (Módulo10) |
|
31
|
+
# |------------------------------------------------------------------------------------------------------------|
|
32
|
+
# | 4º | 33 | 01 | Dígito verificador do código de barras (posição 5 do código de barras) |
|
33
|
+
# |------------------------------------------------------------------------------------------------------------|
|
34
|
+
# | 5ª | 34-37 | 04 | Fator de vencimento (posições 6 a 9 do código de barras) |
|
35
|
+
# | | 38-47 | 10 | Valor nominal do documento (posições 10 a 19 do código de barras) |
|
36
|
+
# -------------------------------------------------------------------------------------------------------------|
|
37
|
+
#
|
38
|
+
# @return [String] Contêm a representação numérica do código de barras formatado com pontos e espaços.
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
#
|
42
|
+
# LinhaDigitavel.new('34196166700000123451091234567880057123457000')
|
43
|
+
# # => '34191.09123 34567.880058 71234.570001 6 16670000012345'
|
44
|
+
#
|
45
|
+
# LinhaDigitavel.new('99991101200000350007772130530150081897500000')
|
46
|
+
# # => '99997.77213 30530.150082 18975.000003 1 10120000035000'
|
47
|
+
#
|
48
|
+
# LinhaDigitavel.new('39998100100000311551111122222500546666666001')
|
49
|
+
# # => '39991.11119 22222.500542 66666.660015 8 10010000031155'
|
50
|
+
#
|
51
|
+
class LinhaDigitavel < String
|
52
|
+
attr_reader :codigo_de_barras
|
53
|
+
# @param [String] codigo_de_barras Código de Barras de 44 posições
|
54
|
+
# @return [String]
|
55
|
+
#
|
56
|
+
# Representação numérica do código de barras
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
#
|
60
|
+
# LinhaDigitavel.new('34196166700000123451091234567880057123457000')
|
61
|
+
# # => '34191.09123 34567.880058 71234.570001 6 16670000012345'
|
62
|
+
#
|
63
|
+
# LinhaDigitavel.new('99991101200000350007772130530150081897500000')
|
64
|
+
# # => '99997.77213 30530.150082 18975.000003 1 10120000035000'
|
65
|
+
#
|
66
|
+
# LinhaDigitavel.new('39998100100000311551111122222500546666666001')
|
67
|
+
# # => '39991.11119 22222.500542 66666.660015 8 10010000031155'
|
68
|
+
#
|
69
|
+
# # Retorna uma String vazia caso o código de barras esteja vazio.
|
70
|
+
# LinhaDigitavel.new('')
|
71
|
+
# # => ''
|
72
|
+
#
|
73
|
+
# # Retorna uma String vazia caso o código de barras esteja vazio.
|
74
|
+
# LinhaDigitavel.new(nil)
|
75
|
+
# # => ''
|
76
|
+
#
|
77
|
+
# # Retorna uma String vazia caso o código de barras seja menor que 44 posições.
|
78
|
+
# LinhaDigitavel.new('123456789')
|
79
|
+
# # => ''
|
80
|
+
#
|
81
|
+
# # Retorna uma String vazia caso o código de barras seja maior que 44 posições.
|
82
|
+
# LinhaDigitavel.new('12345678901234567890123456789012345678901234567890')
|
83
|
+
# # => ''
|
84
|
+
#
|
85
|
+
def initialize(codigo_de_barras)
|
86
|
+
@codigo_de_barras = codigo_de_barras.to_s
|
87
|
+
|
88
|
+
if @codigo_de_barras.present? and @codigo_de_barras.size == 44
|
89
|
+
super(representacao_numerica_do_codigo_de_barras)
|
90
|
+
else
|
91
|
+
super('')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# @return [String] Retorna todos os campos da linha digitável pegando as posições exatas do código de barras.
|
96
|
+
#
|
97
|
+
def representacao_numerica_do_codigo_de_barras
|
98
|
+
"#{primeiro_campo} #{segundo_campo} #{terceiro_campo} #{quarto_campo} #{quinto_campo}"
|
99
|
+
end
|
100
|
+
|
101
|
+
# @api private
|
102
|
+
#
|
103
|
+
# Retorna o primeiro campo da linha digitável com seu respectivo dígito verificador.
|
104
|
+
#
|
105
|
+
# @return [String]
|
106
|
+
#
|
107
|
+
def primeiro_campo
|
108
|
+
primeiro_campo_sem_digito = "#{codigo_de_barras[0..3]}#{codigo_de_barras[19..23]}"
|
109
|
+
digito_verificador = Modulo10.new(primeiro_campo_sem_digito)
|
110
|
+
"#{primeiro_campo_sem_digito}#{digito_verificador}".gsub(/^(.{5})(.{5})/, '\1.\2')
|
111
|
+
end
|
112
|
+
|
113
|
+
# @api private
|
114
|
+
#
|
115
|
+
# Retorna o segundo campo da linha digitável com seu respectivo dígito verificador.
|
116
|
+
#
|
117
|
+
# @return [String]
|
118
|
+
#
|
119
|
+
def segundo_campo
|
120
|
+
segundo_campo_sem_digito = "#{codigo_de_barras[24..33]}"
|
121
|
+
digito_verificador = Modulo10.new(segundo_campo_sem_digito)
|
122
|
+
"#{segundo_campo_sem_digito}#{digito_verificador}".gsub(/(.{5})(.{6})/, '\1.\2')
|
123
|
+
end
|
124
|
+
|
125
|
+
# @api private
|
126
|
+
#
|
127
|
+
# Retorna o terceiro campo da linha digitável com seu respectivo dígito verificador.
|
128
|
+
#
|
129
|
+
# @return [String]
|
130
|
+
#
|
131
|
+
def terceiro_campo
|
132
|
+
terceiro_campo_sem_digito = "#{codigo_de_barras[34..46]}"
|
133
|
+
digito_verificador = Modulo10.new(terceiro_campo_sem_digito)
|
134
|
+
"#{terceiro_campo_sem_digito}#{digito_verificador}".gsub(/(.{5})(.{6})/, '\1.\2')
|
135
|
+
end
|
136
|
+
|
137
|
+
# @api private
|
138
|
+
#
|
139
|
+
# Retorna o dígito verificador do código de barras (posição 5 do código de barras)
|
140
|
+
#
|
141
|
+
# @return [String]
|
142
|
+
#
|
143
|
+
def quarto_campo
|
144
|
+
"#{codigo_de_barras[4]}"
|
145
|
+
end
|
146
|
+
|
147
|
+
# @api private
|
148
|
+
#
|
149
|
+
# Retorna o quinto e último campo da linha digitável.
|
150
|
+
#
|
151
|
+
# @return [String]
|
152
|
+
#
|
153
|
+
def quinto_campo
|
154
|
+
"#{codigo_de_barras[5..8]}#{codigo_de_barras[9..18]}"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module BoletoBancario
|
3
|
+
module Calculos
|
4
|
+
# === Cálculo do Modulo 10
|
5
|
+
#
|
6
|
+
# === Passos
|
7
|
+
#
|
8
|
+
# 1) Multiplica-se cada algarismo do campo pela seqüência de multiplicadores <b>2, 1, 2, 1, 2, 1 ...</b>, posicionados da direita para a esquerda.
|
9
|
+
#
|
10
|
+
# 2) Some individualmente, os algarismos dos resultados dos produtos, obtendo-se o total (N).
|
11
|
+
#
|
12
|
+
# 3) Divida o total encontrado (N) por 10, e determine o resto da divisão como MOD 10 (N).
|
13
|
+
#
|
14
|
+
# 4) Encontre o DAC através da seguinte expressão:
|
15
|
+
#
|
16
|
+
# DAC = 10 - Mod 10 (n)
|
17
|
+
#
|
18
|
+
# <b>OBS.:</b> Se o resultado do passo 4 for 10, considere o DAC = 0.
|
19
|
+
#
|
20
|
+
# ==== Exemplos
|
21
|
+
#
|
22
|
+
# Considerando-se a seguinte representação numérica <b>'12345'</b>.
|
23
|
+
#
|
24
|
+
# 1) Multiplicando a seqüência de multiplicadores:
|
25
|
+
#
|
26
|
+
# 1 2 3 4 5
|
27
|
+
# * * * * * ===> Multiplicação.
|
28
|
+
# 2 1 2 1 2
|
29
|
+
#
|
30
|
+
# 2) Some, individualmente:
|
31
|
+
#
|
32
|
+
# 2 + 2 + 6 + 4 + 1 + 0 (Veja a observação abaixo explicando o '1' + '0').
|
33
|
+
# # => 15
|
34
|
+
#
|
35
|
+
# <b>OBS.:</b>: Resultado da soma que possua 2 digitos deve somar cada dígito.
|
36
|
+
# Exemplos: 10 -> 1 + 0. 11 -> 1 + 1, 28 -> 2 + 8, etc.
|
37
|
+
#
|
38
|
+
# 3) Divida o total encontrado por 10, a fim de determinar o resto da divisão:
|
39
|
+
#
|
40
|
+
# 15 % 10
|
41
|
+
# # => 5
|
42
|
+
#
|
43
|
+
# 4) Calculando o DAC:
|
44
|
+
#
|
45
|
+
# 10 - 5
|
46
|
+
# # => 5 =======> Resultado final retornado.
|
47
|
+
#
|
48
|
+
class Modulo10 < String
|
49
|
+
# @param [String ou Integer] number (Corresponde ao número a ser calculado pelo Módulo 10)
|
50
|
+
# @return [String]
|
51
|
+
# @example
|
52
|
+
#
|
53
|
+
# BoletoBancario::Calculos::Modulo10.new(1233)
|
54
|
+
# # => "6"
|
55
|
+
#
|
56
|
+
# BoletoBancario::Calculos::Modulo10.new(4411)
|
57
|
+
# # => "5"
|
58
|
+
#
|
59
|
+
# BoletoBancario::Calculos::Modulo10.new('9000')
|
60
|
+
# # => "1"
|
61
|
+
#
|
62
|
+
# BoletoBancario::Calculos::Modulo10.new('6789')
|
63
|
+
# # => "2"
|
64
|
+
#
|
65
|
+
def initialize(number)
|
66
|
+
@number = number
|
67
|
+
super(calculate.to_s)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [String] Resultado final do cálculo do módulo 10.
|
71
|
+
#
|
72
|
+
def calculate
|
73
|
+
sum_total = FatoresDeMultiplicacao.new(@number, fatores: [2, 1]).collect do |result_of_each_sum|
|
74
|
+
Digitos.new(result_of_each_sum).sum
|
75
|
+
end.sum
|
76
|
+
total = 10 - (sum_total % 10)
|
77
|
+
|
78
|
+
return 0 if total.equal?(10)
|
79
|
+
total
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module BoletoBancario
|
2
|
+
module Calculos
|
3
|
+
# Classe que possue a convenção de calculo do modulo 11.
|
4
|
+
# O que muda para cada classe é a forma de verificar o total do cálculo.
|
5
|
+
#
|
6
|
+
# @abstract Precisa implementar { #fatores, #calculate } nas subclasses.
|
7
|
+
#
|
8
|
+
class Modulo11 < String
|
9
|
+
# Número que será feito o cálculo do módulo 11.
|
10
|
+
#
|
11
|
+
attr_reader :number
|
12
|
+
|
13
|
+
# @param [String ou Integer] number (Corresponde ao número a ser calculado pelo Módulo 11)
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
def initialize(number)
|
17
|
+
@number = number
|
18
|
+
|
19
|
+
super(calculate.to_s)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Array] Fatores que serão multiplicados por cada digito do
|
23
|
+
# número passado como argumento no initialize.
|
24
|
+
# @raise [NotImplementedError] Precisa implementar na subclasse
|
25
|
+
#
|
26
|
+
def fatores
|
27
|
+
raise NotImplementedError, "Not implemented #fatores in subclass."
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Fixnum]
|
31
|
+
# @raise [NotImplementedError] Precisa implementar na subclasse
|
32
|
+
#
|
33
|
+
def calculate
|
34
|
+
raise NotImplementedError, "Not implemented #calculate in subclass."
|
35
|
+
end
|
36
|
+
|
37
|
+
# Realiza o cálculo retornando o resto da divisão do cálculo dos fatores por 11.
|
38
|
+
#
|
39
|
+
# @return [Fixnum] Resto da divisão por 11.
|
40
|
+
#
|
41
|
+
def mod_division
|
42
|
+
@mod_division ||= FatoresDeMultiplicacao.new(@number, fatores: fatores).sum % 11
|
43
|
+
end
|
44
|
+
|
45
|
+
# Subtrai 11 do resto da divisão para se ter o total do módulo 11.
|
46
|
+
#
|
47
|
+
# @return [Fixnum]
|
48
|
+
#
|
49
|
+
def total
|
50
|
+
@total ||= 11 - mod_division
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module BoletoBancario
|
2
|
+
module Calculos
|
3
|
+
# === Módulo 11 Fator de 2 a 7
|
4
|
+
#
|
5
|
+
# === Passos
|
6
|
+
#
|
7
|
+
# 1) Tomando-se os algarismos multiplique-os, iniciando-se da direita para a esquerda,
|
8
|
+
# pela seqüência numérica de 2 a 7 (2, 3, 4, 5, 6, 7 ... e assim por diante).
|
9
|
+
#
|
10
|
+
# 2) Some o resultado de cada produto efetuado e determine o total como (N).
|
11
|
+
#
|
12
|
+
# 3) Divida o total (N) por 11 e determine o resto obtido da divisão como Mod 11(N).
|
13
|
+
#
|
14
|
+
# 4) Calcule o dígito verificador (DAC) através da expressão:
|
15
|
+
#
|
16
|
+
# DIGIT = 11 - Mod 11 (n)
|
17
|
+
#
|
18
|
+
# <b>OBS.:</b> Se o resto da divisão for “1”, desprezar a diferença entre o divisor
|
19
|
+
# menos o resto que será “10” e considerar o dígito como “P”.
|
20
|
+
#
|
21
|
+
# <b>OBS.:</b> Se o resto da divisão for “0”, desprezar o cálculo de subtração entre
|
22
|
+
# divisor e resto, e considerar o “0” como dígito.
|
23
|
+
#
|
24
|
+
# ==== Exemplo
|
25
|
+
#
|
26
|
+
# Considerando o seguinte número: '89234560'.
|
27
|
+
#
|
28
|
+
# 1) Multiplicando a seqüência de multiplicadores:
|
29
|
+
#
|
30
|
+
# 1 9 0 0 0 0 0 0 0 0 0 0 2
|
31
|
+
# * * * * * * * * * * * * *
|
32
|
+
# 2 7 6 5 4 3 2 7 6 5 4 3 2
|
33
|
+
#
|
34
|
+
# 2) Soma-se o resultado dos produtos obtidos no item “1” acima:
|
35
|
+
#
|
36
|
+
# 2 + 63 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 4
|
37
|
+
# # => 69
|
38
|
+
#
|
39
|
+
# 3) Determina-se o resto da Divisão:
|
40
|
+
#
|
41
|
+
# 69 % 11
|
42
|
+
# # => 3
|
43
|
+
#
|
44
|
+
# 4) Calcula-se o DAC:
|
45
|
+
#
|
46
|
+
# 11 - 3
|
47
|
+
# # => 8 =============> Resultado final retornado.
|
48
|
+
#
|
49
|
+
# @param [String]: Corresponde ao número a ser calculado o Módulo 11 no fator de 2 a 7.
|
50
|
+
# @return [String] Retorna o resultado do cálculo descrito acima.
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
#
|
54
|
+
# BoletoBancario::Calculos::Modulo11FatorDe2a7.new('20')
|
55
|
+
# # => '5'
|
56
|
+
#
|
57
|
+
# BoletoBancario::Calculos::Modulo11FatorDe2a7.new('64')
|
58
|
+
# # => '7'
|
59
|
+
#
|
60
|
+
# BoletoBancario::Calculos::Modulo11FatorDe2a7.new('26')
|
61
|
+
# # => '4'
|
62
|
+
#
|
63
|
+
# BoletoBancario::Calculos::Modulo11FatorDe2a7.new('6')
|
64
|
+
# # => 'P'
|
65
|
+
#
|
66
|
+
# BoletoBancario::Calculos::Modulo11FatorDe2a7.new('14')
|
67
|
+
# # => '0'
|
68
|
+
#
|
69
|
+
class Modulo11FatorDe2a7 < Modulo11
|
70
|
+
# Sequência numérica de 2 a 7 que será feito a multiplicação de cada dígito
|
71
|
+
# do número passado no #initialize.
|
72
|
+
#
|
73
|
+
# @return [Array] Sequência numérica
|
74
|
+
#
|
75
|
+
def fatores
|
76
|
+
[2, 3, 4, 5, 6, 7]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Calcula o número pelos fatores de multiplicação de 2 a 7.
|
80
|
+
# Depois calcula o resto da divisão por 11 e subtrai por 11.
|
81
|
+
# Se o resultado desse cálculo for igual a 11, considere DAC = 0.
|
82
|
+
# Se o resultado desse cálculo for igual a 10, considere DAC = P.
|
83
|
+
#
|
84
|
+
# @return [Fixnum]
|
85
|
+
#
|
86
|
+
def calculate
|
87
|
+
return 0 if total.equal?(11)
|
88
|
+
|
89
|
+
if total == 10
|
90
|
+
'P'
|
91
|
+
else
|
92
|
+
total
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module BoletoBancario
|
3
|
+
module Calculos
|
4
|
+
# === Módulo 11 Fator de 2 a 9
|
5
|
+
#
|
6
|
+
# === Passos
|
7
|
+
#
|
8
|
+
# 1) Tomando-se os algarismos multiplique-os, iniciando-se da direita para a esquerda,
|
9
|
+
# pela seqüência numérica de 2 a 9 (2, 3, 4, 5, 6, 7, 8, 9 ... e assim por diante).
|
10
|
+
#
|
11
|
+
# 2) Some o resultado de cada produto efetuado e determine o total como (N).
|
12
|
+
#
|
13
|
+
# 3) Divida o total (N) por 11 e determine o resto obtido da divisão como Mod 11(N).
|
14
|
+
#
|
15
|
+
# 4) Calcule o dígito verificador (DAC) através da expressão:
|
16
|
+
#
|
17
|
+
# DIGIT = 11 - Mod 11 (n)
|
18
|
+
#
|
19
|
+
# <b>OBS.:</b> Se o resultado desta expressão for igual a 0, 1, 10 ou 11, considere DAC = 1.
|
20
|
+
#
|
21
|
+
# ==== Exemplo
|
22
|
+
#
|
23
|
+
# Considerando o seguinte número: '89234560'.
|
24
|
+
#
|
25
|
+
# 1) Multiplicando a seqüência de multiplicadores:
|
26
|
+
#
|
27
|
+
# 8 9 2 3 4 5 6 0
|
28
|
+
# * * * * * * * *
|
29
|
+
# 9 8 7 6 5 4 3 2
|
30
|
+
#
|
31
|
+
# 2) Soma-se o resultado dos produtos obtidos no item “1” acima:
|
32
|
+
#
|
33
|
+
# 72 + 72 + 14 + 18 + 20 + 20 + 18 + 0
|
34
|
+
# # => 234
|
35
|
+
#
|
36
|
+
# 3) Determina-se o resto da Divisão:
|
37
|
+
#
|
38
|
+
# 234 % 11
|
39
|
+
# # => 3
|
40
|
+
#
|
41
|
+
# 4) Calcula-se o DAC:
|
42
|
+
#
|
43
|
+
# 11 - 3
|
44
|
+
# # => 8 =============> Resultado final retornado.
|
45
|
+
#
|
46
|
+
# @param [String]: Corresponde ao número a ser calculado o Módulo 11 no fator de 2 a 9.
|
47
|
+
# @return [String] Retorna o resultado do cálculo descrito acima.
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
#
|
51
|
+
# BoletoBancario::Calculos::Modulo11FatorDe2a9.new('1')
|
52
|
+
# # => '9'
|
53
|
+
#
|
54
|
+
# BoletoBancario::Calculos::Modulo11FatorDe2a9.new('91')
|
55
|
+
# # => '4'
|
56
|
+
#
|
57
|
+
# BoletoBancario::Calculos::Modulo11FatorDe2a9.new('189')
|
58
|
+
# # => '9'
|
59
|
+
#
|
60
|
+
class Modulo11FatorDe2a9 < Modulo11
|
61
|
+
# Sequência numérica de 2 a 9 que será feito a multiplicação de cada dígito
|
62
|
+
# do número passado no #initialize.
|
63
|
+
#
|
64
|
+
# @return [Array] Sequência numérica
|
65
|
+
#
|
66
|
+
def fatores
|
67
|
+
[2, 3, 4, 5, 6, 7, 8, 9]
|
68
|
+
end
|
69
|
+
|
70
|
+
# Calcula o número pelos fatores de multiplicação de 2 a 9.
|
71
|
+
# Depois calcula o resto da divisão por 11 e subtrai por 11.
|
72
|
+
# Se o resultado desse cálculo for igual a 0, 1, 10 ou 11, considere DAC = 1.
|
73
|
+
#
|
74
|
+
# @return [Fixnum]
|
75
|
+
#
|
76
|
+
def calculate
|
77
|
+
return 1 if total > 9
|
78
|
+
|
79
|
+
total
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module BoletoBancario
|
2
|
+
module Calculos
|
3
|
+
# Classe responsável por calcular o módulo 11 com fatores de 2 a 9.
|
4
|
+
# <b>Essa classe difere da outra com Modulo11FatorDe2a9, no momento de verificar o resto da divisão por 11.</b>
|
5
|
+
#
|
6
|
+
# <b>Para mais detalhes veja a classe Modulo11FatorDe2a9.</b>
|
7
|
+
#
|
8
|
+
class Modulo11FatorDe2a9RestoZero < Modulo11FatorDe2a9
|
9
|
+
# Realiza o cálculo do módulo 11 com fatores de 2 a 9.
|
10
|
+
#
|
11
|
+
# === Resto Da divisão por 11
|
12
|
+
#
|
13
|
+
# * Se o resto da divisão por 11 for igual a 10, o digito será '1' (um),
|
14
|
+
# * Se o resto da divisão por 11 for igual a 1 (um) ou 0 (zero) o digito será 0 (zero).
|
15
|
+
#
|
16
|
+
# Qualquer “RESTO” diferente de “0, 1 ou 10”, subtrair o resto de 11 para obter o digíto.
|
17
|
+
#
|
18
|
+
# @return [Fixnum] Resultado da subtração ou resultado da verificação do resto da divisão.
|
19
|
+
#
|
20
|
+
def calculate
|
21
|
+
if mod_division.equal?(1) or mod_division.equal?(0)
|
22
|
+
0
|
23
|
+
else
|
24
|
+
total
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module BoletoBancario
|
2
|
+
module Calculos
|
3
|
+
# === Módulo 11 Fator de 9 a 2 - Resto 10, sendo X
|
4
|
+
#
|
5
|
+
# === Passos
|
6
|
+
#
|
7
|
+
# 1) Tomando-se os algarismos multiplique-os, iniciando-se da direita para a esquerda,
|
8
|
+
# pela seqüência numérica de 9 a 2 (9, 8, 7, 6, 5, 4, 3, 2 ... e assim por diante).
|
9
|
+
#
|
10
|
+
# 2) Some o resultado de cada produto efetuado e determine o total como (N).
|
11
|
+
#
|
12
|
+
# 3) Divida o total (N) por 11 e determine o resto obtido da divisão como Mod 11(N).
|
13
|
+
#
|
14
|
+
# <b>OBS.:</b> Se o resultado desta expressão for igual a 10, considere DAC = X.
|
15
|
+
#
|
16
|
+
# ==== Exemplo Normal
|
17
|
+
#
|
18
|
+
# Considerando o seguinte número: '89234560'.
|
19
|
+
#
|
20
|
+
# 1) Multiplicando a seqüência de multiplicadores:
|
21
|
+
#
|
22
|
+
# 8 9 2 3 4 5 6 0
|
23
|
+
# * * * * * * * *
|
24
|
+
# 2 3 4 5 6 7 8 9
|
25
|
+
#
|
26
|
+
# 2) Soma-se o resultado dos produtos obtidos no item “1” acima:
|
27
|
+
#
|
28
|
+
# 16 + 27 + 8 + 15 + 24 + 35 + 48 + 0
|
29
|
+
# # => 173
|
30
|
+
#
|
31
|
+
# 3) Determina-se o resto da Divisão:
|
32
|
+
#
|
33
|
+
# 173 % 11
|
34
|
+
# # => 8 =============> Resultado final retornado.
|
35
|
+
#
|
36
|
+
# ==== Exemplo 10 como resto da divisão
|
37
|
+
#
|
38
|
+
# Considerando o seguinte número: '100008'.
|
39
|
+
#
|
40
|
+
# 1) Multiplicando a seqüência de multiplicadores:
|
41
|
+
#
|
42
|
+
# 1 0 0 0 0 8
|
43
|
+
# * * * * * *
|
44
|
+
# 4 5 6 7 8 9
|
45
|
+
#
|
46
|
+
# 2) Soma-se o resultado dos produtos obtidos no item “1” acima:
|
47
|
+
#
|
48
|
+
# 4 + 0 + 0 + 0 + 0 + 72
|
49
|
+
# # => 76
|
50
|
+
#
|
51
|
+
# 3) Determina-se o resto da Divisão:
|
52
|
+
#
|
53
|
+
# 76 % 11
|
54
|
+
# # => 10
|
55
|
+
#
|
56
|
+
# 4) Quando o resultado for '10', o dígito será:
|
57
|
+
#
|
58
|
+
# resultado == 10
|
59
|
+
# # => 'X' =============> Resultado final retornado.
|
60
|
+
#
|
61
|
+
# @param [String]: Corresponde ao número a ser calculado o Módulo 11 no fator de 9 a 2.
|
62
|
+
# @return [String] Retorna o resultado do cálculo descrito acima.
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
#
|
66
|
+
# BoletoBancario::Calculos::Modulo11FatorDe9a2RestoX.new('12345')
|
67
|
+
# # => '5'
|
68
|
+
#
|
69
|
+
# BoletoBancario::Calculos::Modulo11FatorDe9a2RestoX.new('246')
|
70
|
+
# # => '1'
|
71
|
+
#
|
72
|
+
# BoletoBancario::Calculos::Modulo11FatorDe2a9.new('184122')
|
73
|
+
# # => 'X'
|
74
|
+
#
|
75
|
+
class Modulo11FatorDe9a2RestoX < Modulo11
|
76
|
+
# Sequência numérica de 9 a 2 que será feito a multiplicação de cada dígito
|
77
|
+
# do número passado no #initialize.
|
78
|
+
#
|
79
|
+
# @return [Array] Sequência numérica
|
80
|
+
#
|
81
|
+
def fatores
|
82
|
+
[9, 8, 7, 6, 5, 4, 3, 2]
|
83
|
+
end
|
84
|
+
|
85
|
+
# Calcula o número pelos fatores de multiplicação de 9 a 2.
|
86
|
+
# Depois calcula o resto da divisão por 11.
|
87
|
+
# Se o resultado desse cálculo for igual a 10, então o DAC = X.
|
88
|
+
# Se o resultado desse cálculo for menor que 10, retornar o resultado.
|
89
|
+
#
|
90
|
+
# @return [Fixnum]
|
91
|
+
#
|
92
|
+
def calculate
|
93
|
+
if mod_division.equal?(10)
|
94
|
+
'X'
|
95
|
+
else
|
96
|
+
mod_division
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|