br_boleto 1.0.1 → 1.1.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 (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