br_boleto 1.2.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.markdown +278 -98
  5. data/br_boleto.gemspec +5 -3
  6. data/lib/br_boleto/active_model_base.rb +1 -1
  7. data/lib/br_boleto/association/have_conta.rb +109 -0
  8. data/lib/br_boleto/association/have_pagador.rb +38 -0
  9. data/lib/br_boleto/association/have_pagamentos.rb +44 -0
  10. data/lib/br_boleto/boleto/base.rb +50 -379
  11. data/lib/br_boleto/boleto/caixa.rb +28 -143
  12. data/lib/br_boleto/boleto/sicoob.rb +24 -144
  13. data/lib/br_boleto/conta/base.rb +288 -0
  14. data/lib/br_boleto/conta/caixa.rb +109 -0
  15. data/lib/br_boleto/conta/sicoob.rb +64 -0
  16. data/lib/br_boleto/helper/default_codes.rb +33 -0
  17. data/lib/br_boleto/helper/format_value.rb +1 -0
  18. data/lib/br_boleto/helper/number.rb +30 -0
  19. data/lib/br_boleto/pagador.rb +82 -0
  20. data/lib/br_boleto/remessa/base.rb +28 -50
  21. data/lib/br_boleto/remessa/cnab240/base.rb +22 -131
  22. data/lib/br_boleto/remessa/cnab240/caixa.rb +16 -62
  23. data/lib/br_boleto/remessa/cnab240/helper/header_arquivo.rb +7 -7
  24. data/lib/br_boleto/remessa/cnab240/helper/header_lote.rb +6 -6
  25. data/lib/br_boleto/remessa/cnab240/helper/segmento_p.rb +22 -22
  26. data/lib/br_boleto/remessa/cnab240/helper/segmento_q.rb +16 -16
  27. data/lib/br_boleto/remessa/cnab240/helper/segmento_r.rb +3 -3
  28. data/lib/br_boleto/remessa/cnab240/helper/segmento_s.rb +3 -3
  29. data/lib/br_boleto/remessa/cnab240/helper/trailer_arquivo.rb +3 -3
  30. data/lib/br_boleto/remessa/cnab240/helper/trailer_lote.rb +3 -3
  31. data/lib/br_boleto/remessa/cnab240/sicoob.rb +36 -73
  32. data/lib/br_boleto/remessa/cnab400/base.rb +95 -0
  33. data/lib/br_boleto/remessa/cnab400/helper/detalhe.rb +136 -0
  34. data/lib/br_boleto/remessa/cnab400/helper/header.rb +114 -0
  35. data/lib/br_boleto/remessa/cnab400/helper/trailer.rb +50 -0
  36. data/lib/br_boleto/remessa/cnab400/sicoob.rb +249 -0
  37. data/lib/br_boleto/remessa/lote.rb +1 -23
  38. data/lib/br_boleto/remessa/pagamento.rb +188 -51
  39. data/lib/br_boleto/retorno/base.rb +9 -0
  40. data/lib/br_boleto/retorno/cnab240/base.rb +2 -10
  41. data/lib/br_boleto/retorno/cnab400/base.rb +48 -0
  42. data/lib/br_boleto/retorno/cnab400/sicoob.rb +42 -0
  43. data/lib/br_boleto/retorno/pagamento.rb +12 -6
  44. data/lib/br_boleto/string_methods.rb +8 -2
  45. data/lib/br_boleto/validations.rb +19 -0
  46. data/lib/br_boleto/version.rb +3 -3
  47. data/lib/br_boleto.rb +38 -8
  48. data/lib/config/locales/br-boleto-en.yml +89 -0
  49. data/lib/config/locales/br-boleto-pt-BR.yml +89 -0
  50. data/test/br_boleto/association/have_conta_test.rb +319 -0
  51. data/test/br_boleto/association/have_pagador_test.rb +110 -0
  52. data/test/br_boleto/association/have_pagamentos_test.rb +113 -0
  53. data/test/br_boleto/boleto/base_test.rb +127 -201
  54. data/test/br_boleto/boleto/caixa_test.rb +58 -72
  55. data/test/br_boleto/boleto/sicoob_test.rb +88 -147
  56. data/test/br_boleto/conta/base_test.rb +490 -0
  57. data/test/br_boleto/conta/caixa_test.rb +154 -0
  58. data/test/br_boleto/conta/sicoob_test.rb +144 -0
  59. data/test/br_boleto/helper/number_test.rb +29 -0
  60. data/test/br_boleto/pagador_test.rb +158 -0
  61. data/test/br_boleto/remessa/base_test.rb +37 -62
  62. data/test/br_boleto/remessa/cnab240/base_test.rb +75 -95
  63. data/test/br_boleto/remessa/cnab240/caixa_test.rb +61 -96
  64. data/test/br_boleto/remessa/cnab240/helper/header_arquivo_test.rb +11 -11
  65. data/test/br_boleto/remessa/cnab240/helper/header_lote_test.rb +8 -8
  66. data/test/br_boleto/remessa/cnab240/helper/segmento_p_test.rb +17 -15
  67. data/test/br_boleto/remessa/cnab240/helper/segmento_q_test.rb +13 -13
  68. data/test/br_boleto/remessa/cnab240/helper/segmento_r_test.rb +2 -2
  69. data/test/br_boleto/remessa/cnab240/helper/segmento_s_test.rb +3 -3
  70. data/test/br_boleto/remessa/cnab240/helper/trailer_arquivo_test.rb +1 -1
  71. data/test/br_boleto/remessa/cnab240/helper/trailer_lote_test.rb +1 -1
  72. data/test/br_boleto/remessa/cnab240/sicoob_test.rb +136 -131
  73. data/test/br_boleto/remessa/cnab400/base_test.rb +263 -0
  74. data/test/br_boleto/remessa/cnab400/sicoob_test.rb +179 -0
  75. data/test/br_boleto/remessa/lote_test.rb +2 -41
  76. data/test/br_boleto/remessa/pagamento_test.rb +186 -188
  77. data/test/br_boleto/retorno/base_test.rb +0 -1
  78. data/test/br_boleto/retorno/cnab240/base_test.rb +12 -11
  79. data/test/br_boleto/retorno/cnab240/caixa_test.rb +11 -11
  80. data/test/br_boleto/retorno/cnab240/sicoob_test.rb +11 -11
  81. data/test/br_boleto/retorno/cnab400/sicoob_test.rb +227 -0
  82. data/test/br_boleto/retorno/pagamento_test.rb +6 -6
  83. data/test/factories/boleto/base.rb +9 -7
  84. data/test/factories/boleto/boleto_caixa.rb +2 -9
  85. data/test/factories/boleto/boleto_sicoob.rb +10 -8
  86. data/test/factories/conta/base.rb +10 -0
  87. data/test/factories/conta/caixa.rb +15 -0
  88. data/test/factories/conta/sicoob.rb +16 -0
  89. data/test/factories/pagador.rb +15 -0
  90. data/test/factories/remessa/base.rb +0 -6
  91. data/test/factories/remessa/cnab240/base.rb +0 -10
  92. data/test/factories/remessa/cnab240/caixa.rb +1 -6
  93. data/test/factories/remessa/cnab240/sicoob.rb +1 -10
  94. data/test/factories/remessa/cnab400/base.rb +8 -0
  95. data/test/factories/remessa/cnab400/sicoob.rb +8 -0
  96. data/test/factories/remessa/pagamento.rb +8 -7
  97. data/test/fixtures/remessa/cnab240/sicoob.rem +8 -0
  98. data/test/{files → fixtures}/retorno/cnab240/caixa.ret +0 -0
  99. data/test/{files → fixtures}/retorno/cnab240/padrao240.ret +0 -0
  100. data/test/fixtures/retorno/cnab400/sicoob.ret +7 -0
  101. data/test/inheritance/boleto_test.rb +4 -1
  102. data/test/inheritance/sicoob_test.rb +23 -7
  103. data/test/test_helper.rb +70 -0
  104. metadata +63 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e251082e45232d8d43cf666641b8db24670b034f
4
- data.tar.gz: 348d22561d586b904762f0ac3159e53bb7b86512
3
+ metadata.gz: 294ff39fa89db1c6ba4b5d5b19b8fab67b1aec44
4
+ data.tar.gz: b95de65b899273762c04d225aa85cdbbaa3f91fc
5
5
  SHA512:
6
- metadata.gz: 2bcfad706412d14bcb9ebffa6acae7a9712616bd9bd2bf78ce32f49694ee47ac1d2c6d45daeeaee37fb29741559a5295645ee61571af4e9e12fdef0a36c8b3ee
7
- data.tar.gz: 786abed167db7f2ea5beab350cf002b87c4c1b09a1c5ba26000d3fe8910494bd0070ac41d7cfb8426beed89965128b6ebdd318bdc9dfc2e7c7857b99e959adec
6
+ metadata.gz: a330174ff34f16d4456533e874020123e40dff5c7c0ecce1f5efdb6154fbece15e39d20bd60733f272e76f860420663a463fff8d62e553e5462b2f07ddeb4de0
7
+ data.tar.gz: a5f2c505bd24a19295c904d5ef87fc6201f5a95b980fc083a6fd080316b37c2acc5e290c1bf7881b3830c969dc713b8edd8fa529f82c039167094d24663019cb
data/.gitignore CHANGED
@@ -3,3 +3,4 @@ coverage/
3
3
  **/*.subl*
4
4
  **/*.~lock.*
5
5
  dev_load_data.rb
6
+ br_boleto*.gem
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- br_boleto (1.2.2)
4
+ br_boleto (2.0.0)
5
5
  activemodel (~> 4.2)
6
6
  activesupport (~> 4.2)
7
7
  rake (>= 0.8.7)
data/README.markdown CHANGED
@@ -10,21 +10,15 @@ Emissão de Boletos Bancários em Ruby.
10
10
 
11
11
  1. Boleto bancário (apenas os cálculos para o boleto, sem a interface) para os bancos:
12
12
  - Sicoob
13
- - Caixa
13
+ - Caixa (em andamento)
14
14
  2. Arquivo de remessa para os Bancos:
15
- - Sicoob (CNAB 240)
15
+ - Sicoob (CNAB 240 e CNAB400)
16
16
  - Caixa (CNAB 240)
17
17
  3. Arquivo de retorno para os Bancos:
18
- - Sicoob (CNAB 240)
18
+ - Sicoob (CNAB 240 e CNAB400)
19
19
  - Caixa (CNAB 240)
20
20
 
21
- ## Alternativas
22
-
23
- Essa biblioteca é baseada em outras **ótimas** bibliotecas.
24
- **Recomendo analisar muito bem cada solução**:
25
21
 
26
- * Brcobranca [https://github.com/kivanio/brcobranca](https://github.com/kivanio/brcobranca)
27
- * Gem de Boleto Bancário [https://github.com/tomas-stefano/boleto_bancario](https://github.com/tomas-stefano/boleto_bancario)
28
22
 
29
23
  ## Instalação
30
24
  **Manualmente**
@@ -76,55 +70,228 @@ Para todos os bancos e carteiras implementadas, **seguimos as documentações**
76
70
  <table>
77
71
  <tr>
78
72
  <th>Nome do Banco</th>
73
+ <th>CNAB</th>
79
74
  <th>Testada/Homologada no banco</th>
80
75
  <th>Autor </th>
81
76
  </tr>
82
77
  <tr>
83
78
  <td>Sicoob</td>
79
+ <td>240</td>
84
80
  <td>Homologado dia 07/08/2015</td>
85
81
  <td>Bruno M. Mergen</td>
86
82
  </tr>
83
+ <tr>
84
+ <td>Sicoob</td>
85
+ <td>400</td>
86
+ <td>Pendente</td>
87
+ <td>Bruno M. Mergen</td>
88
+ </tr>
87
89
  <tr>
88
90
  <td>Caixa</td>
91
+ <td>240</td>
89
92
  <td>Pendente</td>
90
93
  <td></td>
91
94
  </tr>
92
95
  </table>
93
96
 
94
- ## Como usar
97
+ # Como usar
95
98
 
96
- Você pode usar as próprias classes da gem, porém, **recomendo criar uma subclasse** para os bancos que você gostaria de desenvolver.
99
+ ## Começando
100
+ Em todas as classes desenvolvidas é possível instanciar objetos em forma de `Hash` ou `Block`. Exemplo:
101
+ ```ruby
102
+ obj1 = BrBoleto::Pagador.new(nome: 'João')
103
+ obj2 = BrBoleto::Pagador.new do |pagador|
104
+ pagador.nome = 'João'
105
+ end
106
+ ```
107
+
108
+ As associações também podem ser instanciadas em forma de `Hash`ou `Block`. Exemplo:
109
+ ```ruby
110
+ boleto1 = BrBoleto::Boleto::Sicoob.new do |boleto|
111
+ boleto.conta do |ct|
112
+ ct.agencia = 1234
113
+ ct.carteira = 1
114
+ end
115
+ end
116
+
117
+ boleto1.conta.agencia
118
+ # => "1234"
97
119
 
98
- ### Exemplo
120
+ # OU
121
+
122
+ boleto2 = BrBoleto::Boleto::Sicoob.new({
123
+ conta: {
124
+ agencia: 7465,
125
+ carteira: 2
126
+ }
127
+ }
128
+
129
+ boleto2.conta.agencia
130
+ # => "7465"
131
+
132
+ # OU
133
+
134
+ conta = BrBoleto::Conta::Sicoob.new(agencia: 4522)
135
+ boleto2 = BrBoleto::Boleto::Sicoob.new(conta: conta)
136
+ boleto2.conta.agencia
137
+ # => "4522"
138
+ ```
139
+
140
+
141
+ ### Classes auxiliares
142
+ Devido a falta de padronização de regras e nomenclaturas entre os banco, essa gem é composta por classes auxiliares para conseguir manter o minimo de padronização com sua utilização e nomenclaturas.
143
+
144
+ #### Conta
145
+ Para gerar **boletos** e **remessas** é necessário de uma conta bancária, certo? Pensando nisso foi criado uma classe onde contém todas as regras e informações referente a conta bancária. Existe uma classe para cada banco desenvolvido. **Vejamos um exemplo com o banco Sicoob:**
146
+ ```ruby
147
+ conta = BrBoleto::Conta::Sicoob.new({
148
+ codigo_beneficiario: '253167',
149
+ codigo_beneficiario_dv: '4', # Se não passar o dv irá gerar automaticamente
150
+ conta_corrente: '887469',
151
+ conta_corrente_dv: '7', # Se não passar o dv irá gerar automaticamente
152
+ agencia: '3069',
153
+ carteira: '1',
154
+ modalidade: '02' ,
155
+ razao_social: 'Razao Social emitente',
156
+ cpf_cnpj: '98137264000196',
157
+ endereco: 'Rua nome da rua, 9999',
158
+ })
159
+
160
+ ```
161
+
162
+ #### Pagador
163
+ O pagador é o "cliente" que vai pagar o boleto/cobrança. É utilizado no boleto e no Pagamento da remessa.
164
+ ```ruby
165
+ pagador = BrBoleto::Pagador.new do
166
+ nome = 'João da Silva'
167
+ cpf_cnpj = '33.669.170/0001-12' # Gerado pelo gerador de cnpj
168
+ endereco = 'RUA DO PAGADOR'
169
+ bairro = 'Bairro do pagador'
170
+ cep = '89885-000'
171
+ cidade = 'Chapecó'
172
+ uf = 'SC'
173
+ nome_avalista = 'Maria avalista'
174
+ documento_avalista = '840.106.990-43' # Gerado pelo gerador de CPF
175
+ end
176
+ ```
177
+
178
+ #### Pagamento
179
+ É utilizado apenas para gerar remessas. Cada pagamento representa 1 boleto (por exemplo). Exemplo:
180
+
181
+ ```ruby
182
+ pagamento = BrBoleto::Remessa::Pagamento.new({
183
+ nosso_numero: "123456",
184
+ numero_documento: "977897",
185
+ data_vencimento: Date.tomorrow,
186
+ valor_documento: 100.12,
187
+ pagador: {
188
+ nome: 'João da Silva',
189
+ cpf_cnpj: '33.669.170/0001-12', # Gerado pelo gerador de pdf online
190
+ # ....
191
+ },
192
+ data_emissao: Date.today, # Valor default
193
+ valor_mora: 0.0, # Valor default
194
+ valor_desconto: 0.0, # Valor default
195
+ valor_iof: 0.0, # Valor default
196
+ valor_abatimento: 0.0, # Valor default
197
+ cod_desconto: '0', # Valor default
198
+ desconto_2_codigo: '0', # Valor default
199
+ desconto_2_valor: 0.0, # Valor default
200
+ desconto_3_codigo: '0', # Valor default
201
+ desconto_3_valor: 0.0, # Valor default
202
+ codigo_multa: '3', # Valor default
203
+ codigo_juros: '3', # Valor default
204
+ valor_multa: 0.0, # Valor default
205
+ valor_juros: 0.0, # Valor default
206
+ parcela: '1', # Valor default
207
+ tipo_impressao: '1', # Valor default
208
+ tipo_emissao: '2', # Valor default
209
+ identificacao_ocorrencia: '01', # Valor default
210
+ especie_titulo: '01', # Valor default
211
+ codigo_moeda: '9', # Valor default
212
+ forma_cadastramento: '0', # Valor default
213
+ emissao_boleto: '2', # Valor default
214
+ distribuicao_boleto: '2', # Valor default
215
+ })
216
+ ```
217
+
218
+ ## Sobrescrevendo classes e validações
219
+
220
+ Você pode usar as próprias classes da gem, porém, **recomendo criar uma subclasse** para os bancos que você gostaria de desenvolver. Com isso também é possível sobrescrever validações e métodos da gem. (*Isso pode ser útil caso precise tratar alguma particularidade*)
221
+
222
+ ##### **Exemplo:**
99
223
 
100
224
  ```ruby
101
225
  class BoletoSicoob < BrBoleto::Boleto::Sicoob
226
+ def default_values
227
+ {
228
+ local_pagamento: 'PREFERENCIALMENTE NA EMPRESA XXXXX',
229
+ aceite: true
230
+ }
231
+ end
102
232
  end
103
233
 
234
+ boleto = BoletoSicoob.new()
235
+ boleto.aceite # true
236
+ boleto.local_pagamento # PREFERENCIALMENTE NA EMPRESA XXXXX
237
+ ```
238
+
239
+ Você pode também sobrescrever a `class` da conta, mas para isso será necessário sobrescrever um método na `class` do boleto para que funcione adequadamente:
240
+ ```ruby
241
+ class MinhaContaSicoob < BrBoleto::Conta::Sicoob
242
+ # Suas regras aqui
243
+ end
244
+ class MeuBoletoSicoob < BrBoleto::Boleto::Sicoob
245
+ def conta_class
246
+ MinhaContaSicoob # Sem isso sua conta personalizada não vai funcioanr
247
+ end
248
+ end
249
+
250
+ boleto = MeuBoletoSicoob.new
251
+ boleto.conta.class
252
+ # => MinhaContaSicoob
253
+ ```
254
+
255
+ Você pode sobrescrever os comportamentos na subclasse.
256
+ Por exemplo, imagine que você quer sobrescrever a forma como é tratada a segunda parte do código de barras.
257
+ **Seguindo a interface da classe BrBoleto::Boleto::Base** fica bem simples:
258
+
259
+ ```ruby
260
+ class BoletoSicoob < BrBoleto::Boleto::Sicoob
261
+ def codigo_de_barras_do_banco
262
+ # Sua implementação ...
263
+ end
264
+ end
104
265
  ```
105
266
 
106
267
  ### Criando os boletos / Validações
107
268
 
108
- Agora você pode emitir um boleto, **usando a classe criada no exemplo acima**:
269
+ Agora você pode emitir um boleto, **usando a classe criada no exemplo anterior**:
109
270
 
110
271
  ```ruby
111
- BoletoSicoob.new(agencia: '3195', codigo_cedente: '6532', numero_documento: '1101', carteira: '1', valor_documento: 105.78)
272
+ BoletoSicoob.new(conta: {agencia: '3195', codigo_cedente: '6532', carteira: '1'}, numero_documento: '1101', valor_documento: 105.78)
112
273
  ```
113
274
 
114
275
  Você pode usar blocos se quiser:
115
276
 
116
277
  ```ruby
117
278
  boleto_sicoob = BoletoSicoob.new do |boleto|
118
- boleto.agencia = '0097'
119
- boleto.carteira = '1'
120
- boleto.cedente = 'Razao Social da Empresa'
121
- boleto.codigo_cedente = '90901'
122
- boleto.endereco_cedente = 'Rua nome da rua, 9999'
279
+ boleto.conta = {
280
+ agencia: '0097',
281
+ carteira: '1',
282
+ modalidade: '01',
283
+ razao_social: 'Razao Social da Empresa',
284
+ codigo_cedente: '90901',
285
+ endereco: 'Rua nome da rua, 9999',
286
+ cpf_cnpj: '98137264000196', # Gerado pelo gerador de cnpj
287
+ }
288
+ boleto.pagador do |pag|
289
+ pag.nome = 'Nome do Sacado'
290
+ pag.cpf_cnpj = '35433793990'
291
+ end
123
292
  boleto.numero_documento = '12345678'
124
- boleto.sacado = 'Nome do Sacado'
125
- boleto.documento_sacado = '35433793990'
126
293
  boleto.data_vencimento = Date.tomorrow
127
- boleto.valor_documento = 31678.99
294
+ boleto.valor_documento = 31_678.99
128
295
  end
129
296
  ```
130
297
 
@@ -152,9 +319,9 @@ boleto_sicoob.linha_digitavel
152
319
 
153
320
  boleto_sicoob.nosso_numero
154
321
 
155
- boleto_sicoob.agencia_codigo_cedente
322
+ boleto_sicoob.conta.agencia_codigo_cedente
156
323
 
157
- boleto_sicoob.carteira_formatada # Formata a carteira, para mostrar no boleto.
324
+ boleto_sicoob.conta.carteira_formatada # Formata a carteira, para mostrar no boleto.
158
325
 
159
326
  boleto_sicoob.numero_documento
160
327
 
@@ -165,23 +332,9 @@ boleto_sicoob.especie
165
332
  boleto_sicoob.especie_documento
166
333
  ```
167
334
 
168
- ## Sobrescrevendo comportamentos
169
-
170
- Você pode sobrescrever os comportamentos na subclasse.
171
-
172
- Por exemplo, imagine que você quer sobrescrever a forma como é tratada a segunda parte do código de barras.
173
- **Seguindo a interface da classe BrBoleto::Boleto** fica bem simples:
174
-
175
- ```ruby
176
- class BoletoSicoob < BrBoleto::Boleto::Sicoob
177
- def codigo_de_barras_do_banco
178
- # Sua implementação ...
179
- end
180
- end
181
- ```
182
335
  #**Arquivo de remessa**
183
336
 
184
- ##**CNAB 240**
337
+ ## **CNAB 240**
185
338
  Um arquivo de remessa é composto de UM ou VÁRIOS lotes (class BrBoleto::Remessa::Lote).
186
339
  Estes lotes são compostos de UM ou VÁRIOS pagamentos (class BrBoleto::Remessa::Pagamento).
187
340
 
@@ -191,18 +344,26 @@ Com isso, deve-se instanciar um lote passando os dois pagamentos instanciados. E
191
344
  Exemplo:
192
345
  ```ruby
193
346
  boleto_1 = BrBoleto::Boleto::Sicoob.new({
194
- agencia: 3069,
195
- codigo_cedente: 6532,
347
+ conta: {
348
+ agencia: 3069,
349
+ codigo_cedente: 6532,
350
+ carteira: 1,
351
+ conta_corrente: '5679',
352
+ razao_social: 'Cedente 1',
353
+ cpf_cnpj: '12345678901',
354
+ },
355
+ pagador: {
356
+ nome: 'Sacado',
357
+ cpf_cnpj: '725.275.005-10',
358
+ endereco: 'Rua teste, 23045',
359
+ bairro: 'Centro',
360
+ cep: '89804-457',
361
+ cidade: 'Chapecó',
362
+ uf: 'SC'
363
+ },
196
364
  numero_documento: 10001,
197
- carteira: 1,
198
365
  valor_documento: 100.78,
199
- data_vencimento: Date.tomorrow,
200
- conta_corrente: '5679',
201
- cedente: 'Cedente 1',
202
- documento_cedente:'12345678901',
203
- sacado: 'Sacado',
204
- documento_sacado: '725.275.005-10',
205
- endereco_sacado: 'Rua teste, 23045',
366
+ data_vencimento: Date.tomorrow,
206
367
  instrucoes1: 'Lembrar de algo 1',
207
368
  instrucoes2: 'Lembrar de algo 2',
208
369
  instrucoes3: 'Lembrar de algo 3',
@@ -212,18 +373,26 @@ boleto_1 = BrBoleto::Boleto::Sicoob.new({
212
373
  })
213
374
 
214
375
  boleto_2 = BrBoleto::Boleto::Sicoob.new({
215
- agencia: 3069,
216
- codigo_cedente: 6532,
217
- numero_documento: 10002,
218
- carteira: 1,
376
+ conta: {
377
+ agencia: 3069,
378
+ codigo_cedente: 6532,
379
+ carteira: 1,
380
+ conta_corrente: '5679',
381
+ razao_social: 'Cedente 1',
382
+ cpf_cnpj: '12345678901',
383
+ },
384
+ pagador: {
385
+ nome: 'Sacado 2',
386
+ cpf_cnpj: '725.275.005-10',
387
+ endereco: 'Rua teste, 648',
388
+ bairro: 'Centro',
389
+ cep: '89804-301',
390
+ cidade: 'Xaxim',
391
+ uf: 'SC'
392
+ },
219
393
  valor_documento: 200.78,
220
394
  data_vencimento: Date.tomorrow,
221
- conta_corrente: '5679',
222
- cedente: 'Cedente 2',
223
- documento_cedente:'12345678901',
224
- sacado: 'Sacado',
225
- documento_sacado: '725.275.005-10',
226
- endereco_sacado: 'Rua teste, 23045',
395
+ numero_documento: 10002,
227
396
  instrucoes1: 'Lembrar de algo 1',
228
397
  instrucoes2: 'Lembrar de algo 2',
229
398
  instrucoes3: 'Lembrar de algo 3',
@@ -237,44 +406,30 @@ pagamento_1 = BrBoleto::Remessa::Pagamento.new({
237
406
  nosso_numero: boleto_1.nosso_numero,
238
407
  data_vencimento: boleto_1.data_vencimento,
239
408
  valor_documento: boleto_1.valor_documento,
240
- documento_sacado: boleto_1.documento_sacado,
241
- nome_sacado: boleto_1.sacado,
242
- endereco_sacado: "R. TESTE DO SACADO",
243
- cep_sacado: "89888000",
244
- cidade_sacado: "PIRÁPORA",
245
- uf_sacado: "SC",
246
- bairro_sacado: "Bairro"
409
+ pagador: boleto_1.pagador
247
410
  })
248
411
 
249
412
  pagamento_2 = BrBoleto::Remessa::Pagamento.new({
250
413
  nosso_numero: boleto_2.nosso_numero,
251
414
  data_vencimento: boleto_2.data_vencimento,
252
415
  valor_documento: boleto_2.valor_documento,
253
- documento_sacado: boleto_2.documento_sacado,
254
- nome_sacado: boleto_2.sacado,
255
- endereco_sacado: "R. TESTE DO SACADO",
256
- cep_sacado: "89888000",
257
- cidade_sacado: "PIRÁPORA",
258
- uf_sacado: "SC",
259
- bairro_sacado: "Bairro"
416
+ pagador: boleto_2.pagador
260
417
  })
261
418
 
262
419
 
263
420
  lote = BrBoleto::Remessa::Lote.new(pagamentos: [pagamento_1, pagamento_2])
264
421
 
265
422
  remessa = BrBoleto::Remessa::Cnab240::Sicoob.new({
266
- lotes: lote,
267
- nome_empresa: "Sacado",
268
- agencia: "3069",
269
- conta_corrente: "5679", # Sem DV
270
- digito_conta: "5",
271
- carteira: "1",
272
- sequencial_remessa: 1,
273
- documento_cedente: '12345678901',
274
- convenio: '1',
275
- emissao_boleto: '2',
276
- distribuicao_boleto: '2',
277
- especie_titulo: '02'
423
+ conta: {
424
+ agencia: 3069,
425
+ codigo_cedente: 6532,
426
+ carteira: 1,
427
+ conta_corrente: '5679',
428
+ razao_social: 'Cedente 1',
429
+ cpf_cnpj: '12345678901',
430
+ },
431
+ lotes: lote,
432
+ sequencial_remessa: 1
278
433
  })
279
434
 
280
435
 
@@ -325,20 +480,45 @@ lotes << BrBoleto::Remessa::Lote.new(pagamentos: pagamento_2)
325
480
 
326
481
  remessa = BrBoleto::Remessa::Cnab240::Sicoob.new({
327
482
  lotes: lotes,
328
- nome_empresa: "Sacado",
329
- agencia: "3069",
330
- conta_corrente: "5679", # Sem DV
331
- digito_conta: "5",
332
- carteira: "1",
333
- sequencial_remessa: 1,
334
- documento_cedente: '12345678901',
335
- convenio: '1',
336
- emissao_boleto: '2',
337
- distribuicao_boleto: '2',
338
- especie_titulo: '02'
483
+ conta: {
484
+ agencia: 3069,
485
+ codigo_cedente: 6532,
486
+ carteira: 1,
487
+ conta_corrente: '5679',
488
+ razao_social: 'Cedente 1',
489
+ cpf_cnpj: '12345678901',
490
+ },
491
+ sequencial_remessa: 2
339
492
  })
340
493
  ```
494
+ ##**CNAB 400**
495
+ O CNAB400 é composto por 1 ou vários pagamentos. A diferença de utilização entre o CNAB 240 e o 400 é que no 400 não existe lotes, apenas pagamentos. Exemplo:
496
+
497
+ ```ruby
498
+
499
+ remessa = BrBoleto::Remessa::Cnab400::Sicoob.new do |rem|
500
+ rem.conta = {
501
+ agencia: 3069,
502
+ codigo_cedente: 6532,
503
+ carteira: 1,
504
+ conta_corrente: '5679',
505
+ razao_social: 'Cedente 1',
506
+ cpf_cnpj: '12345678901',
507
+ }
508
+ pagamentos = [pagamento1, pagamento2]
509
+ sequencial_remessa = 5
510
+ end
511
+ ```
512
+
513
+ ## Alternativas
514
+
515
+ Essa biblioteca é baseada em outras **ótimas** bibliotecas.
516
+ **Recomendo analisar muito bem cada solução**:
517
+
518
+ * Brcobranca [https://github.com/kivanio/brcobranca](https://github.com/kivanio/brcobranca)
519
+ * Gem de Boleto Bancário [https://github.com/tomas-stefano/boleto_bancario](https://github.com/tomas-stefano/boleto_bancario)
341
520
 
521
+
342
522
  ## Contribuições
343
523
 
344
524
  Seja um contribuidor. Você pode contribuir de N formas. Seguem elas:
@@ -352,5 +532,5 @@ Seja um contribuidor. Você pode contribuir de N formas. Seguem elas:
352
532
 
353
533
  ## Licença
354
534
 
355
- - BSD
356
- - Copyleft 2015 Bruno M. Mergen
535
+ - MIT
536
+ - Copyleft 2016 Bruno M. Mergen
data/br_boleto.gemspec CHANGED
@@ -12,9 +12,11 @@ Gem::Specification.new do |gem|
12
12
 
13
13
  gem.homepage = "https://github.com/Brunomm/br_boleto"
14
14
 
15
- gem.files = `git ls-files`.split($\).reject { |f| ['.pdf','.xls'].include?(File.extname(f)) }
16
- gem.test_files = `git ls-files -- test/**/*`.split("\n")
17
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.files = `git ls-files`.split("\n").reject{|fil|
16
+ fil.include?('documentacoes_boletos/')
17
+ }
18
+ gem.test_files = `git ls-files -- test`.split("\n")
19
+ # gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
20
  gem.require_paths = ["lib"]
19
21
 
20
22
  gem.required_ruby_version = '~> 2.1'
@@ -9,7 +9,7 @@ module BrBoleto
9
9
  include ActiveModel::Model
10
10
 
11
11
  def initialize(attributes = {})
12
- attributes = default_values.merge!(attributes)
12
+ attributes = default_values.deep_merge!(attributes)
13
13
  assign_attributes(attributes)
14
14
  yield self if block_given?
15
15
  end
@@ -0,0 +1,109 @@
1
+ module BrBoleto
2
+ module HaveConta
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ validate :conta_validations
7
+ end
8
+
9
+ def conta
10
+ yield conta if block_given?
11
+ get_conta
12
+ end
13
+
14
+ def conta=(value)
15
+ if value.is_a?(conta_class) || value.nil?
16
+ @conta = value
17
+ elsif value.is_a?(Hash)
18
+ conta.assign_attributes(value)
19
+ end
20
+ end
21
+
22
+ def conta_class
23
+ raise NotImplementedError.new("Not implemented #conta_class in #{self}.")
24
+ end
25
+
26
+ private
27
+
28
+ def get_conta
29
+ @conta.is_a?(conta_class) ? @conta : @conta = conta_class.new()
30
+ set_regras_tamanho_e_validations!
31
+ @conta
32
+ end
33
+
34
+ ####################### VALIDAÇÔES DA CONTA #######################
35
+ # Devem ser sobrescrita a cada classe que utilizar, pois pode variar
36
+ def valid_conta_corrente_length; end
37
+ def valid_conta_corrente_minimum; end
38
+ def valid_conta_corrente_maximum; end
39
+ def valid_conta_corrente_required; end
40
+ def valid_modalidade_length; end
41
+ def valid_modalidade_minimum; end
42
+ def valid_modalidade_maximum; end
43
+ def valid_modalidade_required; end
44
+ def valid_codigo_cedente_length; end
45
+ def valid_codigo_cedente_minimum; end
46
+ def valid_codigo_cedente_maximum; end
47
+ def valid_codigo_cedente_required; end
48
+ def valid_codigo_cedente_inclusion; end
49
+ def valid_endereco_required; end
50
+ def valid_carteira_length; end
51
+ def valid_carteira_minimum; end
52
+ def valid_carteira_maximum; end
53
+ def valid_carteira_required; end
54
+ def valid_convenio_length; end
55
+ def valid_convenio_minimum; end
56
+ def valid_convenio_maximum; end
57
+ def valid_convenio_required; end
58
+ def valid_modalidade_inclusion; end
59
+ def valid_carteira_inclusion; end
60
+ def valid_convenio_inclusion; end
61
+ def valid_versao_aplicativo_required; end # Banco da Caixa
62
+
63
+ def set_regras_tamanho_e_validations!
64
+ @conta ||= conta_class.new()
65
+ @conta.valid_conta_corrente_length = valid_conta_corrente_length if "#{valid_conta_corrente_length}".present?
66
+ @conta.valid_conta_corrente_minimum = valid_conta_corrente_minimum if "#{valid_conta_corrente_minimum}".present?
67
+ @conta.valid_conta_corrente_maximum = valid_conta_corrente_maximum if "#{valid_conta_corrente_maximum}".present?
68
+ @conta.valid_conta_corrente_required = valid_conta_corrente_required if "#{valid_conta_corrente_required}".present?
69
+
70
+ @conta.valid_modalidade_length = valid_modalidade_length if "#{valid_modalidade_length}".present?
71
+ @conta.valid_modalidade_minimum = valid_modalidade_minimum if "#{valid_modalidade_minimum}".present?
72
+ @conta.valid_modalidade_maximum = valid_modalidade_maximum if "#{valid_modalidade_maximum}".present?
73
+ @conta.valid_modalidade_required = valid_modalidade_required if "#{valid_modalidade_required}".present?
74
+ @conta.valid_modalidade_inclusion = valid_modalidade_inclusion if "#{valid_modalidade_inclusion}".present?
75
+
76
+ @conta.valid_endereco_required = valid_endereco_required if "#{valid_endereco_required}".present?
77
+
78
+ @conta.valid_carteira_length = valid_carteira_length if "#{valid_carteira_length}".present?
79
+ @conta.valid_carteira_minimum = valid_carteira_minimum if "#{valid_carteira_minimum}".present?
80
+ @conta.valid_carteira_maximum = valid_carteira_maximum if "#{valid_carteira_maximum}".present?
81
+ @conta.valid_carteira_required = valid_carteira_required if "#{valid_carteira_required}".present?
82
+ @conta.valid_carteira_inclusion = valid_carteira_inclusion if "#{valid_carteira_inclusion}".present?
83
+
84
+ # Se tiver alguma validação setada em convênio é o que deve prevalecer
85
+ @conta.valid_codigo_cedente_length = valid_codigo_cedente_length if "#{valid_codigo_cedente_length}".present?
86
+ @conta.valid_codigo_cedente_minimum = valid_codigo_cedente_minimum if "#{valid_codigo_cedente_minimum}".present?
87
+ @conta.valid_codigo_cedente_maximum = valid_codigo_cedente_maximum if "#{valid_codigo_cedente_maximum}".present?
88
+ @conta.valid_codigo_cedente_required = valid_codigo_cedente_required if "#{valid_codigo_cedente_required}".present?
89
+ @conta.valid_codigo_cedente_inclusion = valid_codigo_cedente_inclusion if "#{valid_codigo_cedente_inclusion}".present?
90
+
91
+ @conta.valid_convenio_length = valid_convenio_length if "#{valid_convenio_length}".present?
92
+ @conta.valid_convenio_minimum = valid_convenio_minimum if "#{valid_convenio_minimum}".present?
93
+ @conta.valid_convenio_maximum = valid_convenio_maximum if "#{valid_convenio_maximum}".present?
94
+ @conta.valid_convenio_required = valid_convenio_required if "#{valid_convenio_required}".present?
95
+ @conta.valid_convenio_inclusion = valid_convenio_inclusion if "#{valid_convenio_inclusion}".present?
96
+
97
+ @conta.valid_versao_aplicativo_required = valid_versao_aplicativo_required if "#{valid_versao_aplicativo_required}".present?
98
+ end
99
+
100
+ def conta_validations
101
+ set_regras_tamanho_e_validations!
102
+ if conta.invalid?
103
+ conta.errors.full_messages.each do |msg|
104
+ errors.add(:base, msg)
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end