br_boleto 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +13 -0
  5. data/LICENSE +1 -1
  6. data/README.markdown +22 -7
  7. data/br_boleto.gemspec +9 -7
  8. data/lib/br_boleto/active_model_base.rb +28 -0
  9. data/lib/br_boleto/boleto/base.rb +666 -633
  10. data/lib/br_boleto/boleto/caixa.rb +257 -0
  11. data/lib/br_boleto/boleto/sicoob.rb +6 -18
  12. data/lib/br_boleto/helper/format_value.rb +18 -0
  13. data/lib/br_boleto/remessa/base.rb +1 -22
  14. data/lib/br_boleto/remessa/cnab240/base.rb +12 -9
  15. data/lib/br_boleto/remessa/cnab240/caixa.rb +201 -0
  16. data/lib/br_boleto/remessa/cnab240/helper/header_arquivo.rb +2 -2
  17. data/lib/br_boleto/remessa/cnab240/helper/header_lote.rb +10 -1
  18. data/lib/br_boleto/remessa/cnab240/helper/segmento_p.rb +2 -2
  19. data/lib/br_boleto/remessa/cnab240/helper/segmento_q.rb +2 -2
  20. data/lib/br_boleto/remessa/cnab240/helper/trailer_arquivo.rb +7 -0
  21. data/lib/br_boleto/remessa/cnab240/sicoob.rb +6 -6
  22. data/lib/br_boleto/remessa/lote.rb +1 -21
  23. data/lib/br_boleto/remessa/pagamento.rb +22 -36
  24. data/lib/br_boleto/retorno/base.rb +31 -0
  25. data/lib/br_boleto/retorno/cnab240/base.rb +101 -0
  26. data/lib/br_boleto/retorno/cnab240/caixa.rb +30 -0
  27. data/lib/br_boleto/retorno/cnab240/sicoob.rb +35 -0
  28. data/lib/br_boleto/retorno/pagamento.rb +242 -0
  29. data/lib/br_boleto/version.rb +2 -2
  30. data/lib/br_boleto.rb +23 -11
  31. data/test/br_boleto/boleto/base_test.rb +6 -6
  32. data/test/br_boleto/boleto/caixa_test.rb +191 -0
  33. data/test/br_boleto/boleto/sicoob_test.rb +18 -11
  34. data/test/br_boleto/remessa/cnab240/base_test.rb +5 -5
  35. data/test/br_boleto/remessa/cnab240/caixa_test.rb +271 -0
  36. data/test/br_boleto/remessa/cnab240/helper/header_arquivo_test.rb +2 -2
  37. data/test/br_boleto/remessa/cnab240/helper/segmento_p_test.rb +1 -1
  38. data/test/br_boleto/remessa/cnab240/sicoob_test.rb +27 -27
  39. data/test/br_boleto/remessa/pagamento_test.rb +12 -2
  40. data/test/br_boleto/retorno/cnab240/base_test.rb +217 -0
  41. data/test/br_boleto/retorno/cnab240/caixa_test.rb +217 -0
  42. data/test/br_boleto/retorno/cnab240/sicoob_test.rb +217 -0
  43. data/test/br_boleto/retorno/pagamento_test.rb +179 -0
  44. data/test/factories/boleto/boleto_caixa.rb +25 -0
  45. data/test/factories/remessa/cnab240/caixa.rb +14 -0
  46. data/test/factories/remessa/pagamento.rb +1 -0
  47. data/test/factories/retorno/pagamento.rb +6 -0
  48. data/test/files/retorno/cnab240/caixa.ret +14 -0
  49. data/test/files/retorno/cnab240/padrao240.ret +14 -0
  50. metadata +51 -6
@@ -1,636 +1,669 @@
1
1
  # encoding: utf-8
2
2
  module BrBoleto
3
- module Boleto
4
- # @abstract Métodos { #codigo_banco, #digito_codigo_banco, #agencia_codigo_cedente, #nosso_numero, #codigo_de_barras_do_banco}
5
- # Métodos para serem escritos nas subclasses (exitem outros opcionais, conforme visto nessa documentação).
6
- #
7
- class Base
8
- include BrBoleto::Calculos
9
-
10
- # Seguindo a interface do Active Model para:
11
- # * Validações;
12
- # * Internacionalização;
13
- # * Nomes das classes para serem manipuladas;
14
- #
15
- include ActiveModel::Model
16
-
17
- # Nome/Razão social que aparece no campo 'Cedente' no boleto.
18
- #
19
- attr_accessor :cedente
20
-
21
- # <b>Código do Cedente é o código do cliente, fornecido pelo banco.</b>
22
- #
23
- # Alguns bancos, dependendo do banco e da carteira, precisam desse campo preenchido.
24
- # Em compensação, outros bancos (a minoria) não fazem utilização desse campo.
25
- #
26
- attr_accessor :codigo_cedente
27
-
28
- # Documento do Cedente (CPF ou CNPJ).
29
- # <b>OBS.: Esse campo não possui validação do campo. Caso você precise imeplemente na subclasse.</b>
30
- #
31
- # Esse campo serve apenas para mostrar no boleto no campo "CPF/CNPJ".
32
- #
33
- attr_accessor :documento_cedente
34
-
35
- # Deve ser informado o endereço completo do Cedente.
36
- # Se o título possuir a figura de Sacador Avalista o endereço informado
37
- # deverá ser do Sacador Avalista, conforme Lei Federal 12.039 de 01/10/2009.
38
- #
39
- # <b>Campo Obrigatório</b>
40
- #
41
- attr_accessor :endereco_cedente
42
-
43
- # Data do vencimento do boleto. Campo auto explicativo.
44
- #
45
- # <b>Campo Obrigatório</b>
46
- #
47
- attr_accessor :data_vencimento
48
-
49
- # Número do documento que será mostrado no boleto.
50
- # Campo de resposabilidade do Cedente e cada banco possui um tamanho esperado.
51
- #
52
- attr_accessor :numero_documento
53
-
54
- # Valor total do documento. Campo auto explicativo.
55
- #
56
- # <b>Campo Obrigatório</b>.
57
- #
58
- attr_accessor :valor_documento
59
-
60
- # Uma carteira de cobrança define o modo como o boleto é tratado pelo banco.
61
- # Existem duas grandes divisões: carteiras não registradas e carteiras registradas.
62
- #
63
- # === Carteiras Não Registradas
64
- #
65
- # Significa que não há registro no banco sobre os boletos gerados, ou seja, você não precisa
66
- # notificar o banco a cada boleto gerado.
67
- # Neste caso a cobrança de taxa bancária é feita por boleto pago.
68
- #
69
- # === Carteiras Registradas
70
- #
71
- # Você precisa notificar o banco sobre todos os boletos gerados, em geral enviando um
72
- # arquivo chamado "arquivo de remessa".
73
- # Neste caso, normalmente existe uma taxa bancária por boleto gerado, independentemente de ele ser pago.
74
- # Nestas carteiras também se encaixam serviços bancários adicionais, como protesto em caso de não pagamento.
75
- #
76
- # <b>Campo Obrigatório</b>
77
- #
78
- attr_accessor :carteira
79
-
80
- # Número da agência. Campo auto explicativo.
81
- #
82
- attr_accessor :agencia
83
-
84
- # Número da Conta corrente. Campo auto explicativo.
85
- #
86
- attr_accessor :conta_corrente
87
-
88
- # Código da moeda. Campo auto explicativo.
89
- # Padrão '9' (Real).
90
- #
91
- attr_accessor :codigo_moeda
92
-
93
- # Essencial para identificação da moeda em que a operação foi efetuada.
94
- #
95
- # Padrão 'R$' (Real).
96
- #
97
- attr_accessor :especie
98
-
99
- # Normalmente se vê neste campo a informação "DM" que quer dizer duplicata mercantil,
100
- # mas existem inúmeros tipos de espécie, <b>neste caso é aconselhável discutir com o banco
101
- # qual a espécie de documento será utilizada</b>, a identificação incorreta da espécie do documento
102
- # não vai impedir que o boleto seja pago e nem que o credito seja efetuado na conta do cliente,
103
- # mas <b>pode ocasionar na impossibilidade de se protestar o boleto caso venha a ser necessário.</b>
104
- #
105
- # Segue a sigla e descrição do campo especie do documento:
106
- #
107
- # ---------------------------------
108
- # | Sigla | Descrição |
109
- # ----------------------------------
110
- # | NP | Nota Promissória |
111
- # | NS | Nota de Seguro |
112
- # | CS | Cobrança Seriada |
113
- # | REC | Recibo |
114
- # | LC | Letras de Câmbio |
115
- # | ND | Notas de débito |
116
- # | DS | Duplicata de Serviços |
117
- # | DM | Duplicata Mercantil |
118
- # ---------------------------------|
119
- #
120
- # Padrão 'DM' (Duplicata Mercantil)
121
- #
122
- attr_accessor :especie_documento
123
-
124
- # Data em que o documento foi gerado. Campo auto explicativo.
125
- #
126
- attr_accessor :data_documento
127
-
128
- # Nome do sacado.
129
- #
130
- # O sacado é a pessoa para o qual o boleto está sendo emitido, podemos resumir dizendo
131
- # que o sacado é o cliente do Cedente, ou aquele para o qual uma determina mercadoria
132
- # foi vendida e o pagamento desta será efetuado por meio de boleto de cobrança.
133
- #
134
- # <b>Campo Obrigatório</b>.
135
- #
136
- attr_accessor :sacado
137
-
138
- # Documento do sacado.
139
- #
140
- # <b>OBS.: Esse campo não possui validação do campo. Caso você precise imeplemente na subclasse.</b>
141
- #
142
- # Esse campo serve apenas para mostrar no boleto no campo "CPF/CNPJ".
143
- #
144
- attr_accessor :documento_sacado
145
-
146
- # Endereço do sacado.
147
- #
148
- # <b>OBS.: Esse campo não possui validação do campo. Caso você precise imeplemente na subclasse.</b>
149
- #
150
- # Esse campo serve apenas para mostrar no boleto no campo "Sacado".
151
- #
152
- attr_accessor :endereco_sacado
153
-
154
- # Descrição do local do pagamento.
155
- #
156
- attr_accessor :local_pagamento
157
-
158
- # Aceitar após o vencimento.
159
- # Nessa gem utilizamos o campo aceite como Boolean.
160
- # Obviamente, true para 'S' e false/nil para 'N'.
161
- #
162
- attr_accessor :aceite
163
-
164
- # Campos de instruções.
165
- # São permitidas até seis linhas de instruções a serem mostradas no boleto
166
-
167
- attr_accessor :instrucoes1,
168
- :instrucoes2,
169
- :instrucoes3,
170
- :instrucoes4,
171
- :instrucoes5,
172
- :instrucoes6
173
-
174
- # Caminho do logo do banco.
175
- #
176
- attr_accessor :logo
177
-
178
- # Tamanho maximo do valor do documento do boleto.
179
- # Acredito que não existirá valor de documento nesse valor,
180
- # <b>porém a biblioteca precisa manter a consistência</b>.
181
- #
182
- # No código de barras o valor do documento precisa
183
- # ter um tamanho de 8 caracteres para os reais (acrescentando zeros à esquerda),
184
- # e 2 caracteres nos centavos (acrescentando zeros à esquerda).
185
- #
186
- # @return [Float] 99999999.99
187
- #
188
- def self.valor_documento_tamanho_maximo
189
- 99999999.99
190
- end
191
-
192
- # Validações de todos os boletos
193
- #
194
- validates :carteira, :valor_documento, :numero_documento, :data_vencimento, presence: true
195
- validates :cedente, :endereco_cedente, presence: true
196
- validates :sacado, :documento_sacado, presence: true
197
- validates :valor_documento, numericality: { less_than_or_equal_to: ->(object) { object.class.valor_documento_tamanho_maximo } }
198
- validate :data_vencimento_deve_ser_uma_data
199
-
200
- # Passing the attributes as Hash or block
201
- #
202
- # @overload initialize(options = {}, &block)
203
- # @param [Hash] options Passing a hash accessing the attributes of the self.
204
- # @option options [String] :cedente
205
- # @option options [String] :codigo_cedente
206
- # @option options [String] :documento_cedente
207
- # @option options [String] :endereco_cedente
208
- # @option options [String] :conta_corrente
209
- # @option options [String] :agencia
210
- # @option options [Date] :data_vencimento
211
- # @option options [String] :numero_documento
212
- # @option options [Float] :valor_documento
213
- # @option options [String] :codigo_moeda
214
- # @option options [String] :especie
215
- # @option options [String] :especie_documento
216
- # @option options [String] :sacado
217
- # @option options [String] :documento_sacado
218
- #
219
- # @param [Proc] block Optional params. Passing a block accessing the attributes of the self.
220
- #
221
- # For the options, waiting for the ActiveModel 4 and the ActiveModel::Model. :)
222
- #
223
- # === Exemplos
224
- #
225
- # O recomendado é usar os boletos herdando de seu respectivo banco. Por exemplo:
226
- #
227
- # class Sicoob < BrBoleto::Sicoob
228
- # end
229
- #
230
- # Agora você pode emitir um boleto usando a classe criada acima:
231
- #
232
- # Sicoob.new(conta_corrente: '89755', agencia: '0097', :carteira => '195')
233
- #
234
- # Você pode usar blocos se quiser:
235
- #
236
- # Sicoob.new do |boleto|
237
- # boleto.conta_corrente = '89755'
238
- # boleto.agencia = '0097'
239
- # boleto.carteira = '198'
240
- # boleto.numero_documento = '12345678'
241
- # boleto.codigo_cedente = '909014'
242
- # end
243
- #
244
- def initialize(options={}, &block)
245
- default_options.merge(options).each do |attribute, value|
246
- send("#{attribute}=", value) if respond_to?("#{attribute}=")
247
- end
248
-
249
- yield(self) if block_given?
250
- end
251
-
252
- # Opções default.
253
- #
254
- # Caso queira sobrescrever as opções, você pode simplesmente instanciar o objeto passando a opção desejada:
255
- #
256
- # class Bradesco < BrBoleto::Bradesco
257
- # end
258
- #
259
- # Bradesco.new do |bradesco|
260
- # bradesco.codigo_moeda = 'outro_codigo_da_moeda'
261
- # bradesco.especie = 'outra_especie_que_nao_seja_em_reais'
262
- # bradesco.especie_documento = 'outra_especie_do_documento'
263
- # bradesco.data_documento = Date.tomorrow
264
- # bradesco.aceite = false
265
- # end
266
- #
267
- # @return [Hash] Código da Moeda sendo '9' (real). Espécie sendo 'R$' (real).
268
- #
269
- def default_options
270
- {
271
- :codigo_moeda => '9',
272
- :especie => 'R$',
273
- :especie_documento => 'DM',
274
- :local_pagamento => 'PAGÁVEL EM QUALQUER BANCO ATÉ O VENCIMENTO',
275
- :data_documento => Date.today,
276
- :aceite => true
277
- }
278
- end
279
-
280
- # Tipo de cobrança
281
- # Ex: :com_registro, :sem_registro, :garantia_caucionada
282
- # A implementação para esse valor deve ser implementada para cada banco,
283
- # pois cada banco tem uma maneira diferente para saber o tipo de cobrança.
284
- #
285
- # Obs: O VALOR DESSE METODO NÃO INFLUÊNCIA NA GERAÇÃO DO BOLETO
286
- # É APENAS PARA QUESTÃO DE INFORMAÇÃO CASO PRECISE PARA OUTRAS COISAS, POR EXEMPLO:
287
- # É UTILIZADO NOS PAGAMENTOS DAS REMESSAS, MAIS ESPECIFICAMENTE NO COMPLEMENTO TRAILER
288
- # DO LOTE PARA O BANCO SICOOB NO CNAB 240.
289
- def tipo_cobranca
290
- end
291
-
292
- # Código do Banco.
293
- # <b>Esse campo é específico para cada banco</b>.
294
- #
295
- # @return [String] Corresponde ao código do banco.
296
- #
297
- # @raise [NotImplementedError] Precisa implementar nas subclasses.
298
- #
299
- def codigo_banco
300
- raise NotImplementedError.new("Not implemented #codigo_banco in #{self}.")
301
- end
302
-
303
- # Dígito do código do banco.
304
- # <b>Esse campo é específico para cada banco</b>.
305
- #
306
- # @return [String] Corresponde ao dígito do código do banco.
307
- # @raise [NotImplementedError] Precisa implementar nas subclasses.
308
- #
309
- def digito_codigo_banco
310
- raise NotImplementedError.new("Not implemented #digito_codigo_banco in #{self}.")
311
- end
312
-
313
- # Formata o código do banco com o dígito do código do banco.
314
- # Método usado para o campo de código do banco localizado no cabeçalho do boleto.
315
- #
316
- # @return [String]
317
- #
318
- def codigo_banco_formatado
319
- "#{codigo_banco}-#{digito_codigo_banco}"
320
- end
321
-
322
- # Agência, código do cedente ou nosso número.
323
- # <b>Esse campo é específico para cada banco</b>.
324
- #
325
- # @return [String] - Corresponde aos campos "Agencia / Codigo do Cedente".
326
- # @raise [NotImplementedError] Precisa implementar nas subclasses.
327
- #
328
- def agencia_codigo_cedente
329
- raise NotImplementedError.new("Not implemented #agencia_codigo_cedente in #{self}.")
330
- end
331
-
332
- # O Nosso Número é o número que identifica unicamente um boleto para uma conta.
333
- # O tamanho máximo do Nosso Número depende do banco e carteira.
334
- #
335
- # <b>Para carteiras registradas, você deve solicitar ao seu banco um intervalo de números para utilização.</b>
336
- # Quando estiver perto do fim do intervalo, deve solicitar um novo intervalo.
337
- #
338
- # <b>Para carteiras não registradas o Nosso Número é livre</b>.
339
- # Ao receber o retorno do banco, é através do Nosso Número que será possível identificar os boletos pagos.
340
- #
341
- # <b>Esse campo é específico para cada banco</b>.
342
- #
343
- # @return [String] Corresponde ao formato específico de cada banco.
344
- # @raise [NotImplementedError] Precisa implementar nas subclasses.
345
- #
346
- def nosso_numero
347
- raise NotImplementedError.new("Not implemented #nosso_numero in #{self}.")
348
- end
349
-
350
- # Formata o valor do documentado para ser mostrado no código de barras
351
- # e na linha digitável com 08 dígitos na casa dos Reais e 02 dígitos nas casas dos centavos.
352
- #
353
- # @example
354
- #
355
- # Bradesco.new(:valor_documento => 123.45).valor_formatado_para_codigo_de_barras
356
- # # => "0000012345"
357
- #
358
- # @return [String] Precisa retornar 10 dígitos para o código de barras (incluindo os centavos).
359
- #
360
- def valor_formatado_para_codigo_de_barras
361
- valor_documento_formatado = (Integer(valor_documento.to_f * 100) / Float(100))
362
- real, centavos = valor_documento_formatado.to_s.split(/\./)
363
- "#{real.rjust(8, '0')}#{centavos.ljust(2, '0')}"
364
- end
365
-
366
- # Força a carteira a retornar o valor como string
367
- #
368
- # @return [String]
369
- #
370
- def carteira
371
- @carteira.to_s if @carteira.present?
372
- end
373
-
374
- # Embora o padrão seja mostrar o número da carteira no boleto,
375
- # <b>alguns bancos</b> requerem que seja mostrado um valor diferente na carteira.
376
- # <b>Para essas exceções, sobrescreva esse método na subclasse.</b>
377
- #
378
- # @return [String] retorna o número da carteira
379
- #
380
- def carteira_formatada
381
- carteira
382
- end
383
-
384
- # Se o aceite for 'true', retorna 'S'.
385
- # Retorna 'N', caso contrário.
386
- #
387
- # @return [String]
388
- #
389
- def aceite_formatado
390
- if @aceite.present?
391
- 'S'
392
- else
393
- 'N'
394
- end
395
- end
396
-
397
- # Fator de vencimento que é calculado a partir de uma data base.
398
- # Veja <b>FatorVencimento</b> para mais detalhes.
399
- #
400
- # @return [String] 4 caracteres.
401
- #
402
- def fator_de_vencimento
403
- FatorVencimento.new(data_vencimento)
404
- end
405
-
406
- # === Código de Barras
407
- #
408
- # O código de barras contêm exatamente 44 posições nessa sequência:
409
- #
410
- # ____________________________________________________________
411
- # | Posição | Tamanho | Descrição |
412
- # |----------|---------|--------------------------------------|
413
- # | 01-03 | 03 | Código do banco |
414
- # | 04 | 01 | Código da moeda |
415
- # | 05 | 01 | Dígito do código de barras (DAC) |
416
- # | 06-09 | 04 | Fator de vencimento |
417
- # | 10-19 | 10 | Valor do documento |
418
- # | 20-44 | 25 | Critério de cada Banco (Campo livre) |
419
- # -------------------------------------------------------------
420
- #
421
- # @return [String] Código de barras com 44 posições.
422
- #
423
- def codigo_de_barras
424
- "#{codigo_de_barras_padrao}#{codigo_de_barras_do_banco}".insert(4, digito_codigo_de_barras)
425
- end
426
-
427
- # Primeira parte do código de barras.
428
- # <b>Essa parte do código de barras é padrão para todos os bancos.</b>.
429
- #
430
- # @return [String] Primeiras 18 posições do código de barras (<b>Não retorna o DAC do código de barras</b>).
431
- #
432
- def codigo_de_barras_padrao
433
- "#{codigo_banco}#{codigo_moeda}#{fator_de_vencimento}#{valor_formatado_para_codigo_de_barras}"
434
- end
435
-
436
- # Segunda parte do código de barras.
437
- # <b>Esse campo é específico para cada banco</b>.
438
- #
439
- # @return [String] 25 últimas posições do código de barras.
440
- # @raise [NotImplementedError] Precisa implementar nas subclasses.
441
- #
442
- def codigo_de_barras_do_banco
443
- raise NotImplementedError.new("Not implemented #codigo_de_barras_do_banco in #{self}.")
444
- end
445
-
446
- # Dígito verificador do código de barras (DAC).
447
- #
448
- # Por definição da FEBRABAN e do Banco Central do Brasil,
449
- # na <b>5º posição do Código de Barras</b>, deve ser indicado obrigatoriamente
450
- # o “dígito verificador” (DAC), calculado através do módulo 11.
451
- #
452
- # <b>OBS.:</b> Para mais detalhes deste cálculo,
453
- # veja a descrição em <b>BrBoleto::Calculos::Modulo11FatorDe2a9</b>.
454
- #
455
- # @return [String] Dígito calculado do código de barras.
456
- #
457
- def digito_codigo_de_barras
458
- Modulo11FatorDe2a9.new("#{codigo_de_barras_padrao}#{codigo_de_barras_do_banco}")
459
- end
460
-
461
- # Representação numérica do código de barras, mais conhecida como linha digitável! :p
462
- #
463
- # A representação numérica do código de barras é composta, por cinco campos.
464
- # Sendo os três primeiros campos, amarrados por DAC's (dígitos verificadores),
465
- # todos calculados pelo módulo 10.
466
- #
467
- # <b>OBS.:</b> Para mais detalhes deste cálculo, veja a descrição em Modulo10.
468
- #
469
- # === Linha Digitável
470
- #
471
- # A linha digitável contêm exatamente 47 posições nessa sequência:
472
- #
473
- # _______________________________________________________________________________________________________
474
- # |Campo | Posição | Tamanho | Descrição |
475
- # |------|----------|---------|--------------------------------------------------------------------------|
476
- # | 1º | 01-03 | 03 | Código do banco (posições 1 a 3 do código de barras) |
477
- # | | 04 | 01 | Código da moeda (posição 4 do código de barras) |
478
- # | | 05-09 | 5 | Cinco posições do campo livre (posições 20 a 24 do código de barras) |
479
- # | | 10 | 1 | Dígito verificador do primeiro campo (Módulo10) |
480
- # |------------------------------------------------------------------------------------------------------|
481
- # | 2º | 11-20 | 10 | a 15º posições do campo livre (posições 25 a 34 do código de barras) |
482
- # | | 21 | 01 | Dígito verificador do segundo campo (Módulo10) |
483
- # |------------------------------------------------------------------------------------------------------|
484
- # | 3º | 22-31 | 10 | 16º a 25º posições do campo livre (posições 35 a 44 do código de barras) |
485
- # | | 32 | 01 | Dígito verificador do terceiro campo (Módulo10) |
486
- # |------------------------------------------------------------------------------------------------------|
487
- # | 4º | 33 | 01 | Dígito verificador do código de barras (posição 5 do código de barras) |
488
- # |------------------------------------------------------------------------------------------------------|
489
- # | 5ª | 34-37 | 04 | Fator de vencimento (posições 6 a 9 do código de barras) |
490
- # | | 38-47 | 10 | Valor nominal do documento (posições 10 a 19 do código de barras) |
491
- # -------------------------------------------------------------------------------------------------------|
492
- #
493
- # @return [String] Contêm a representação numérica do código de barras formatado com pontos e espaços.
494
- #
495
- def linha_digitavel
496
- LinhaDigitavel.new(codigo_de_barras)
497
- end
498
-
499
- # Returns a string that <b>identifying the render path associated with the object</b>.
500
- #
501
- # <b>ActionPack uses this to find a suitable partial to represent the object.</b>
502
- #
503
- # @return [String]
504
- #
505
- def to_partial_path
506
- "br_boleto/#{self.class.name.demodulize.underscore}"
507
- end
508
-
509
- # Seguindo a interface do Active Model.
510
- #
511
- # @return [False]
512
- #
513
- def persisted?
514
- false
515
- end
516
-
517
- # Método usado para verificar se deve realizar a validação de tamanho do campo 'agência'.
518
- # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
519
- #
520
- # @return [True]
521
- #
522
- def deve_validar_agencia?
523
- true
524
- end
525
-
526
- # Método usado para verificar se deve realizar a validação de tamanho do campo 'conta_corrente'.
527
- # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
528
- #
529
- # @return [True]
530
- #
531
- def deve_validar_conta_corrente?
532
- true
533
- end
534
-
535
- # Método usado para verificar se deve realizar a validação de tamanho do campo 'codigo_cedente'.
536
- # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
537
- #
538
- # @return [True]
539
- #
540
- def deve_validar_codigo_cedente?
541
- true
542
- end
543
-
544
- # Método usado para verificar se deve realizar a validação de tamanho do campo 'numero_documento'.
545
- # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
546
- #
547
- # @return [True]
548
- #
549
- def deve_validar_numero_documento?
550
- true
551
- end
552
-
553
- # Método usado para verificar se deve realizar a validação do campo 'carteira'.
554
- # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
555
- #
556
- # @return [True]
557
- #
558
- def deve_validar_carteira?
559
- true
560
- end
561
-
562
- # Verifica e valida se a data do vencimento deve ser uma data válida.
563
- # <b>Precisa ser uma data para o cálculo do fator do vencimento.</b>
564
- #
565
- def data_vencimento_deve_ser_uma_data
566
- errors.add(:data_vencimento, :invalid) unless data_vencimento.kind_of?(Date)
567
- end
568
-
569
-
570
- ################ FORMATAÇÃO PARA CPF OU CNPJ ################
571
- # tanto o documento do sacado quandto do cedente possui 3 tipos de formatação
572
- # EX:
573
- # documento_sacado = '12345678901'
574
- # atributo + '_formatado':
575
- # documento_sacado_formatado = '123.456.789-01'
576
- # atributo + '_formatado_com_label':
577
- # documento_sacado_formatado_com_label = 'CPF 123.456.789-01'
578
- #
579
- # OBS: O documento_cedente e documento_sacado SEMPRE irão retornar o valor sem a formatação
580
- # mesmo que seja setado
581
- ##############################################################
582
-
583
- # Retorna o documento do sacado com tamanho 0, 11 ou 14 caracteres
584
- # Sempre retorna o valor sem a formatação
585
- #
586
- # @return String
587
- #
588
- def documento_sacado
589
- return "" unless @documento_sacado.present?
590
- BrBoleto::Helper::CpfCnpj.new(@documento_sacado).sem_formatacao
591
- end
592
-
593
- # Retorna o documento do sacado formatado
594
- #
595
- # @return String
596
- #
597
- def documento_sacado_formatado
598
- BrBoleto::Helper::CpfCnpj.new(documento_sacado).com_formatacao
599
- end
600
-
601
- # Retorna o documento do sacado formatado com label de CNPJ ou CPF
602
- #
603
- # @return String
604
- #
605
- def documento_sacado_formatado_com_label
606
- BrBoleto::Helper::CpfCnpj.new(documento_sacado).formatado_com_label
607
- end
608
-
609
- # Retorna o documento do cedente com tamanho 0, 11 ou 14 caracteres
610
- # Sempre retorna o valor sem a formatação
611
- #
612
- # @return String
613
- #
614
- def documento_cedente
615
- return "" unless @documento_cedente.present?
616
- BrBoleto::Helper::CpfCnpj.new(@documento_cedente).sem_formatacao
617
- end
618
-
619
- # Retorna o documento do cedente formatado
620
- #
621
- # @return String
622
- #
623
- def documento_cedente_formatado
624
- BrBoleto::Helper::CpfCnpj.new(documento_cedente).com_formatacao
625
- end
626
-
627
- # Retorna o documento do cedente formatado com label de CNPJ ou CPF
628
- #
629
- # @return String
630
- #
631
- def documento_cedente_formatado_com_label
632
- BrBoleto::Helper::CpfCnpj.new(documento_cedente).formatado_com_label
633
- end
634
- end
635
- end
3
+ module Boleto
4
+ # @abstract Métodos { #codigo_banco, #digito_codigo_banco, #agencia_codigo_cedente, #nosso_numero, #codigo_de_barras_do_banco}
5
+ # Métodos para serem escritos nas subclasses (exitem outros opcionais, conforme visto nessa documentação).
6
+ #
7
+ class Base < BrBoleto::ActiveModelBase
8
+ include BrBoleto::Calculos
9
+
10
+ # Nome/Razão social que aparece no campo 'Cedente' no boleto.
11
+ #
12
+ attr_accessor :cedente
13
+
14
+ # <b>Código do Cedente é o código do cliente, fornecido pelo banco.</b>
15
+ #
16
+ # Alguns bancos, dependendo do banco e da carteira, precisam desse campo preenchido.
17
+ # Em compensação, outros bancos (a minoria) não fazem utilização desse campo.
18
+ #
19
+ attr_accessor :codigo_cedente
20
+
21
+ # Código do beneficiário e codigo cedente é a mesma coisa
22
+ # Por isso foi criado um alias para que cada um utilize a nomenclatura que preferir.
23
+ #
24
+ alias_attribute :codigo_beneficiario, :codigo_cedente
25
+
26
+ # Formatação para o código do cedente conforme o tamanho definido por cada banco
27
+ # Perceba que é obrigatório ter o metodo self.tamanho_maximo_codigo_cedente implementado
28
+ # na classe de cada banco
29
+ #
30
+ # @return [String]
31
+ #
32
+ def codigo_cedente
33
+ @codigo_cedente.to_s.rjust(self.class.tamanho_maximo_codigo_cedente, '0') if @codigo_cedente.present?
34
+ end
35
+
36
+ # Documento do Cedente (CPF ou CNPJ).
37
+ # <b>OBS.: Esse campo não possui validação do campo. Caso você precise imeplemente na subclasse.</b>
38
+ #
39
+ # Esse campo serve apenas para mostrar no boleto no campo "CPF/CNPJ".
40
+ #
41
+ attr_accessor :documento_cedente
42
+
43
+ # Deve ser informado o endereço completo do Cedente.
44
+ # Se o título possuir a figura de Sacador Avalista o endereço informado
45
+ # deverá ser do Sacador Avalista, conforme Lei Federal 12.039 de 01/10/2009.
46
+ #
47
+ # <b>Campo Obrigatório</b>
48
+ #
49
+ attr_accessor :endereco_cedente
50
+
51
+ # Data do vencimento do boleto. Campo auto explicativo.
52
+ #
53
+ # <b>Campo Obrigatório</b>
54
+ #
55
+ attr_accessor :data_vencimento
56
+
57
+ # Número do documento que será mostrado no boleto.
58
+ # Campo de resposabilidade do Cedente e cada banco possui um tamanho esperado.
59
+ #
60
+ attr_accessor :numero_documento
61
+ #
62
+ # @return [String]
63
+ #
64
+ def numero_documento
65
+ @numero_documento.to_s.rjust(self.class.tamanho_maximo_numero_documento, '0') if @numero_documento.present?
66
+ end
67
+
68
+ # Valor total do documento. Campo auto explicativo.
69
+ #
70
+ # <b>Campo Obrigatório</b>.
71
+ #
72
+ attr_accessor :valor_documento
73
+
74
+ # Uma carteira de cobrança define o modo como o boleto é tratado pelo banco.
75
+ # Existem duas grandes divisões: carteiras não registradas e carteiras registradas.
76
+ #
77
+ # === Carteiras Não Registradas
78
+ #
79
+ # Significa que não há registro no banco sobre os boletos gerados, ou seja, você não precisa
80
+ # notificar o banco a cada boleto gerado.
81
+ # Neste caso a cobrança de taxa bancária é feita por boleto pago.
82
+ #
83
+ # === Carteiras Registradas
84
+ #
85
+ # Você precisa notificar o banco sobre todos os boletos gerados, em geral enviando um
86
+ # arquivo chamado "arquivo de remessa".
87
+ # Neste caso, normalmente existe uma taxa bancária por boleto gerado, independentemente de ele ser pago.
88
+ # Nestas carteiras também se encaixam serviços bancários adicionais, como protesto em caso de não pagamento.
89
+ #
90
+ # <b>Campo Obrigatório</b>
91
+ #
92
+ attr_accessor :carteira
93
+
94
+ # Número da agência. Campo auto explicativo.
95
+ #
96
+ attr_accessor :agencia
97
+ #
98
+ # @return [String] 4 caracteres
99
+ #
100
+ def agencia
101
+ @agencia.to_s.rjust(self.class.tamanho_maximo_agencia, '0') if @agencia.present?
102
+ end
103
+
104
+ # Número da Conta corrente. Campo auto explicativo.
105
+ #
106
+ attr_accessor :conta_corrente
107
+
108
+ # Código da moeda. Campo auto explicativo.
109
+ # Padrão '9' (Real).
110
+ #
111
+ attr_accessor :codigo_moeda
112
+
113
+ # Essencial para identificação da moeda em que a operação foi efetuada.
114
+ #
115
+ # Padrão 'R$' (Real).
116
+ #
117
+ attr_accessor :especie
118
+
119
+ # Normalmente se vê neste campo a informação "DM" que quer dizer duplicata mercantil,
120
+ # mas existem inúmeros tipos de espécie, <b>neste caso é aconselhável discutir com o banco
121
+ # qual a espécie de documento será utilizada</b>, a identificação incorreta da espécie do documento
122
+ # não vai impedir que o boleto seja pago e nem que o credito seja efetuado na conta do cliente,
123
+ # mas <b>pode ocasionar na impossibilidade de se protestar o boleto caso venha a ser necessário.</b>
124
+ #
125
+ # Segue a sigla e descrição do campo especie do documento:
126
+ #
127
+ # ---------------------------------
128
+ # | Sigla | Descrição |
129
+ # ----------------------------------
130
+ # | NP | Nota Promissória |
131
+ # | NS | Nota de Seguro |
132
+ # | CS | Cobrança Seriada |
133
+ # | REC | Recibo |
134
+ # | LC | Letras de Câmbio |
135
+ # | ND | Notas de débito |
136
+ # | DS | Duplicata de Serviços |
137
+ # | DM | Duplicata Mercantil |
138
+ # ---------------------------------|
139
+ #
140
+ # Padrão 'DM' (Duplicata Mercantil)
141
+ #
142
+ attr_accessor :especie_documento
143
+
144
+ # Data em que o documento foi gerado. Campo auto explicativo.
145
+ #
146
+ attr_accessor :data_documento
147
+
148
+ # Nome do sacado.
149
+ #
150
+ # O sacado é a pessoa para o qual o boleto está sendo emitido, podemos resumir dizendo
151
+ # que o sacado é o cliente do Cedente, ou aquele para o qual uma determina mercadoria
152
+ # foi vendida e o pagamento desta será efetuado por meio de boleto de cobrança.
153
+ #
154
+ # <b>Campo Obrigatório</b>.
155
+ #
156
+ attr_accessor :sacado
157
+
158
+ # Documento do sacado.
159
+ #
160
+ # <b>OBS.: Esse campo não possui validação do campo. Caso você precise imeplemente na subclasse.</b>
161
+ #
162
+ # Esse campo serve apenas para mostrar no boleto no campo "CPF/CNPJ".
163
+ #
164
+ attr_accessor :documento_sacado
165
+
166
+ # Endereço do sacado.
167
+ #
168
+ # <b>OBS.: Esse campo não possui validação do campo. Caso você precise imeplemente na subclasse.</b>
169
+ #
170
+ # Esse campo serve apenas para mostrar no boleto no campo "Sacado".
171
+ #
172
+ attr_accessor :endereco_sacado
173
+
174
+ # Descrição do local do pagamento.
175
+ #
176
+ attr_accessor :local_pagamento
177
+
178
+ # Aceitar após o vencimento.
179
+ # Nessa gem utilizamos o campo aceite como Boolean.
180
+ # Obviamente, true para 'S' e false/nil para 'N'.
181
+ #
182
+ attr_accessor :aceite
183
+
184
+ # Campos de instruções.
185
+ # São permitidas até seis linhas de instruções a serem mostradas no boleto
186
+
187
+ attr_accessor :instrucoes1,
188
+ :instrucoes2,
189
+ :instrucoes3,
190
+ :instrucoes4,
191
+ :instrucoes5,
192
+ :instrucoes6
193
+
194
+ # Caminho do logo do banco.
195
+ #
196
+ attr_accessor :logo
197
+
198
+ # Tamanho maximo do valor do documento do boleto.
199
+ # Acredito que não existirá valor de documento nesse valor,
200
+ # <b>porém a biblioteca precisa manter a consistência</b>.
201
+ #
202
+ # No código de barras o valor do documento precisa
203
+ # ter um tamanho de 8 caracteres para os reais (acrescentando zeros à esquerda),
204
+ # e 2 caracteres nos centavos (acrescentando zeros à esquerda).
205
+ #
206
+ # @return [Float] 99999999.99
207
+ #
208
+ def self.valor_documento_tamanho_maximo
209
+ 99999999.99
210
+ end
211
+
212
+ # Validações de todos os boletos
213
+ #
214
+ validates :carteira, :valor_documento, :numero_documento, :data_vencimento, presence: true
215
+ validates :cedente, :endereco_cedente, presence: true
216
+ validates :sacado, :documento_sacado, presence: true
217
+ validates :valor_documento, numericality: { less_than_or_equal_to: ->(object) { object.class.valor_documento_tamanho_maximo } }
218
+ validate :data_vencimento_deve_ser_uma_data
219
+
220
+ # Passing the attributes as Hash or block
221
+ #
222
+ # @overload initialize(options = {}, &block)
223
+ # @param [Hash] options Passing a hash accessing the attributes of the self.
224
+ # @option options [String] :cedente
225
+ # @option options [String] :codigo_cedente
226
+ # @option options [String] :documento_cedente
227
+ # @option options [String] :endereco_cedente
228
+ # @option options [String] :conta_corrente
229
+ # @option options [String] :agencia
230
+ # @option options [Date] :data_vencimento
231
+ # @option options [String] :numero_documento
232
+ # @option options [Float] :valor_documento
233
+ # @option options [String] :codigo_moeda
234
+ # @option options [String] :especie
235
+ # @option options [String] :especie_documento
236
+ # @option options [String] :sacado
237
+ # @option options [String] :documento_sacado
238
+ #
239
+ # @param [Proc] block Optional params. Passing a block accessing the attributes of the self.
240
+ #
241
+ # For the options, waiting for the ActiveModel 4 and the ActiveModel::Model. :)
242
+ #
243
+ # === Exemplos
244
+ #
245
+ # O recomendado é usar os boletos herdando de seu respectivo banco. Por exemplo:
246
+ #
247
+ # class Sicoob < BrBoleto::Sicoob
248
+ # end
249
+ #
250
+ # Agora você pode emitir um boleto usando a classe criada acima:
251
+ #
252
+ # Sicoob.new(conta_corrente: '89755', agencia: '0097', :carteira => '195')
253
+ #
254
+ # Você pode usar blocos se quiser:
255
+ #
256
+ # Sicoob.new do |boleto|
257
+ # boleto.conta_corrente = '89755'
258
+ # boleto.agencia = '0097'
259
+ # boleto.carteira = '198'
260
+ # boleto.numero_documento = '12345678'
261
+ # boleto.codigo_cedente = '909014'
262
+ # end
263
+ #
264
+ def initialize(options={}, &block)
265
+ default_values.merge(options).each do |attribute, value|
266
+ send("#{attribute}=", value) if respond_to?("#{attribute}=")
267
+ end
268
+
269
+ yield(self) if block_given?
270
+ end
271
+
272
+ # Opções default.
273
+ #
274
+ # Caso queira sobrescrever as opções, você pode simplesmente instanciar o objeto passando a opção desejada:
275
+ #
276
+ # class Bradesco < BrBoleto::Bradesco
277
+ # end
278
+ #
279
+ # Bradesco.new do |bradesco|
280
+ # bradesco.codigo_moeda = 'outro_codigo_da_moeda'
281
+ # bradesco.especie = 'outra_especie_que_nao_seja_em_reais'
282
+ # bradesco.especie_documento = 'outra_especie_do_documento'
283
+ # bradesco.data_documento = Date.tomorrow
284
+ # bradesco.aceite = false
285
+ # end
286
+ #
287
+ # @return [Hash] Código da Moeda sendo '9' (real). Espécie sendo 'R$' (real).
288
+ #
289
+ def default_values
290
+ {
291
+ :codigo_moeda => '9',
292
+ :especie => 'R$',
293
+ :especie_documento => 'DM',
294
+ :local_pagamento => 'PAGÁVEL EM QUALQUER BANCO ATÉ O VENCIMENTO',
295
+ :data_documento => Date.current,
296
+ :aceite => true
297
+ }
298
+ end
299
+
300
+ # Tipo de cobrança
301
+ # Ex: :com_registro, :sem_registro, :caucionada
302
+ # A implementação para esse valor deve ser implementada para cada banco,
303
+ # pois cada banco tem uma maneira diferente para saber o tipo de cobrança.
304
+ #
305
+ # Obs: O VALOR DESSE METODO NÃO INFLUÊNCIA NA GERAÇÃO DO BOLETO
306
+ # É APENAS PARA QUESTÃO DE INFORMAÇÃO CASO PRECISE PARA OUTRAS COISAS, POR EXEMPLO:
307
+ # É UTILIZADO NOS PAGAMENTOS DAS REMESSAS, MAIS ESPECIFICAMENTE NO COMPLEMENTO TRAILER
308
+ # DO LOTE PARA O BANCO SICOOB NO CNAB 240.
309
+ def tipo_cobranca_formatada
310
+ end
311
+
312
+ # Código do Banco.
313
+ # <b>Esse campo é específico para cada banco</b>.
314
+ #
315
+ # @return [String] Corresponde ao código do banco.
316
+ #
317
+ # @raise [NotImplementedError] Precisa implementar nas subclasses.
318
+ #
319
+ def codigo_banco
320
+ raise NotImplementedError.new("Not implemented #codigo_banco in #{self}.")
321
+ end
322
+
323
+ # Dígito do código do banco.
324
+ # <b>Esse campo é específico para cada banco</b>.
325
+ #
326
+ # @return [String] Corresponde ao dígito do código do banco.
327
+ # @raise [NotImplementedError] Precisa implementar nas subclasses.
328
+ #
329
+ def digito_codigo_banco
330
+ raise NotImplementedError.new("Not implemented #digito_codigo_banco in #{self}.")
331
+ end
332
+
333
+ # Esses métodos servem apenas para questão de testes
334
+ # Não são utilizados nas subclasses.
335
+ # Devem obrigatóriamente ser sobrescritos nas subclasses
336
+ def self.tamanho_maximo_agencia
337
+ 4
338
+ end
339
+ def self.tamanho_maximo_codigo_cedente
340
+ 6
341
+ end
342
+ def self.tamanho_maximo_numero_documento
343
+ 6
344
+ end
345
+
346
+ # Formata o código do banco com o dígito do código do banco.
347
+ # Método usado para o campo de código do banco localizado no cabeçalho do boleto.
348
+ #
349
+ # @return [String]
350
+ #
351
+ def codigo_banco_formatado
352
+ "#{codigo_banco}-#{digito_codigo_banco}"
353
+ end
354
+
355
+ # Agência, código do cedente ou nosso número.
356
+ # <b>Esse campo é específico para cada banco</b>.
357
+ #
358
+ # @return [String] - Corresponde aos campos "Agencia / Codigo do Cedente".
359
+ # @raise [NotImplementedError] Precisa implementar nas subclasses.
360
+ #
361
+ def agencia_codigo_cedente
362
+ raise NotImplementedError.new("Not implemented #agencia_codigo_cedente in #{self}.")
363
+ end
364
+
365
+ # O Nosso Número é o número que identifica unicamente um boleto para uma conta.
366
+ # O tamanho máximo do Nosso Número depende do banco e carteira.
367
+ #
368
+ # <b>Para carteiras registradas, você deve solicitar ao seu banco um intervalo de números para utilização.</b>
369
+ # Quando estiver perto do fim do intervalo, deve solicitar um novo intervalo.
370
+ #
371
+ # <b>Para carteiras não registradas o Nosso Número é livre</b>.
372
+ # Ao receber o retorno do banco, é através do Nosso Número que será possível identificar os boletos pagos.
373
+ #
374
+ # <b>Esse campo é específico para cada banco</b>.
375
+ #
376
+ # @return [String] Corresponde ao formato específico de cada banco.
377
+ # @raise [NotImplementedError] Precisa implementar nas subclasses.
378
+ #
379
+ def nosso_numero
380
+ raise NotImplementedError.new("Not implemented #nosso_numero in #{self}.")
381
+ end
382
+
383
+ # Formata o valor do documentado para ser mostrado no código de barras
384
+ # e na linha digitável com 08 dígitos na casa dos Reais e 02 dígitos nas casas dos centavos.
385
+ #
386
+ # @example
387
+ #
388
+ # Bradesco.new(:valor_documento => 123.45).valor_formatado_para_codigo_de_barras
389
+ # # => "0000012345"
390
+ #
391
+ # @return [String] Precisa retornar 10 dígitos para o código de barras (incluindo os centavos).
392
+ #
393
+ def valor_formatado_para_codigo_de_barras
394
+ valor_documento_formatado = (Integer(valor_documento.to_f * 100) / Float(100))
395
+ real, centavos = valor_documento_formatado.to_s.split(/\./)
396
+ "#{real.rjust(8, '0')}#{centavos.ljust(2, '0')}"
397
+ end
398
+
399
+ # Força a carteira a retornar o valor como string
400
+ #
401
+ # @return [String]
402
+ #
403
+ def carteira
404
+ @carteira.to_s if @carteira.present?
405
+ end
406
+
407
+ # Embora o padrão seja mostrar o número da carteira no boleto,
408
+ # <b>alguns bancos</b> requerem que seja mostrado um valor diferente na carteira.
409
+ # <b>Para essas exceções, sobrescreva esse método na subclasse.</b>
410
+ #
411
+ # @return [String] retorna o número da carteira
412
+ #
413
+ def carteira_formatada
414
+ carteira
415
+ end
416
+
417
+ # Se o aceite for 'true', retorna 'S'.
418
+ # Retorna 'N', caso contrário.
419
+ #
420
+ # @return [String]
421
+ #
422
+ def aceite_formatado
423
+ if @aceite.present?
424
+ 'S'
425
+ else
426
+ 'N'
427
+ end
428
+ end
429
+
430
+ # Fator de vencimento que é calculado a partir de uma data base.
431
+ # Veja <b>FatorVencimento</b> para mais detalhes.
432
+ #
433
+ # @return [String] 4 caracteres.
434
+ #
435
+ def fator_de_vencimento
436
+ FatorVencimento.new(data_vencimento)
437
+ end
438
+
439
+ # === Código de Barras
440
+ #
441
+ # O código de barras contêm exatamente 44 posições nessa sequência:
442
+ #
443
+ # ____________________________________________________________
444
+ # | Posição | Tamanho | Descrição |
445
+ # |----------|---------|--------------------------------------|
446
+ # | 01-03 | 03 | Código do banco |
447
+ # | 04 | 01 | Código da moeda |
448
+ # | 05 | 01 | Dígito do código de barras (DAC) |
449
+ # | 06-09 | 04 | Fator de vencimento |
450
+ # | 10-19 | 10 | Valor do documento |
451
+ # | 20-44 | 25 | Critério de cada Banco (Campo livre) |
452
+ # -------------------------------------------------------------
453
+ #
454
+ # @return [String] Código de barras com 44 posições.
455
+ #
456
+ def codigo_de_barras
457
+ "#{codigo_de_barras_padrao}#{codigo_de_barras_do_banco}".insert(4, digito_codigo_de_barras)
458
+ end
459
+
460
+ # Primeira parte do código de barras.
461
+ # <b>Essa parte do código de barras é padrão para todos os bancos.</b>.
462
+ #
463
+ # @return [String] Primeiras 18 posições do código de barras (<b>Não retorna o DAC do código de barras</b>).
464
+ #
465
+ def codigo_de_barras_padrao
466
+ "#{codigo_banco}#{codigo_moeda}#{fator_de_vencimento}#{valor_formatado_para_codigo_de_barras}"
467
+ end
468
+
469
+ # Segunda parte do código de barras.
470
+ # <b>Esse campo é específico para cada banco</b>.
471
+ #
472
+ # @return [String] 25 últimas posições do código de barras.
473
+ # @raise [NotImplementedError] Precisa implementar nas subclasses.
474
+ #
475
+ def codigo_de_barras_do_banco
476
+ raise NotImplementedError.new("Not implemented #codigo_de_barras_do_banco in #{self}.")
477
+ end
478
+
479
+ # Dígito verificador do código de barras (DAC).
480
+ #
481
+ # Por definição da FEBRABAN e do Banco Central do Brasil,
482
+ # na <b>5º posição do Código de Barras</b>, deve ser indicado obrigatoriamente
483
+ # o “dígito verificador” (DAC), calculado através do módulo 11.
484
+ #
485
+ # <b>OBS.:</b> Para mais detalhes deste cálculo,
486
+ # veja a descrição em <b>BrBoleto::Calculos::Modulo11FatorDe2a9</b>.
487
+ #
488
+ # @return [String] Dígito calculado do código de barras.
489
+ #
490
+ def digito_codigo_de_barras
491
+ Modulo11FatorDe2a9.new("#{codigo_de_barras_padrao}#{codigo_de_barras_do_banco}")
492
+ end
493
+
494
+ # Representação numérica do código de barras, mais conhecida como linha digitável! :p
495
+ #
496
+ # A representação numérica do código de barras é composta, por cinco campos.
497
+ # Sendo os três primeiros campos, amarrados por DAC's (dígitos verificadores),
498
+ # todos calculados pelo módulo 10.
499
+ #
500
+ # <b>OBS.:</b> Para mais detalhes deste cálculo, veja a descrição em Modulo10.
501
+ #
502
+ # === Linha Digitável
503
+ #
504
+ # A linha digitável contêm exatamente 47 posições nessa sequência:
505
+ #
506
+ # _______________________________________________________________________________________________________
507
+ # |Campo | Posição | Tamanho | Descrição |
508
+ # |------|----------|---------|--------------------------------------------------------------------------|
509
+ # | 1º | 01-03 | 03 | Código do banco (posições 1 a 3 do código de barras) |
510
+ # | | 04 | 01 | Código da moeda (posição 4 do código de barras) |
511
+ # | | 05-09 | 5 | Cinco posições do campo livre (posições 20 a 24 do código de barras) |
512
+ # | | 10 | 1 | Dígito verificador do primeiro campo (Módulo10) |
513
+ # |------------------------------------------------------------------------------------------------------|
514
+ # | 2º | 11-20 | 10 | 6º a 15º posições do campo livre (posições 25 a 34 do código de barras) |
515
+ # | | 21 | 01 | Dígito verificador do segundo campo (Módulo10) |
516
+ # |------------------------------------------------------------------------------------------------------|
517
+ # | 3º | 22-31 | 10 | 16º a 25º posições do campo livre (posições 35 a 44 do código de barras) |
518
+ # | | 32 | 01 | Dígito verificador do terceiro campo (Módulo10) |
519
+ # |------------------------------------------------------------------------------------------------------|
520
+ # | 4º | 33 | 01 | Dígito verificador do código de barras (posição 5 do código de barras) |
521
+ # |------------------------------------------------------------------------------------------------------|
522
+ # | 5ª | 34-37 | 04 | Fator de vencimento (posições 6 a 9 do código de barras) |
523
+ # | | 38-47 | 10 | Valor nominal do documento (posições 10 a 19 do código de barras) |
524
+ # -------------------------------------------------------------------------------------------------------|
525
+ #
526
+ # @return [String] Contêm a representação numérica do código de barras formatado com pontos e espaços.
527
+ #
528
+ def linha_digitavel
529
+ LinhaDigitavel.new(codigo_de_barras)
530
+ end
531
+
532
+ # Returns a string that <b>identifying the render path associated with the object</b>.
533
+ #
534
+ # <b>ActionPack uses this to find a suitable partial to represent the object.</b>
535
+ #
536
+ # @return [String]
537
+ #
538
+ def to_partial_path
539
+ "br_boleto/#{self.class.name.demodulize.underscore}"
540
+ end
541
+
542
+ # Seguindo a interface do Active Model.
543
+ #
544
+ # @return [False]
545
+ #
546
+ def persisted?
547
+ false
548
+ end
549
+
550
+ # Método usado para verificar se deve realizar a validação de tamanho do campo 'agência'.
551
+ # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
552
+ #
553
+ # @return [True]
554
+ #
555
+ def deve_validar_agencia?
556
+ true
557
+ end
558
+
559
+ # Método usado para verificar se deve realizar a validação de tamanho do campo 'conta_corrente'.
560
+ # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
561
+ #
562
+ # @return [True]
563
+ #
564
+ def deve_validar_conta_corrente?
565
+ true
566
+ end
567
+
568
+ # Método usado para verificar se deve realizar a validação de tamanho do campo 'codigo_cedente'.
569
+ # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
570
+ #
571
+ # @return [True]
572
+ #
573
+ def deve_validar_codigo_cedente?
574
+ true
575
+ end
576
+
577
+ # Método usado para verificar se deve realizar a validação de tamanho do campo 'numero_documento'.
578
+ # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
579
+ #
580
+ # @return [True]
581
+ #
582
+ def deve_validar_numero_documento?
583
+ true
584
+ end
585
+
586
+ # Método usado para verificar se deve realizar a validação do campo 'carteira'.
587
+ # <b>Sobrescreva esse método na subclasse, caso você mesmo queira fazer as validações</b>.
588
+ #
589
+ # @return [True]
590
+ #
591
+ def deve_validar_carteira?
592
+ true
593
+ end
594
+
595
+ # Verifica e valida se a data do vencimento deve ser uma data válida.
596
+ # <b>Precisa ser uma data para o cálculo do fator do vencimento.</b>
597
+ #
598
+ def data_vencimento_deve_ser_uma_data
599
+ errors.add(:data_vencimento, :invalid) unless data_vencimento.kind_of?(Date)
600
+ end
601
+
602
+
603
+ ################ FORMATAÇÃO PARA CPF OU CNPJ ################
604
+ # tanto o documento do sacado quandto do cedente possui 3 tipos de formatação
605
+ # EX:
606
+ # documento_sacado = '12345678901'
607
+ # atributo + '_formatado':
608
+ # documento_sacado_formatado = '123.456.789-01'
609
+ # atributo + '_formatado_com_label':
610
+ # documento_sacado_formatado_com_label = 'CPF 123.456.789-01'
611
+ #
612
+ # OBS: O documento_cedente e documento_sacado SEMPRE irão retornar o valor sem a formatação
613
+ # mesmo que seja setado
614
+ ##############################################################
615
+
616
+ # Retorna o documento do sacado com tamanho 0, 11 ou 14 caracteres
617
+ # Sempre retorna o valor sem a formatação
618
+ #
619
+ # @return String
620
+ #
621
+ def documento_sacado
622
+ return "" unless @documento_sacado.present?
623
+ BrBoleto::Helper::CpfCnpj.new(@documento_sacado).sem_formatacao
624
+ end
625
+
626
+ # Retorna o documento do sacado formatado
627
+ #
628
+ # @return String
629
+ #
630
+ def documento_sacado_formatado
631
+ BrBoleto::Helper::CpfCnpj.new(documento_sacado).com_formatacao
632
+ end
633
+
634
+ # Retorna o documento do sacado formatado com label de CNPJ ou CPF
635
+ #
636
+ # @return String
637
+ #
638
+ def documento_sacado_formatado_com_label
639
+ BrBoleto::Helper::CpfCnpj.new(documento_sacado).formatado_com_label
640
+ end
641
+
642
+ # Retorna o documento do cedente com tamanho 0, 11 ou 14 caracteres
643
+ # Sempre retorna o valor sem a formatação
644
+ #
645
+ # @return String
646
+ #
647
+ def documento_cedente
648
+ return "" unless @documento_cedente.present?
649
+ BrBoleto::Helper::CpfCnpj.new(@documento_cedente).sem_formatacao
650
+ end
651
+
652
+ # Retorna o documento do cedente formatado
653
+ #
654
+ # @return String
655
+ #
656
+ def documento_cedente_formatado
657
+ BrBoleto::Helper::CpfCnpj.new(documento_cedente).com_formatacao
658
+ end
659
+
660
+ # Retorna o documento do cedente formatado com label de CNPJ ou CPF
661
+ #
662
+ # @return String
663
+ #
664
+ def documento_cedente_formatado_com_label
665
+ BrBoleto::Helper::CpfCnpj.new(documento_cedente).formatado_com_label
666
+ end
667
+ end
668
+ end
636
669
  end