boleto_bancario 0.0.2 → 1.0.0
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.
- checksums.yaml +5 -5
- data/Changelog.markdown +54 -2
- data/README.markdown +660 -189
- data/lib/boleto_bancario/calculos/documento.rb +191 -0
- data/lib/boleto_bancario/calculos/fator_vencimento.rb +78 -31
- data/lib/boleto_bancario/core/boleto.rb +30 -1
- data/lib/boleto_bancario/core/c6_bank.rb +155 -0
- data/lib/boleto_bancario/core/inter.rb +155 -0
- data/lib/boleto_bancario/core/nubank.rb +156 -0
- data/lib/boleto_bancario/locales/pt-BR.yml +55 -0
- data/lib/boleto_bancario/renderers/base.rb +154 -0
- data/lib/boleto_bancario/renderers/html_renderer.rb +92 -0
- data/lib/boleto_bancario/renderers/pdf_renderer.rb +130 -0
- data/lib/boleto_bancario/renderers/png_renderer.rb +66 -0
- data/lib/boleto_bancario/templates/_barcode.html.erb +3 -0
- data/lib/boleto_bancario/templates/_cedente.html.erb +14 -0
- data/lib/boleto_bancario/templates/_header.html.erb +4 -0
- data/lib/boleto_bancario/templates/_instructions.html.erb +10 -0
- data/lib/boleto_bancario/templates/_payment.html.erb +36 -0
- data/lib/boleto_bancario/templates/_sacado.html.erb +10 -0
- data/lib/boleto_bancario/templates/boleto.html.erb +22 -0
- data/lib/boleto_bancario/templates/boleto_styles.css +18 -0
- data/lib/boleto_bancario/version.rb +3 -1
- data/lib/boleto_bancario.rb +23 -6
- data/lib/generators/boleto_bancario/views_generator.rb +47 -0
- metadata +91 -129
- data/.gitignore +0 -19
- data/.rspec +0 -1
- data/.travis.yml +0 -10
- data/Gemfile +0 -3
- data/Planning.markdown +0 -63
- data/Rakefile +0 -15
- data/TODO.markdown +0 -19
- data/boleto_bancario.gemspec +0 -29
- data/documentacoes_dos_boletos/Bradesco/Manual_BRADESCO.PDF +0 -0
- data/lib/boleto_bancario/core/hsbc.rb +0 -170
- data/lib/boleto_bancario/core/real.rb +0 -177
- data/spec/boleto_bancario/calculos/digitos_spec.rb +0 -19
- data/spec/boleto_bancario/calculos/fator_vencimento_spec.rb +0 -59
- data/spec/boleto_bancario/calculos/fatores_de_multiplicacao_spec.rb +0 -69
- data/spec/boleto_bancario/calculos/linha_digitavel_spec.rb +0 -57
- data/spec/boleto_bancario/calculos/modulo10_spec.rb +0 -53
- data/spec/boleto_bancario/calculos/modulo11_fator_de2a7_spec.rb +0 -43
- data/spec/boleto_bancario/calculos/modulo11_fator_de2a9_resto_zero_spec.rb +0 -39
- data/spec/boleto_bancario/calculos/modulo11_fator_de2a9_spec.rb +0 -67
- data/spec/boleto_bancario/calculos/modulo11_fator_de9a2_resto_x_spec.rb +0 -37
- data/spec/boleto_bancario/calculos/modulo11_fator_de9a2_spec.rb +0 -31
- data/spec/boleto_bancario/calculos/modulo11_spec.rb +0 -19
- data/spec/boleto_bancario/calculos/modulo_numero_de_controle_spec.rb +0 -37
- data/spec/boleto_bancario/core/banco_brasil_spec.rb +0 -377
- data/spec/boleto_bancario/core/banrisul_spec.rb +0 -129
- data/spec/boleto_bancario/core/boleto_spec.rb +0 -218
- data/spec/boleto_bancario/core/bradesco_spec.rb +0 -163
- data/spec/boleto_bancario/core/caixa_spec.rb +0 -111
- data/spec/boleto_bancario/core/hsbc_spec.rb +0 -72
- data/spec/boleto_bancario/core/itau_spec.rb +0 -333
- data/spec/boleto_bancario/core/real_spec.rb +0 -104
- data/spec/boleto_bancario/core/santander_spec.rb +0 -137
- data/spec/boleto_bancario/core/sicoob_spec.rb +0 -111
- data/spec/boleto_bancario/core/sicredi_spec.rb +0 -149
- data/spec/inheritance/banco_brasil_spec.rb +0 -22
- data/spec/inheritance/banrisul_spec.rb +0 -22
- data/spec/inheritance/boleto_spec.rb +0 -15
- data/spec/inheritance/bradesco_spec.rb +0 -22
- data/spec/inheritance/caixa_spec.rb +0 -22
- data/spec/inheritance/hsbc_spec.rb +0 -22
- data/spec/inheritance/itau_spec.rb +0 -22
- data/spec/inheritance/real_spec.rb +0 -22
- data/spec/inheritance/santander_spec.rb +0 -22
- data/spec/inheritance/sicoob_spec.rb +0 -22
- data/spec/inheritance/sicredi_spec.rb +0 -22
- data/spec/shared_examples/boleto_bancario_shared_example.rb +0 -151
- data/spec/spec_helper.rb +0 -14
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BoletoBancario
|
|
4
|
+
module Calculos
|
|
5
|
+
# Classe responsável pela validação e formatação de documentos (CPF e CNPJ).
|
|
6
|
+
#
|
|
7
|
+
# === Validação de CPF
|
|
8
|
+
#
|
|
9
|
+
# O CPF possui 11 dígitos e é validado através de dois dígitos verificadores
|
|
10
|
+
# calculados pelo módulo 11.
|
|
11
|
+
#
|
|
12
|
+
# === Validação de CNPJ
|
|
13
|
+
#
|
|
14
|
+
# O CNPJ possui 14 dígitos e é validado através de dois dígitos verificadores
|
|
15
|
+
# calculados pelo módulo 11.
|
|
16
|
+
#
|
|
17
|
+
# @example Validação
|
|
18
|
+
#
|
|
19
|
+
# Documento.valid?('111.444.777-35')
|
|
20
|
+
# #=> true
|
|
21
|
+
#
|
|
22
|
+
# Documento.valid?('11.222.333/0001-81')
|
|
23
|
+
# #=> true
|
|
24
|
+
#
|
|
25
|
+
# @example Formatação
|
|
26
|
+
#
|
|
27
|
+
# Documento.format('11144477735')
|
|
28
|
+
# #=> '111.444.777-35'
|
|
29
|
+
#
|
|
30
|
+
# Documento.format('11222333000181')
|
|
31
|
+
# #=> '11.222.333/0001-81'
|
|
32
|
+
#
|
|
33
|
+
class Documento
|
|
34
|
+
CPF_SIZE = 11
|
|
35
|
+
CNPJ_SIZE = 14
|
|
36
|
+
|
|
37
|
+
# CPF weights for first digit calculation
|
|
38
|
+
CPF_WEIGHTS_FIRST = [10, 9, 8, 7, 6, 5, 4, 3, 2].freeze
|
|
39
|
+
|
|
40
|
+
# CPF weights for second digit calculation
|
|
41
|
+
CPF_WEIGHTS_SECOND = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2].freeze
|
|
42
|
+
|
|
43
|
+
# CNPJ weights for first digit calculation
|
|
44
|
+
CNPJ_WEIGHTS_FIRST = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2].freeze
|
|
45
|
+
|
|
46
|
+
# CNPJ weights for second digit calculation
|
|
47
|
+
CNPJ_WEIGHTS_SECOND = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2].freeze
|
|
48
|
+
|
|
49
|
+
class << self
|
|
50
|
+
# Valida se o documento é um CPF ou CNPJ válido.
|
|
51
|
+
#
|
|
52
|
+
# @param [String] documento O documento a ser validado
|
|
53
|
+
# @return [Boolean] true se válido, false caso contrário
|
|
54
|
+
#
|
|
55
|
+
def valid?(documento)
|
|
56
|
+
return false if documento.blank?
|
|
57
|
+
|
|
58
|
+
digits = only_digits(documento)
|
|
59
|
+
|
|
60
|
+
case digits.size
|
|
61
|
+
when CPF_SIZE
|
|
62
|
+
valid_cpf?(digits)
|
|
63
|
+
when CNPJ_SIZE
|
|
64
|
+
valid_cnpj?(digits)
|
|
65
|
+
else
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Formata o documento com pontuação.
|
|
71
|
+
#
|
|
72
|
+
# @param [String] documento O documento a ser formatado
|
|
73
|
+
# @return [String] O documento formatado
|
|
74
|
+
#
|
|
75
|
+
def format(documento)
|
|
76
|
+
return documento if documento.blank?
|
|
77
|
+
|
|
78
|
+
digits = only_digits(documento)
|
|
79
|
+
|
|
80
|
+
case digits.size
|
|
81
|
+
when CPF_SIZE
|
|
82
|
+
format_cpf(digits)
|
|
83
|
+
when CNPJ_SIZE
|
|
84
|
+
format_cnpj(digits)
|
|
85
|
+
else
|
|
86
|
+
documento.to_s
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Verifica se o documento é um CPF.
|
|
91
|
+
#
|
|
92
|
+
# @param [String] documento O documento a ser verificado
|
|
93
|
+
# @return [Boolean]
|
|
94
|
+
#
|
|
95
|
+
def cpf?(documento)
|
|
96
|
+
only_digits(documento).size == CPF_SIZE
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Verifica se o documento é um CNPJ.
|
|
100
|
+
#
|
|
101
|
+
# @param [String] documento O documento a ser verificado
|
|
102
|
+
# @return [Boolean]
|
|
103
|
+
#
|
|
104
|
+
def cnpj?(documento)
|
|
105
|
+
only_digits(documento).size == CNPJ_SIZE
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
# Remove caracteres não numéricos.
|
|
111
|
+
#
|
|
112
|
+
# @param [String] value
|
|
113
|
+
# @return [String]
|
|
114
|
+
#
|
|
115
|
+
def only_digits(value)
|
|
116
|
+
value.to_s.gsub(/\D/, '')
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Valida um CPF.
|
|
120
|
+
#
|
|
121
|
+
# @param [String] digits Os 11 dígitos do CPF
|
|
122
|
+
# @return [Boolean]
|
|
123
|
+
#
|
|
124
|
+
def valid_cpf?(digits)
|
|
125
|
+
return false if invalid_sequence?(digits)
|
|
126
|
+
|
|
127
|
+
first_digit = calculate_digit(digits[0, 9], CPF_WEIGHTS_FIRST)
|
|
128
|
+
second_digit = calculate_digit(digits[0, 10], CPF_WEIGHTS_SECOND)
|
|
129
|
+
|
|
130
|
+
digits[9].to_i == first_digit && digits[10].to_i == second_digit
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Valida um CNPJ.
|
|
134
|
+
#
|
|
135
|
+
# @param [String] digits Os 14 dígitos do CNPJ
|
|
136
|
+
# @return [Boolean]
|
|
137
|
+
#
|
|
138
|
+
def valid_cnpj?(digits)
|
|
139
|
+
return false if invalid_sequence?(digits)
|
|
140
|
+
|
|
141
|
+
first_digit = calculate_digit(digits[0, 12], CNPJ_WEIGHTS_FIRST)
|
|
142
|
+
second_digit = calculate_digit(digits[0, 13], CNPJ_WEIGHTS_SECOND)
|
|
143
|
+
|
|
144
|
+
digits[12].to_i == first_digit && digits[13].to_i == second_digit
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Verifica se todos os dígitos são iguais (sequência inválida).
|
|
148
|
+
#
|
|
149
|
+
# @param [String] digits
|
|
150
|
+
# @return [Boolean]
|
|
151
|
+
#
|
|
152
|
+
def invalid_sequence?(digits)
|
|
153
|
+
digits.chars.uniq.size == 1
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Calcula um dígito verificador usando módulo 11.
|
|
157
|
+
#
|
|
158
|
+
# @param [String] digits Os dígitos base
|
|
159
|
+
# @param [Array<Integer>] weights Os pesos para multiplicação
|
|
160
|
+
# @return [Integer] O dígito calculado
|
|
161
|
+
#
|
|
162
|
+
def calculate_digit(digits, weights)
|
|
163
|
+
sum = digits.chars.each_with_index.sum do |digit, index|
|
|
164
|
+
digit.to_i * weights[index]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
remainder = sum % 11
|
|
168
|
+
remainder < 2 ? 0 : 11 - remainder
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Formata CPF com pontuação.
|
|
172
|
+
#
|
|
173
|
+
# @param [String] digits
|
|
174
|
+
# @return [String]
|
|
175
|
+
#
|
|
176
|
+
def format_cpf(digits)
|
|
177
|
+
"#{digits[0, 3]}.#{digits[3, 3]}.#{digits[6, 3]}-#{digits[9, 2]}"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Formata CNPJ com pontuação.
|
|
181
|
+
#
|
|
182
|
+
# @param [String] digits
|
|
183
|
+
# @return [String]
|
|
184
|
+
#
|
|
185
|
+
def format_cnpj(digits)
|
|
186
|
+
"#{digits[0, 2]}.#{digits[2, 3]}.#{digits[5, 3]}/#{digits[8, 4]}-#{digits[12, 2]}"
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -1,33 +1,44 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
module BoletoBancario
|
|
3
4
|
module Calculos
|
|
4
5
|
# Classe responsável pelo cálculo de Fator de Vencimento do boleto bancário.
|
|
5
6
|
#
|
|
6
|
-
# ===
|
|
7
|
+
# === Descrição
|
|
7
8
|
#
|
|
8
9
|
# Conforme Carta-circular 002926 do Banco Central do Brasil, de 24/07/2000, recomenda-se a indicação do Fator de Vencimento no Código de Barras.
|
|
9
10
|
# A partir de 02/04/2001, o Banco acolhedor/recebedor não será mais responsável por eventuais diferenças de recebimento de BOLETOs fora do prazo,
|
|
10
11
|
# ou sem a indicação do fator de vencimento.
|
|
11
12
|
#
|
|
13
|
+
# === Atualização FEBRABAN 2025
|
|
14
|
+
#
|
|
15
|
+
# Em 22/02/2025, o fator de vencimento atingiu o limite de 9999 (baseado em 07/10/1997).
|
|
16
|
+
# A partir desta data, o cálculo utiliza uma nova data base (29/05/2022) e reinicia em 1000.
|
|
17
|
+
#
|
|
12
18
|
# === Forma para obtenção do Fator de Vencimento
|
|
13
19
|
#
|
|
14
|
-
# Calcula-se <b>o número de dias corridos</b> entre a data base
|
|
20
|
+
# Calcula-se <b>o número de dias corridos</b> entre a data base e a do vencimento desejado:
|
|
21
|
+
#
|
|
22
|
+
# Para datas anteriores a 22/02/2025:
|
|
23
|
+
# Data base: 07/10/1997
|
|
24
|
+
# Vencimento: 04/07/2000 => Fator: 1001
|
|
15
25
|
#
|
|
16
|
-
#
|
|
17
|
-
# Data base
|
|
18
|
-
#
|
|
26
|
+
# Para datas a partir de 22/02/2025:
|
|
27
|
+
# Data base: 29/05/2022
|
|
28
|
+
# Fator inicial: 1000
|
|
29
|
+
# Vencimento: 22/02/2025 => Fator: 1000
|
|
19
30
|
#
|
|
20
31
|
# === Atenção
|
|
21
32
|
#
|
|
22
|
-
# Caso ocorra divergência entre a data impressa no campo
|
|
33
|
+
# Caso ocorra divergência entre a data impressa no campo "data de vencimento" e a constante no código de barras,
|
|
23
34
|
# o recebimento se dará da seguinte forma:
|
|
24
35
|
#
|
|
25
|
-
# * Quando pago por sistemas eletrônicos (Home-Banking, Auto-Atendimento, Internet, SISPAG, telefone, etc.), prevalecerá à representada no
|
|
26
|
-
# * Quando quitado na rede de agências, diretamente no caixa, será considerada a data impressa no campo
|
|
36
|
+
# * Quando pago por sistemas eletrônicos (Home-Banking, Auto-Atendimento, Internet, SISPAG, telefone, etc.), prevalecerá à representada no "código de barras";
|
|
37
|
+
# * Quando quitado na rede de agências, diretamente no caixa, será considerada a data impressa no campo "vencimento" do BOLETO.
|
|
27
38
|
#
|
|
28
39
|
# @return [String] retorna o resultado do cálculo. <b>Deve conter 4 dígitos</b>.
|
|
29
40
|
#
|
|
30
|
-
# @example
|
|
41
|
+
# @example Datas anteriores à transição
|
|
31
42
|
#
|
|
32
43
|
# FatorVencimento.new(Date.parse("2012-12-02"))
|
|
33
44
|
# #=> "5535"
|
|
@@ -35,51 +46,87 @@ module BoletoBancario
|
|
|
35
46
|
# FatorVencimento.new(Date.parse("1997-10-08"))
|
|
36
47
|
# #=> "0001"
|
|
37
48
|
#
|
|
38
|
-
#
|
|
39
|
-
# #=> "5549"
|
|
49
|
+
# @example Datas após a transição FEBRABAN 2025
|
|
40
50
|
#
|
|
41
|
-
# FatorVencimento.new(Date.parse("
|
|
42
|
-
# #=> "
|
|
51
|
+
# FatorVencimento.new(Date.parse("2025-02-21"))
|
|
52
|
+
# #=> "9999"
|
|
53
|
+
#
|
|
54
|
+
# FatorVencimento.new(Date.parse("2025-02-22"))
|
|
55
|
+
# #=> "1000"
|
|
56
|
+
#
|
|
57
|
+
# FatorVencimento.new(Date.parse("2025-02-23"))
|
|
58
|
+
# #=> "1001"
|
|
43
59
|
#
|
|
44
60
|
class FatorVencimento < String
|
|
61
|
+
# Data base original utilizada até 21/02/2025
|
|
62
|
+
OLD_BASE_DATE = Date.new(1997, 10, 7).freeze
|
|
63
|
+
|
|
64
|
+
# Nova data base utilizada a partir de 22/02/2025
|
|
65
|
+
NEW_BASE_DATE = Date.new(2022, 5, 29).freeze
|
|
66
|
+
|
|
67
|
+
# Data de transição para o novo cálculo
|
|
68
|
+
TRANSITION_DATE = Date.new(2025, 2, 22).freeze
|
|
69
|
+
|
|
70
|
+
# Fator inicial para a nova data base
|
|
71
|
+
NEW_BASE_FACTOR = 1000
|
|
72
|
+
|
|
45
73
|
attr_reader :base_date
|
|
46
|
-
|
|
47
|
-
# @param [Date]
|
|
74
|
+
|
|
75
|
+
# @param [Date] expiration_date Data de vencimento do boleto
|
|
76
|
+
# @param [Date] base_date Data base para cálculo (opcional, determinado automaticamente)
|
|
48
77
|
# @return [String] retorna o resultado do cálculo. <b>Deve conter 4 dígitos</b>.
|
|
49
|
-
# @example
|
|
50
|
-
# FatorVencimento.new(Date.parse("2012-09-02"))
|
|
51
|
-
# #=> "5444"
|
|
52
|
-
#
|
|
53
|
-
# FatorVencimento.new(Date.parse("1999-10-01"))
|
|
54
|
-
# #=> "0724"
|
|
55
78
|
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
79
|
+
# @example
|
|
80
|
+
# FatorVencimento.new(Date.parse("2025-03-01"))
|
|
81
|
+
# #=> "1007"
|
|
58
82
|
#
|
|
59
|
-
def initialize(expiration_date, base_date =
|
|
60
|
-
@base_date = base_date
|
|
83
|
+
def initialize(expiration_date, base_date = nil)
|
|
61
84
|
@expiration_date = expiration_date
|
|
85
|
+
@base_date = base_date || determine_base_date
|
|
62
86
|
|
|
63
87
|
if @expiration_date.present?
|
|
64
88
|
super(calculate)
|
|
89
|
+
else
|
|
90
|
+
super()
|
|
65
91
|
end
|
|
66
92
|
end
|
|
67
93
|
|
|
68
94
|
# Cálculo da data de vencimento com a data base.
|
|
95
|
+
# Para ambos os períodos, o fator é simplesmente o número de dias desde a data base.
|
|
96
|
+
# A nova data base (29/05/2022) foi escolhida para que 22/02/2025 resulte em fator 1000.
|
|
69
97
|
#
|
|
70
98
|
# @return [String] exatamente 4 dígitos
|
|
71
99
|
#
|
|
72
100
|
def calculate
|
|
73
|
-
|
|
101
|
+
days_from_base.to_s.rjust(4, '0')
|
|
74
102
|
end
|
|
75
103
|
|
|
76
|
-
|
|
104
|
+
private
|
|
105
|
+
|
|
106
|
+
# Determina qual data base usar com base na data de vencimento
|
|
77
107
|
#
|
|
78
|
-
#
|
|
108
|
+
# @return [Date] a data base apropriada
|
|
109
|
+
#
|
|
110
|
+
def determine_base_date
|
|
111
|
+
return OLD_BASE_DATE unless @expiration_date
|
|
112
|
+
|
|
113
|
+
uses_new_calculation? ? NEW_BASE_DATE : OLD_BASE_DATE
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Verifica se deve usar o novo cálculo (pós-transição FEBRABAN)
|
|
117
|
+
#
|
|
118
|
+
# @return [Boolean]
|
|
119
|
+
#
|
|
120
|
+
def uses_new_calculation?
|
|
121
|
+
@expiration_date.is_a?(Date) && @expiration_date >= TRANSITION_DATE
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Calcula a diferença em dias entre a data de vencimento e a data base.
|
|
79
125
|
# Chamando #to_i para não retornar um Float.
|
|
80
|
-
# @return [Integer] diff between this two dates.
|
|
81
126
|
#
|
|
82
|
-
|
|
127
|
+
# @return [Integer] diferença em dias
|
|
128
|
+
#
|
|
129
|
+
def days_from_base
|
|
83
130
|
(@expiration_date - @base_date).to_i
|
|
84
131
|
end
|
|
85
132
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
module BoletoBancario
|
|
3
4
|
module Core
|
|
4
5
|
# @abstract Métodos { #codigo_banco, #digito_codigo_banco, #agencia_codigo_cedente, #nosso_numero, #codigo_de_barras_do_banco}
|
|
@@ -502,6 +503,34 @@ module BoletoBancario
|
|
|
502
503
|
false
|
|
503
504
|
end
|
|
504
505
|
|
|
506
|
+
# Renderiza o boleto em formato PDF.
|
|
507
|
+
#
|
|
508
|
+
# @return [String] Conteúdo binário do PDF
|
|
509
|
+
# @raise [ArgumentError] Se o boleto não for válido
|
|
510
|
+
#
|
|
511
|
+
def to_pdf
|
|
512
|
+
Renderers::PdfRenderer.new(self).render
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
# Renderiza o boleto em formato HTML.
|
|
516
|
+
#
|
|
517
|
+
# @return [String] Conteúdo HTML do boleto
|
|
518
|
+
# @raise [ArgumentError] Se o boleto não for válido
|
|
519
|
+
#
|
|
520
|
+
def to_html
|
|
521
|
+
Renderers::HtmlRenderer.new(self).render
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
# Renderiza o código de barras em formato PNG.
|
|
525
|
+
#
|
|
526
|
+
# @param [Hash] options Opções para o renderizador PNG
|
|
527
|
+
# @return [String] Conteúdo binário do PNG
|
|
528
|
+
# @raise [ArgumentError] Se o boleto não for válido
|
|
529
|
+
#
|
|
530
|
+
def to_png(options = {})
|
|
531
|
+
Renderers::PngRenderer.new(self, options).render
|
|
532
|
+
end
|
|
533
|
+
|
|
505
534
|
# Método usado para verificar se deve realizar a validação de tamanho do campo 'agência'.
|
|
506
535
|
# <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
|
|
507
536
|
#
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BoletoBancario
|
|
4
|
+
module Core
|
|
5
|
+
# Implementação de emissão de boleto bancário pelo C6 Bank.
|
|
6
|
+
#
|
|
7
|
+
# === Documentação Implementada
|
|
8
|
+
#
|
|
9
|
+
# A documentação na qual essa implementação foi baseada está localizada na pasta
|
|
10
|
+
# 'documentacoes_dos_boletos/c6_bank' dentro dessa biblioteca.
|
|
11
|
+
#
|
|
12
|
+
# === Contrato das classes de emissão de boletos
|
|
13
|
+
#
|
|
14
|
+
# Para ver o "<b>contrato</b>" da Emissão de Boletos veja a classe BoletoBancario::Core::Boleto.
|
|
15
|
+
#
|
|
16
|
+
# === Carteiras suportadas
|
|
17
|
+
#
|
|
18
|
+
# O C6 Bank trabalha com carteira de cobrança registrada.
|
|
19
|
+
#
|
|
20
|
+
# ___________________________________________________________________________
|
|
21
|
+
# | Carteira | Descrição | Testada/Homologada |
|
|
22
|
+
# | 1 | Cobrança Registrada | Esperando Contribuição |
|
|
23
|
+
# ----------------------------------------------------------------------------
|
|
24
|
+
#
|
|
25
|
+
class C6Bank < Boleto
|
|
26
|
+
# Tamanho máximo de uma conta corrente no C6 Bank.
|
|
27
|
+
#
|
|
28
|
+
# @return [Integer] 10
|
|
29
|
+
#
|
|
30
|
+
def self.tamanho_maximo_conta_corrente
|
|
31
|
+
10
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Tamanho máximo de uma agência no C6 Bank.
|
|
35
|
+
#
|
|
36
|
+
# @return [Integer] 4
|
|
37
|
+
#
|
|
38
|
+
def self.tamanho_maximo_agencia
|
|
39
|
+
4
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Tamanho máximo do número do documento.
|
|
43
|
+
#
|
|
44
|
+
# @return [Integer] 11
|
|
45
|
+
#
|
|
46
|
+
def self.tamanho_maximo_numero_documento
|
|
47
|
+
11
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Tamanho máximo do código do cedente.
|
|
51
|
+
#
|
|
52
|
+
# @return [Integer] 10
|
|
53
|
+
#
|
|
54
|
+
def self.tamanho_maximo_codigo_cedente
|
|
55
|
+
10
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Carteiras suportadas pelo C6 Bank.
|
|
59
|
+
#
|
|
60
|
+
# @return [Array]
|
|
61
|
+
#
|
|
62
|
+
def self.carteiras_suportadas
|
|
63
|
+
%w[1]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
validates :agencia, :conta_corrente, presence: true
|
|
67
|
+
validates :numero_documento, length: { maximum: tamanho_maximo_numero_documento }, if: :deve_validar_numero_documento?
|
|
68
|
+
validates :conta_corrente, length: { maximum: tamanho_maximo_conta_corrente }, if: :deve_validar_conta_corrente?
|
|
69
|
+
validates :agencia, length: { maximum: tamanho_maximo_agencia }, if: :deve_validar_agencia?
|
|
70
|
+
validates :carteira, inclusion: { in: ->(object) { object.class.carteiras_suportadas } }, if: :deve_validar_carteira?
|
|
71
|
+
|
|
72
|
+
# @return [String] Número do documento com 11 dígitos.
|
|
73
|
+
#
|
|
74
|
+
def numero_documento
|
|
75
|
+
@numero_documento.to_s.rjust(11, '0') if @numero_documento.present?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @return [String] Agência com 4 dígitos.
|
|
79
|
+
#
|
|
80
|
+
def agencia
|
|
81
|
+
@agencia.to_s.rjust(4, '0') if @agencia.present?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @return [String] Conta corrente com 10 dígitos.
|
|
85
|
+
#
|
|
86
|
+
def conta_corrente
|
|
87
|
+
@conta_corrente.to_s.rjust(10, '0') if @conta_corrente.present?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# @return [String] Código do cedente com 10 dígitos.
|
|
91
|
+
#
|
|
92
|
+
def codigo_cedente
|
|
93
|
+
@codigo_cedente.to_s.rjust(10, '0') if @codigo_cedente.present?
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Código do C6 Bank.
|
|
97
|
+
#
|
|
98
|
+
# @return [String] '336'
|
|
99
|
+
#
|
|
100
|
+
def codigo_banco
|
|
101
|
+
'336'
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Dígito do código do banco.
|
|
105
|
+
#
|
|
106
|
+
# @return [String] '5'
|
|
107
|
+
#
|
|
108
|
+
def digito_codigo_banco
|
|
109
|
+
'5'
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Dígito verificador da conta corrente.
|
|
113
|
+
#
|
|
114
|
+
# @return [String]
|
|
115
|
+
#
|
|
116
|
+
def digito_conta_corrente
|
|
117
|
+
Modulo10.new(conta_corrente.to_s)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Agência e código do cedente formatados.
|
|
121
|
+
#
|
|
122
|
+
# @return [String]
|
|
123
|
+
#
|
|
124
|
+
def agencia_codigo_cedente
|
|
125
|
+
"#{agencia} / #{conta_corrente}-#{digito_conta_corrente}"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Nosso Número formatado.
|
|
129
|
+
#
|
|
130
|
+
# @return [String]
|
|
131
|
+
#
|
|
132
|
+
def nosso_numero
|
|
133
|
+
"#{numero_documento}-#{digito_nosso_numero}"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Dígito verificador do nosso número.
|
|
137
|
+
#
|
|
138
|
+
# @return [String]
|
|
139
|
+
#
|
|
140
|
+
def digito_nosso_numero
|
|
141
|
+
Modulo11FatorDe2a9.new(numero_documento.to_s)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Segunda parte do código de barras (campo livre).
|
|
145
|
+
# 25 posições específicas do C6 Bank.
|
|
146
|
+
#
|
|
147
|
+
# @return [String]
|
|
148
|
+
#
|
|
149
|
+
def codigo_de_barras_do_banco
|
|
150
|
+
codigo = "#{agencia}#{carteira.to_s.rjust(1, '0')}#{numero_documento}#{conta_corrente.to_s[0, 9]}"
|
|
151
|
+
"#{codigo.ljust(25, '0')}"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BoletoBancario
|
|
4
|
+
module Core
|
|
5
|
+
# Implementação de emissão de boleto bancário pelo Banco Inter.
|
|
6
|
+
#
|
|
7
|
+
# === Documentação Implementada
|
|
8
|
+
#
|
|
9
|
+
# A documentação na qual essa implementação foi baseada está localizada na pasta
|
|
10
|
+
# 'documentacoes_dos_boletos/inter' dentro dessa biblioteca.
|
|
11
|
+
#
|
|
12
|
+
# === Contrato das classes de emissão de boletos
|
|
13
|
+
#
|
|
14
|
+
# Para ver o "<b>contrato</b>" da Emissão de Boletos veja a classe BoletoBancario::Core::Boleto.
|
|
15
|
+
#
|
|
16
|
+
# === Carteiras suportadas
|
|
17
|
+
#
|
|
18
|
+
# O Banco Inter trabalha com carteira de cobrança registrada.
|
|
19
|
+
#
|
|
20
|
+
# ___________________________________________________________________________
|
|
21
|
+
# | Carteira | Descrição | Testada/Homologada |
|
|
22
|
+
# | 112 | Cobrança Registrada | Esperando Contribuição |
|
|
23
|
+
# ----------------------------------------------------------------------------
|
|
24
|
+
#
|
|
25
|
+
class Inter < Boleto
|
|
26
|
+
# Tamanho máximo de uma conta corrente no Banco Inter.
|
|
27
|
+
#
|
|
28
|
+
# @return [Integer] 10
|
|
29
|
+
#
|
|
30
|
+
def self.tamanho_maximo_conta_corrente
|
|
31
|
+
10
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Tamanho máximo de uma agência no Banco Inter.
|
|
35
|
+
#
|
|
36
|
+
# @return [Integer] 4
|
|
37
|
+
#
|
|
38
|
+
def self.tamanho_maximo_agencia
|
|
39
|
+
4
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Tamanho máximo do número do documento.
|
|
43
|
+
#
|
|
44
|
+
# @return [Integer] 11
|
|
45
|
+
#
|
|
46
|
+
def self.tamanho_maximo_numero_documento
|
|
47
|
+
11
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Tamanho máximo do código do cedente.
|
|
51
|
+
#
|
|
52
|
+
# @return [Integer] 10
|
|
53
|
+
#
|
|
54
|
+
def self.tamanho_maximo_codigo_cedente
|
|
55
|
+
10
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Carteiras suportadas pelo Banco Inter.
|
|
59
|
+
#
|
|
60
|
+
# @return [Array]
|
|
61
|
+
#
|
|
62
|
+
def self.carteiras_suportadas
|
|
63
|
+
%w[112]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
validates :agencia, :conta_corrente, presence: true
|
|
67
|
+
validates :numero_documento, length: { maximum: tamanho_maximo_numero_documento }, if: :deve_validar_numero_documento?
|
|
68
|
+
validates :conta_corrente, length: { maximum: tamanho_maximo_conta_corrente }, if: :deve_validar_conta_corrente?
|
|
69
|
+
validates :agencia, length: { maximum: tamanho_maximo_agencia }, if: :deve_validar_agencia?
|
|
70
|
+
validates :carteira, inclusion: { in: ->(object) { object.class.carteiras_suportadas } }, if: :deve_validar_carteira?
|
|
71
|
+
|
|
72
|
+
# @return [String] Número do documento com 11 dígitos.
|
|
73
|
+
#
|
|
74
|
+
def numero_documento
|
|
75
|
+
@numero_documento.to_s.rjust(11, '0') if @numero_documento.present?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @return [String] Agência com 4 dígitos.
|
|
79
|
+
#
|
|
80
|
+
def agencia
|
|
81
|
+
@agencia.to_s.rjust(4, '0') if @agencia.present?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @return [String] Conta corrente com 10 dígitos.
|
|
85
|
+
#
|
|
86
|
+
def conta_corrente
|
|
87
|
+
@conta_corrente.to_s.rjust(10, '0') if @conta_corrente.present?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# @return [String] Código do cedente com 10 dígitos.
|
|
91
|
+
#
|
|
92
|
+
def codigo_cedente
|
|
93
|
+
@codigo_cedente.to_s.rjust(10, '0') if @codigo_cedente.present?
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Código do Banco Inter.
|
|
97
|
+
#
|
|
98
|
+
# @return [String] '077'
|
|
99
|
+
#
|
|
100
|
+
def codigo_banco
|
|
101
|
+
'077'
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Dígito do código do banco.
|
|
105
|
+
#
|
|
106
|
+
# @return [String] '9'
|
|
107
|
+
#
|
|
108
|
+
def digito_codigo_banco
|
|
109
|
+
'9'
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Dígito verificador da conta corrente.
|
|
113
|
+
#
|
|
114
|
+
# @return [String]
|
|
115
|
+
#
|
|
116
|
+
def digito_conta_corrente
|
|
117
|
+
Modulo10.new(conta_corrente.to_s)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Agência e código do cedente formatados.
|
|
121
|
+
#
|
|
122
|
+
# @return [String]
|
|
123
|
+
#
|
|
124
|
+
def agencia_codigo_cedente
|
|
125
|
+
"#{agencia} / #{conta_corrente}-#{digito_conta_corrente}"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Nosso Número formatado.
|
|
129
|
+
#
|
|
130
|
+
# @return [String]
|
|
131
|
+
#
|
|
132
|
+
def nosso_numero
|
|
133
|
+
"#{numero_documento}-#{digito_nosso_numero}"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Dígito verificador do nosso número.
|
|
137
|
+
#
|
|
138
|
+
# @return [String]
|
|
139
|
+
#
|
|
140
|
+
def digito_nosso_numero
|
|
141
|
+
Modulo11FatorDe2a9.new(numero_documento.to_s)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Segunda parte do código de barras (campo livre).
|
|
145
|
+
# 25 posições específicas do Banco Inter.
|
|
146
|
+
#
|
|
147
|
+
# @return [String]
|
|
148
|
+
#
|
|
149
|
+
def codigo_de_barras_do_banco
|
|
150
|
+
codigo = "#{agencia}#{carteira}#{numero_documento}#{conta_corrente.to_s[0, 7]}"
|
|
151
|
+
"#{codigo.ljust(25, '0')}"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|