br_boleto 0.1.0 → 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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/Gemfile.lock +3 -3
  4. data/README.markdown +196 -11
  5. data/Rakefile +5 -0
  6. data/br_boleto.gemspec +1 -1
  7. data/lib/br_boleto.rb +30 -12
  8. data/lib/br_boleto/{core/boleto.rb → boleto/base.rb} +83 -5
  9. data/lib/br_boleto/boleto/sicoob.rb +211 -0
  10. data/lib/br_boleto/calculos/modulo11_fator3197.rb +5 -5
  11. data/lib/br_boleto/helper/cpf_cnpj.rb +60 -0
  12. data/lib/br_boleto/helper/number.rb +15 -0
  13. data/lib/br_boleto/remessa/base.rb +89 -0
  14. data/lib/br_boleto/remessa/cnab240/base.rb +328 -0
  15. data/lib/br_boleto/remessa/cnab240/helper/header_arquivo.rb +186 -0
  16. data/lib/br_boleto/remessa/cnab240/helper/header_lote.rb +180 -0
  17. data/lib/br_boleto/remessa/cnab240/helper/segmento_p.rb +349 -0
  18. data/lib/br_boleto/remessa/cnab240/helper/segmento_q.rb +206 -0
  19. data/lib/br_boleto/remessa/cnab240/helper/segmento_r.rb +261 -0
  20. data/lib/br_boleto/remessa/cnab240/helper/segmento_s.rb +193 -0
  21. data/lib/br_boleto/remessa/cnab240/helper/trailer_arquivo.rb +88 -0
  22. data/lib/br_boleto/remessa/cnab240/helper/trailer_lote.rb +75 -0
  23. data/lib/br_boleto/remessa/cnab240/sicoob.rb +246 -0
  24. data/lib/br_boleto/remessa/lote.rb +52 -0
  25. data/lib/br_boleto/remessa/pagamento.rb +238 -0
  26. data/lib/br_boleto/string_methods.rb +21 -0
  27. data/lib/br_boleto/version.rb +2 -2
  28. data/test/br_boleto/{core/boleto_test.rb → boleto/base_test.rb} +107 -11
  29. data/test/br_boleto/{core → boleto}/sicoob_test.rb +60 -2
  30. data/test/br_boleto/remessa/base_test.rb +80 -0
  31. data/test/br_boleto/remessa/cnab240/base_test.rb +405 -0
  32. data/test/br_boleto/remessa/cnab240/helper/header_arquivo_test.rb +208 -0
  33. data/test/br_boleto/remessa/cnab240/helper/header_lote_test.rb +200 -0
  34. data/test/br_boleto/remessa/cnab240/helper/segmento_p_test.rb +390 -0
  35. data/test/br_boleto/remessa/cnab240/helper/segmento_q_test.rb +223 -0
  36. data/test/br_boleto/remessa/cnab240/helper/segmento_r_test.rb +260 -0
  37. data/test/br_boleto/remessa/cnab240/helper/segmento_s_test.rb +217 -0
  38. data/test/br_boleto/remessa/cnab240/helper/trailer_arquivo_test.rb +82 -0
  39. data/test/br_boleto/remessa/cnab240/helper/trailer_lote_test.rb +67 -0
  40. data/test/br_boleto/remessa/cnab240/sicoob_test.rb +347 -0
  41. data/test/br_boleto/remessa/lote_test.rb +49 -0
  42. data/test/br_boleto/remessa/pagamento_test.rb +339 -0
  43. data/test/factories/{boleto.rb → boleto/base.rb} +1 -1
  44. data/test/factories/{boleto_sicoob.rb → boleto/boleto_sicoob.rb} +1 -1
  45. data/test/factories/remessa/base.rb +13 -0
  46. data/test/factories/remessa/cnab240/base.rb +18 -0
  47. data/test/factories/remessa/cnab240/sicoob.rb +18 -0
  48. data/test/factories/remessa/lote.rb +7 -0
  49. data/test/factories/remessa/pagamento.rb +16 -0
  50. data/test/inheritance/boleto_test.rb +1 -1
  51. data/test/inheritance/sicoob_test.rb +1 -1
  52. metadata +65 -13
  53. data/lib/br_boleto/core/sicoob.rb +0 -169
@@ -0,0 +1,211 @@
1
+ # encoding: utf-8
2
+ module BrBoleto
3
+ module Boleto
4
+ # Implementação de emissão de boleto bancário pelo Banco Sicoob.
5
+ #
6
+ # === Documentação Implementada
7
+ #
8
+ # A documentação na qual essa implementação foi baseada está localizada na pasta
9
+ # 'documentacoes_dos_boletos/sicoob' dentro dessa biblioteca.
10
+ #
11
+ class Sicoob < Base
12
+ # === Carteira/Modalidade:
13
+ #
14
+ # '1/01' - Simples com registro
15
+ # '1/02' - Simples sem registro
16
+ # '3/03' - Garantida Caucionada
17
+ #
18
+ attr_accessor :modalidade_cobranca
19
+
20
+ def modalidade_cobranca
21
+ if @modalidade_cobranca.present?
22
+ @modalidade_cobranca.to_s.rjust(2, '0')
23
+ else
24
+ '01'
25
+ end
26
+ end
27
+
28
+ #Modalidades de cobranças válidas conforme a documentação
29
+ def self.modalidade_cobranca_validas
30
+ %{'01' '02' '03'}
31
+ end
32
+
33
+ def deve_validar_modalidade_cobranca?
34
+ true
35
+ end
36
+
37
+ # Quantidade de parcelas que o boleto possui
38
+ # Liberando a possibilidade de edição
39
+ attr_accessor :parcelas
40
+ def parcelas
41
+ if @parcelas.present?
42
+ @parcelas.to_s.rjust(3, '0')
43
+ else
44
+ '001'
45
+ end
46
+ end
47
+
48
+
49
+ # Tamanho máximo de uma agência no Banco Sicoob.
50
+ # <b>Método criado justamente para ficar documentado o tamanho máximo aceito até a data corrente.</b>
51
+ #
52
+ # @return [Fixnum] 4
53
+ #
54
+ def self.tamanho_maximo_agencia
55
+ 4
56
+ end
57
+
58
+ # Tamanho máximo do codigo cedente no Banco Sicoob.
59
+ # <b>Método criado justamente para ficar documentado o tamanho máximo aceito até a data corrente.</b>
60
+ #
61
+ # @return [Fixnum] 7
62
+ #
63
+ def self.tamanho_maximo_codigo_cedente
64
+ 7
65
+ end
66
+
67
+ # Tamanho máximo do numero do documento no Boleto.
68
+ # <b>Método criado justamente para ficar documentado o tamanho máximo aceito até a data corrente.</b>
69
+ #
70
+ # @return [Fixnum] 6
71
+ #
72
+ def self.tamanho_maximo_numero_documento
73
+ 7
74
+ end
75
+
76
+ # <b>Carteiras suportadas.</b>
77
+ #
78
+ # <b>Método criado para validar se a carteira informada é suportada.</b>
79
+ #
80
+ # @return [Array]
81
+ #
82
+ def self.carteiras_suportadas
83
+ %w[1 3]
84
+ end
85
+
86
+ # Validações para os campos abaixo:
87
+ #
88
+ # * Agencia
89
+ # * Codigo Cedente
90
+ # * Número do documento
91
+ #
92
+ # Se você quiser sobrescrever os metodos, <b>ficará a sua responsabilidade.</b>
93
+ # Basta você sobrescrever os métodos de validação:
94
+ #
95
+ # class Sicoob < BrBoleto::Core::Sicoob
96
+ # def self.tamanho_maximo_agencia
97
+ # 6
98
+ # end
99
+ #
100
+ # def self.tamanho_maximo_codigo_cedente
101
+ # 9
102
+ # end
103
+ #
104
+ # def self.tamanho_maximo_numero_documento
105
+ # 10
106
+ # end
107
+ # end
108
+ #
109
+ # Obs.: Mudar as regras de validação podem influenciar na emissão do boleto em si.
110
+ # Talvez você precise analisar o efeito no #codigo_de_barras e na #linha_digitável (ambos podem ser
111
+ # sobreescritos também).
112
+ #
113
+ validates :agencia, :codigo_cedente, presence: true
114
+
115
+ validates :agencia, length: { maximum: tamanho_maximo_agencia }, if: :deve_validar_agencia?
116
+ validates :codigo_cedente, length: { maximum: tamanho_maximo_codigo_cedente }, if: :deve_validar_codigo_cedente?
117
+ validates :numero_documento, length: { maximum: tamanho_maximo_numero_documento }, if: :deve_validar_numero_documento?
118
+
119
+ validates :carteira, inclusion: { in: ->(object) { object.class.carteiras_suportadas } }, if: :deve_validar_carteira?
120
+ validates :modalidade_cobranca, inclusion: { in: ->(object) { object.class.modalidade_cobranca_validas } }, if: :deve_validar_modalidade_cobranca?
121
+
122
+ # @return [String] 4 caracteres
123
+ #
124
+ def agencia
125
+ @agencia.to_s.rjust(4, '0') if @agencia.present?
126
+ end
127
+
128
+ # @return [String] 7 caracteres
129
+ # O Código do cedente é o mesmo que o codigo do beneficiário
130
+ def codigo_cedente
131
+ @codigo_cedente.to_s.rjust(7, '0') if @codigo_cedente.present?
132
+ end
133
+
134
+ # @return [String] 6 caracteres
135
+ #
136
+ def numero_documento
137
+ @numero_documento.to_s.rjust(7, '0') if @numero_documento.present?
138
+ end
139
+
140
+ # @return [String] Código do Banco descrito na documentação.
141
+ #
142
+ def codigo_banco
143
+ '756'
144
+ end
145
+
146
+ # @return [String] Dígito do código do banco descrito na documentação.
147
+ #
148
+ def digito_codigo_banco
149
+ '0'
150
+ end
151
+
152
+ # Campo Agência / Código do Cedente
153
+ #
154
+ # @return [String]
155
+ #
156
+ def agencia_codigo_cedente
157
+ "#{agencia} / #{codigo_cedente}"
158
+ end
159
+
160
+ # O nosso número descrino na documentação é formado pelo numero do documento mais o digito
161
+ # verificador no nosso_numero, que é um cálculo descrito na documentação.
162
+ #
163
+ # @return [String]
164
+ #
165
+ def nosso_numero
166
+ "#{numero_documento}-#{digito_verificador_nosso_numero}"
167
+ end
168
+
169
+ # Tipo de cobrança
170
+ # Ex: :com_registro, :sem_registro, :garantia_caucionada
171
+ #
172
+ # Obs: O VALOR DESSE METODO NÃO INFLUÊNCIA NA GERAÇÃO DO BOLETO
173
+ # É APENAS PARA QUESTÃO DE INFORMAÇÃO CASO PRECISE PARA OUTRAS COISAS.
174
+ #
175
+ def tipo_cobranca
176
+ case "#{modalidade_cobranca}".rjust(2, "0")
177
+ when '01'
178
+ :com_registro
179
+ when '02'
180
+ :sem_registro
181
+ when '03'
182
+ :garantia_caucionada
183
+ end
184
+ end
185
+
186
+
187
+ # === Código de barras do banco
188
+ #
189
+ # ___________________________________________________________
190
+ # | Posição | Tamanho | Descrição |
191
+ # |---------|---------|---------------------------------------|
192
+ # | 20 - 20 | 01 | Código da carteira |
193
+ # | 21 - 24 | 04 | Código da agência |
194
+ # | 25 - 26 | 02 | Código da modalidade de cobrança (01) |
195
+ # | 27 - 33 | 07 | Código do Cedente |
196
+ # | 34 - 41 | 08 | Nosso Número do título |
197
+ # | 42 - 44 | 03 | Número da Parcela do Título (001) |
198
+ # |___________________________________________________________|
199
+ #
200
+ # @return [String]
201
+ #
202
+ def codigo_de_barras_do_banco
203
+ "#{carteira}#{agencia}#{modalidade_cobranca}#{codigo_cedente}#{nosso_numero.gsub('-','')}#{parcelas}"
204
+ end
205
+
206
+ def digito_verificador_nosso_numero
207
+ BrBoleto::Calculos::Modulo11Fator3197.new("#{agencia}#{codigo_cedente.rjust(10, '0')}#{numero_documento}")
208
+ end
209
+ end
210
+ end
211
+ end
@@ -49,19 +49,19 @@ module BrBoleto
49
49
  #
50
50
  # @example
51
51
  #
52
- # BrBoleto::Calculos::Modulo11FatorDe2a7.new('20')
52
+ # BrBoleto::Calculos::Modulo11Fator3197.new('20')
53
53
  # # => '5'
54
54
  #
55
- # BrBoleto::Calculos::Modulo11FatorDe2a7.new('64')
55
+ # BrBoleto::Calculos::Modulo11Fator3197.new('64')
56
56
  # # => '7'
57
57
  #
58
- # BrBoleto::Calculos::Modulo11FatorDe2a7.new('26')
58
+ # BrBoleto::Calculos::Modulo11Fator3197.new('26')
59
59
  # # => '4'
60
60
  #
61
- # BrBoleto::Calculos::Modulo11FatorDe2a7.new('6')
61
+ # BrBoleto::Calculos::Modulo11Fator3197.new('6')
62
62
  # # => 'P'
63
63
  #
64
- # BrBoleto::Calculos::Modulo11FatorDe2a7.new('14')
64
+ # BrBoleto::Calculos::Modulo11Fator3197.new('14')
65
65
  # # => '0'
66
66
  #
67
67
  class Modulo11Fator3197 < Modulo11
@@ -0,0 +1,60 @@
1
+ module BrBoleto
2
+ module Helper
3
+ class CpfCnpj
4
+
5
+ def initialize(cpf_cnpj)
6
+ @cpf_cnpj = ajusta_cpf_cnpj_com_zero("#{cpf_cnpj}")
7
+ end
8
+
9
+ def cpf?
10
+ cpf_ou_cnpj? == :cpf
11
+ end
12
+
13
+ def cnpj?
14
+ cpf_ou_cnpj? == :cnpj
15
+ end
16
+
17
+ def cpf_ou_cnpj?
18
+ @cpf_cnpj.size > 11 ? :cnpj : :cpf
19
+ end
20
+
21
+ def tipo_documento(tamanho = 2)
22
+ return '0' if sem_formatacao.blank?
23
+ sem_formatacao.size < 14 ? '1'.rjust(tamanho, '0') : '2'.rjust(tamanho, '0')
24
+ end
25
+
26
+ def sem_formatacao
27
+ @cpf_cnpj.gsub(/[\.]|[\-]|[\/]/,'')
28
+ end
29
+
30
+ def com_formatacao
31
+ cnpj? ? formata_cnpj : formata_cpf
32
+ end
33
+
34
+ def formatado_com_label
35
+ cnpj? ? "CNPJ #{formata_cnpj}" : "CPF #{formata_cpf}"
36
+ end
37
+
38
+ private
39
+
40
+ def ajusta_cpf_cnpj_com_zero(value)
41
+ return "" if value.blank?
42
+ if value.to_s.size <= 11
43
+ value.to_s.rjust(11, '0')
44
+ else
45
+ value.to_s.rjust(14, '0')
46
+ end
47
+ end
48
+
49
+ def formata_cpf
50
+ @cpf_cnpj.gsub!(/[\.]|[\-]|[\/]/,'')
51
+ "#{@cpf_cnpj[0..2]}.#{@cpf_cnpj[3..5]}.#{@cpf_cnpj[6..8]}-#{@cpf_cnpj[9..10]}"
52
+ end
53
+
54
+ def formata_cnpj
55
+ @cpf_cnpj.gsub!(/[\.]|[\-]|[\/]/,'')
56
+ "#{@cpf_cnpj[0..1]}.#{@cpf_cnpj[2..4]}.#{@cpf_cnpj[5..7]}/#{@cpf_cnpj[8..11]}-#{@cpf_cnpj[12..13]}"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,15 @@
1
+ module BrBoleto
2
+ module Helper
3
+ class Number
4
+ def initialize(numero)
5
+ @numero = numero
6
+ end
7
+
8
+ def formata_valor_monetario(size=13)
9
+ return ''.rjust(size, '0') if @numero.blank?
10
+ sprintf('%.2f', @numero).delete('.').rjust(size, '0')
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,89 @@
1
+ module BrBoleto
2
+ module Remessa
3
+ class Base
4
+ # Seguindo a interface do Active Model para:
5
+ # * Validações;
6
+ # * Internacionalização;
7
+ # * Nomes das classes para serem manipuladas;
8
+ #
9
+ include ActiveModel::Model
10
+
11
+ # variavel que terá os lotes no qual será gerado o arquivo de remessa
12
+ # um lote deve conter no minimo 1 pagamento
13
+ # Pode haver 1 ou vários lotes para o mesmo arquivo
14
+ attr_accessor :lotes
15
+
16
+ def self.class_for_lote
17
+ BrBoleto::Remessa::Lote
18
+ end
19
+
20
+ # Razão social da empresa
21
+ attr_accessor :nome_empresa
22
+
23
+ # agencia (sem digito verificador)
24
+ attr_accessor :agencia
25
+
26
+ # numero da conta corrente
27
+ attr_accessor :conta_corrente
28
+
29
+ # digito verificador da conta corrente
30
+ attr_accessor :digito_conta
31
+
32
+ # carteira do cedente
33
+ attr_accessor :carteira
34
+
35
+ # sequencial remessa (num. sequencial que nao pode ser repetido nem zerado)
36
+ attr_accessor :sequencial_remessa
37
+
38
+ # aceite (A = ACEITO/N = NAO ACEITO)
39
+ attr_accessor :aceite
40
+
41
+ def initialize(attributes = {})
42
+ self.lotes = [] # Para poder utilizar o << para adicionar lote
43
+ attributes = default_values.merge!(attributes)
44
+ assign_attributes(attributes)
45
+ yield self if block_given?
46
+ end
47
+
48
+ def assign_attributes(attributes)
49
+ attributes ||= {}
50
+ attributes.each do |name, value|
51
+ send("#{name}=", value)
52
+ end
53
+ end
54
+
55
+ validates :nome_empresa, presence: true
56
+ validates :aceite, inclusion: { in: %w(A a n N), message: "valor deve ser A(aceito) ou N(não ceito)" }
57
+
58
+ validates_each :lotes do |record, attr, value|
59
+ record.errors.add(attr, 'não pode estar vazio.') if value.empty?
60
+ value.each do |lote|
61
+ if lote.is_a? record.class.class_for_lote
62
+ if lote.invalid?
63
+ lote.errors.full_messages.each { |msg| record.errors.add(attr, msg) }
64
+ end
65
+ else
66
+ record.errors.add(attr, 'cada item deve ser um objeto Lote.')
67
+ end
68
+ end
69
+ end
70
+
71
+ # O atributo lotes sempre irá retornar umm Array
72
+ def lotes
73
+ @lotes = [@lotes].flatten
74
+ end
75
+
76
+ def default_values
77
+ {aceite: "N"}
78
+ end
79
+
80
+ def persisted?
81
+ false
82
+ end
83
+
84
+ def nome_empresa_formatada
85
+ "#{nome_empresa}".adjust_size_to(30)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,328 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'br_boleto/remessa/cnab240/helper/header_arquivo'
3
+ require 'br_boleto/remessa/cnab240/helper/header_lote'
4
+ require 'br_boleto/remessa/cnab240/helper/segmento_p'
5
+ require 'br_boleto/remessa/cnab240/helper/segmento_q'
6
+ require 'br_boleto/remessa/cnab240/helper/segmento_r'
7
+ require 'br_boleto/remessa/cnab240/helper/segmento_s'
8
+ require 'br_boleto/remessa/cnab240/helper/trailer_lote'
9
+ require 'br_boleto/remessa/cnab240/helper/trailer_arquivo'
10
+
11
+ module BrBoleto
12
+ module Remessa
13
+ module Cnab240
14
+ class Base < BrBoleto::Remessa::Base
15
+
16
+ # Utilizado para montar o header do arquivo
17
+ include BrBoleto::Remessa::Cnab240::Helper::HeaderArquivo
18
+
19
+ # Utilizado para montar o header do lote
20
+ include BrBoleto::Remessa::Cnab240::Helper::HeaderLote
21
+
22
+ # Utilizado para montar o segmento P
23
+ include BrBoleto::Remessa::Cnab240::Helper::SegmentoP
24
+
25
+ # Utilizado para montar o segmento Q
26
+ include BrBoleto::Remessa::Cnab240::Helper::SegmentoQ
27
+
28
+ # Utilizado para montar o segmento R
29
+ include BrBoleto::Remessa::Cnab240::Helper::SegmentoR
30
+
31
+ # Utilizado para montar o segmento S
32
+ include BrBoleto::Remessa::Cnab240::Helper::SegmentoS
33
+
34
+ # Utilizado para montar o trailer do lote
35
+ include BrBoleto::Remessa::Cnab240::Helper::TrailerLote
36
+
37
+ # Utilizado para montar o trailer do arquivo
38
+ include BrBoleto::Remessa::Cnab240::Helper::TrailerArquivo
39
+
40
+ # documento do cedente (CPF/CNPJ)
41
+ attr_accessor :documento_cedente
42
+
43
+ # convenio do cedente
44
+ attr_accessor :convenio
45
+
46
+ # mensagem 1
47
+ attr_accessor :mensagem_1
48
+
49
+ # mensagem 2
50
+ attr_accessor :mensagem_2
51
+
52
+ # Data e hora da geração do arquivo
53
+ attr_accessor :data_hora_arquivo
54
+
55
+ # codigo da carteira
56
+ # opcoes:
57
+ # 1 - cobranca simples
58
+ # 2 - cobranca caucionada
59
+ # 3 - cobranca descontada
60
+ # 7 – modalidade Simples quando carteira 17 (apenas Banco do Brasil)
61
+ attr_accessor :codigo_carteira
62
+
63
+ # forma de cadastramento dos titulos (campo nao tratado pelo Banco do Brasil)
64
+ # opcoes:
65
+ # 1 - com cadastramento (cobrança registrada)
66
+ # 2 - sem cadastramento (cobrança sem registro)
67
+ attr_accessor :forma_cadastramento
68
+
69
+ # identificacao da emissao do boleto (verificar opcoes nas classes referentes aos bancos)
70
+ attr_accessor :emissao_boleto
71
+
72
+ # identificacao da distribuicao do boleto (verificar opcoes nas classes referentes aos bancos)
73
+ attr_accessor :distribuicao_boleto
74
+
75
+ # especie do titulo (verificar o padrao nas classes referentes aos bancos)
76
+ attr_accessor :especie_titulo
77
+
78
+
79
+ def self.tamanho_codigo_carteira
80
+ 1
81
+ end
82
+
83
+ def self.tamanho_forma_cadastramento
84
+ 1
85
+ end
86
+
87
+ def self.tamanho_emissao_boleto
88
+ 1
89
+ end
90
+
91
+ def self.tamanho_distribuicao_boleto
92
+ 1
93
+ end
94
+
95
+ def self.tamanho_especie_titulo
96
+ 2
97
+ end
98
+
99
+ def convenio_obrigatorio?
100
+ true
101
+ end
102
+
103
+ validates :convenio, presence: true, if: :convenio_obrigatorio?
104
+ validates :documento_cedente, presence: true
105
+
106
+ validates :codigo_carteira, length: {is: tamanho_codigo_carteira, message: "deve ter #{tamanho_codigo_carteira} dígito."}
107
+ validates :forma_cadastramento, length: {is: tamanho_forma_cadastramento, message: "deve ter #{tamanho_forma_cadastramento} dígito."}
108
+ validates :emissao_boleto, length: {is: tamanho_emissao_boleto, message: "deve ter #{tamanho_emissao_boleto} dígito."}
109
+ validates :distribuicao_boleto, length: {is: tamanho_distribuicao_boleto, message: "deve ter #{tamanho_distribuicao_boleto} dígito."}
110
+ validates :especie_titulo, length: {is: tamanho_especie_titulo, message: "deve ter #{tamanho_especie_titulo} dígitos."}
111
+
112
+ def default_values
113
+ super.merge({
114
+ codigo_carteira: '1',
115
+ forma_cadastramento: '1'
116
+ })
117
+ end
118
+
119
+ # Tipo de inscricao do cedente
120
+ # (pessoa fisica ou juridica)
121
+ #
122
+ # @return [String]
123
+ #
124
+ def tipo_inscricao
125
+ # Retorna 1 se CPF e 2 se CNPJ
126
+ BrBoleto::Helper::CpfCnpj.new(documento_cedente).tipo_documento(1)
127
+ end
128
+
129
+ # Data de geracao do arquivo
130
+ #
131
+ # @return [String]
132
+ #
133
+ def data_geracao
134
+ data_hora_arquivo.to_date.strftime('%d%m%Y')
135
+ end
136
+
137
+ # Hora de geracao do arquivo
138
+ #
139
+ # @return [String]
140
+ #
141
+ def hora_geracao
142
+ data_hora_arquivo.strftime('%H%M%S')
143
+ end
144
+
145
+ def data_hora_arquivo
146
+ @data_hora_arquivo.to_time
147
+ rescue
148
+ return Time.now
149
+ end
150
+
151
+ # Monta um lote para o arquivo
152
+ #
153
+ # @param lote [BrBoleto::Remessa::Lote]
154
+ # objeto contendo os detalhes do boleto (valor, )
155
+ #
156
+ # @param nro_lote [Integer]
157
+ # numero do lote no arquivo
158
+ #
159
+ # @return [Array]
160
+ #
161
+ def monta_lote(lote, nro_lote)
162
+ return if lote.invalid?
163
+
164
+
165
+ # Metodo 'monta_header_lote' implementado no module -> BrBoleto::Remessa::Cnab240::Helper::HeaderLote
166
+ itens_lote = [monta_header_lote(lote, nro_lote)]
167
+
168
+ #Nº Sequencial de Registros no Lote:
169
+ sequencial_do_lote = 0
170
+
171
+ lote.pagamentos.each do |pagamento|
172
+ # Metodo 'monta_segmento_p' implementado no module -> BrBoleto::Remessa::Cnab240::Helper::SegmentoP
173
+ sequencial_do_lote += 1
174
+ itens_lote << monta_segmento_p(pagamento, nro_lote, sequencial_do_lote)
175
+
176
+ # Metodo 'monta_segmento_q' implementado no module -> BrBoleto::Remessa::Cnab240::Helper::SegmentoQ
177
+ sequencial_do_lote += 1
178
+ itens_lote << monta_segmento_q(pagamento, nro_lote, sequencial_do_lote)
179
+
180
+ # Metodo 'monta_segmento_r' implementado no module -> BrBoleto::Remessa::Cnab240::Helper::SegmentoR
181
+ sequencial_do_lote += 1
182
+ itens_lote << monta_segmento_r(pagamento, nro_lote, sequencial_do_lote)
183
+
184
+ # Metodo 'monta_segmento_s' implementado no module -> BrBoleto::Remessa::Cnab240::Helper::SegmentoS
185
+ sequencial_do_lote += 1
186
+ itens_lote << monta_segmento_s(pagamento, nro_lote, sequencial_do_lote)
187
+ end
188
+
189
+ # total_de_registros_do_lote é a quantidade de registros(linhas) que constam em um lote
190
+ # Total de complementos do lote + o HEADER_LOTE + TRAILER_LOTE
191
+ # sequencial_do_lote + 1 + 1
192
+ total_de_registros_do_lote = sequencial_do_lote + 2
193
+
194
+ # Metodo 'monta_trailer_lote' implementado no module -> BrBoleto::Remessa::Cnab240::Helper::TrailerLote
195
+ itens_lote << monta_trailer_lote(lote, nro_lote, total_de_registros_do_lote)
196
+
197
+ itens_lote
198
+ end
199
+
200
+ # Gera os dados para o arquivo remessa
201
+ #
202
+ # @return [String]
203
+ #
204
+ def dados_do_arquivo
205
+ return if self.invalid?
206
+
207
+ # contador dos registros do lote
208
+ contador = 1
209
+
210
+ # Metodo 'monta_header_arquivo' implementado no module -> BrBoleto::Remessa::Cnab240::Helper::HeaderArquivo
211
+ arquivo = [monta_header_arquivo]
212
+ contador += 1
213
+
214
+ lotes.each_with_index do |lote, index|
215
+ novo_lote = monta_lote(lote, (index + 1))
216
+ arquivo.push novo_lote
217
+ novo_lote.each { |_lote| contador += 1 }
218
+ end
219
+
220
+ # Metodo 'monta_trailer_arquivo' implementado no module -> BrBoleto::Remessa::Cnab240::Helper::TrailerArquivo
221
+ arquivo << monta_trailer_arquivo(lotes.count, contador)
222
+
223
+ retorno = arquivo.join("\n")
224
+ ActiveSupport::Inflector.transliterate(retorno).upcase
225
+ end
226
+
227
+ # Número do Documento de Cobrança
228
+ # Cada banco tem sua maneira de identificar esse número, mas o padrão é o
229
+ # Valor que se encontra no nosso numero
230
+ # 15 posições
231
+ #
232
+ def segmento_p_numero_do_documento(pagamento)
233
+ pagamento.nosso_numero.to_s.rjust(15, '0')
234
+ end
235
+
236
+ # Complemento do registro
237
+ #
238
+ # Este metodo deve ser sobrescrevido na classe do banco
239
+ #
240
+ def complemento_header
241
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
242
+ end
243
+
244
+ # Numero da versao do layout do arquivo
245
+ #
246
+ # Este metodo deve ser sobrescrevido na classe do banco
247
+ #
248
+ def versao_layout_arquivo
249
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
250
+ end
251
+
252
+ # Numero da versao do layout do lote
253
+ #
254
+ # Este metodo deve ser sobrescrevido na classe do banco
255
+ #
256
+ def versao_layout_lote
257
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
258
+ end
259
+
260
+ # Informacoes do convenio para o lote
261
+ #
262
+ # Este metodo deve ser sobrescrevido na classe do banco
263
+ #
264
+ def convenio_lote(lote)
265
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
266
+ end
267
+
268
+ # Nome do banco
269
+ #
270
+ # Este metodo deve ser sobrescrevido na classe do banco
271
+ #
272
+ def nome_banco
273
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
274
+ end
275
+
276
+ # Codigo do banco
277
+ #
278
+ # Este metodo deve ser sobrescrevido na classe do banco
279
+ #
280
+ def codigo_banco
281
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
282
+ end
283
+
284
+ # Informacoes da conta do cedente
285
+ #
286
+ # Este metodo deve ser sobrescrevido na classe do banco
287
+ #
288
+ def informacoes_da_conta
289
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
290
+ end
291
+
292
+ # Codigo do convenio
293
+ #
294
+ # Este metodo deve ser sobrescrevido na classe do banco
295
+ #
296
+ def codigo_convenio
297
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
298
+ end
299
+
300
+ # Digito verificado da agência
301
+ # Normalmente calculado pelo Modulo 11
302
+ # Deve ser sobrescrito na classe do banco
303
+ #
304
+ def digito_agencia
305
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
306
+ end
307
+
308
+ # Complemento do segmento P
309
+ # Recebe um objeto da classe BrBoleto::Remessa::Pagamento
310
+ # Composto por 34 digitos
311
+ # Cada banco tem seu padrão
312
+ # Deve ser sobrescrito na classe do banco
313
+ #
314
+ def complemento_p(pagamento)
315
+ raise NotImplementedError.new('Sobreescreva este método na classe referente ao banco que você esta criando')
316
+ end
317
+
318
+ # Complemento final do trailer do lote
319
+ # Por padrão coloco 217 caracateres em branco pois é na maioria dos bancos
320
+ # Mas para alguns bancos isso pode mudar
321
+ #
322
+ def complemento_trailer_lote(lote, nr_lote)
323
+ ''.rjust(217, ' ')
324
+ end
325
+ end
326
+ end
327
+ end
328
+ end