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.
Files changed (47) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -0
  4. data/Changelog.markdown +6 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +22 -0
  7. data/Planning.markdown +131 -0
  8. data/README.markdown +208 -0
  9. data/Rakefile +9 -0
  10. data/TODO.markdown +5 -0
  11. data/boleto_bancario.gemspec +25 -0
  12. data/documentacoes_dos_boletos/Bradesco/Manual_BRADESCO.PDF +0 -0
  13. data/lib/boleto_bancario/calculos/digitos.rb +35 -0
  14. data/lib/boleto_bancario/calculos/fator_vencimento.rb +87 -0
  15. data/lib/boleto_bancario/calculos/fatores_de_multiplicacao.rb +67 -0
  16. data/lib/boleto_bancario/calculos/linha_digitavel.rb +158 -0
  17. data/lib/boleto_bancario/calculos/modulo10.rb +83 -0
  18. data/lib/boleto_bancario/calculos/modulo11.rb +54 -0
  19. data/lib/boleto_bancario/calculos/modulo11_fator_de2a7.rb +97 -0
  20. data/lib/boleto_bancario/calculos/modulo11_fator_de2a9.rb +83 -0
  21. data/lib/boleto_bancario/calculos/modulo11_fator_de2a9_resto_zero.rb +29 -0
  22. data/lib/boleto_bancario/calculos/modulo11_fator_de9a2_resto_x.rb +101 -0
  23. data/lib/boleto_bancario/core/banco_brasil.rb +532 -0
  24. data/lib/boleto_bancario/core/boleto.rb +525 -0
  25. data/lib/boleto_bancario/core/bradesco.rb +285 -0
  26. data/lib/boleto_bancario/core/itau.rb +455 -0
  27. data/lib/boleto_bancario/core/santander.rb +274 -0
  28. data/lib/boleto_bancario/version.rb +4 -0
  29. data/lib/boleto_bancario.rb +83 -0
  30. data/spec/boleto_bancario/calculos/digitos_spec.rb +19 -0
  31. data/spec/boleto_bancario/calculos/fator_vencimento_spec.rb +59 -0
  32. data/spec/boleto_bancario/calculos/fatores_de_multiplicacao_spec.rb +69 -0
  33. data/spec/boleto_bancario/calculos/linha_digitavel_spec.rb +57 -0
  34. data/spec/boleto_bancario/calculos/modulo10_spec.rb +49 -0
  35. data/spec/boleto_bancario/calculos/modulo11_fator_de2a7_spec.rb +43 -0
  36. data/spec/boleto_bancario/calculos/modulo11_fator_de2a9_resto_zero_spec.rb +39 -0
  37. data/spec/boleto_bancario/calculos/modulo11_fator_de2a9_spec.rb +61 -0
  38. data/spec/boleto_bancario/calculos/modulo11_fator_de9a2_resto_x_spec.rb +37 -0
  39. data/spec/boleto_bancario/calculos/modulo11_spec.rb +19 -0
  40. data/spec/boleto_bancario/core/banco_brasil_spec.rb +383 -0
  41. data/spec/boleto_bancario/core/boleto_spec.rb +102 -0
  42. data/spec/boleto_bancario/core/bradesco_spec.rb +170 -0
  43. data/spec/boleto_bancario/core/itau_spec.rb +336 -0
  44. data/spec/boleto_bancario/core/santander_spec.rb +135 -0
  45. data/spec/shared_examples/boleto_bancario_shared_example.rb +164 -0
  46. data/spec/spec_helper.rb +14 -0
  47. 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