brcobranca 12.0.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/brcobranca/boleto/itau.rb +21 -8
- data/lib/brcobranca/remessa/cnab240/itau.rb +326 -0
- data/lib/brcobranca/remessa/cnab240/sicredi.rb +36 -3
- data/lib/brcobranca/remessa/cnab240/unicred.rb +322 -1
- data/lib/brcobranca/retorno/cnab240/base.rb +7 -5
- data/lib/brcobranca/retorno/cnab240/itau.rb +126 -0
- data/lib/brcobranca/util/itau.rb +39 -0
- data/lib/brcobranca/version.rb +1 -1
- data/lib/brcobranca.rb +3 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6cb709eea03591dba80bcbd44a13db892cccf3631872d1ff612395b75efa7895
|
|
4
|
+
data.tar.gz: e71144ac7164a789303d3aa3fef7065c8ddbc46286c98b3f22a13aecd8c7a126
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a7f6d6750e2a4ca483d72e1dc649b68e0da0c6252a806d82e4fe5a476ab4d96beee8cf2709c714f5f1d03b00f4e69bf995130592bdfc36e63ceecd6ad29f716
|
|
7
|
+
data.tar.gz: 2420142f69f9306c859c03c8c39f9f78072a6fe6fed30846b0cb25a4ad7bd9e85b7a2a13fd2139e3b4bafa3788b99ec5cd015879779dd411976a789e36bc3bfe
|
data/README.md
CHANGED
|
@@ -53,7 +53,7 @@ Criado pelo pessoal da [Akretion](http://www.akretion.com) muito TOP \o/
|
|
|
53
53
|
| Caixa | 240 | 240 |
|
|
54
54
|
| Citibank | Não | 400 |
|
|
55
55
|
| HSBC | Não | Não |
|
|
56
|
-
| Itaú | 400
|
|
56
|
+
| Itaú | 400 e 240 | 400, 444 e 240 |
|
|
57
57
|
| Santander | 400 e 240 | 400 e 240 |
|
|
58
58
|
| Sicoob | 240 | 400 e 240 |
|
|
59
59
|
| Sicredi | 240 | 240 |
|
|
@@ -28,6 +28,18 @@ module Brcobranca
|
|
|
28
28
|
'341'
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# Agencia mantenedora da conta.
|
|
32
|
+
# @return [String] 4 caracteres numericos.
|
|
33
|
+
def agencia=(valor)
|
|
34
|
+
@agencia = valor.to_s.rjust(4, "0") if valor
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Numero da carteira no banco.
|
|
38
|
+
# @return [String] 3 caracteres numericos.
|
|
39
|
+
def carteira=(valor)
|
|
40
|
+
@carteira = valor.to_s.rjust(3, "0") if valor
|
|
41
|
+
end
|
|
42
|
+
|
|
31
43
|
# Número do convênio/contrato do cliente junto ao banco.
|
|
32
44
|
# @return [String] 5 caracteres numéricos.
|
|
33
45
|
def convenio=(valor)
|
|
@@ -65,17 +77,18 @@ module Brcobranca
|
|
|
65
77
|
#
|
|
66
78
|
# @return [String] 1 caracteres numéricos.
|
|
67
79
|
def nosso_numero_dv
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"#{agencia}#{conta_corrente}#{carteira}#{nosso_numero}".modulo10
|
|
72
|
-
end
|
|
80
|
+
Brcobranca::Util::Itau.nosso_numero_dv(
|
|
81
|
+
agencia, conta_corrente, carteira, nosso_numero
|
|
82
|
+
)
|
|
73
83
|
end
|
|
74
84
|
|
|
75
|
-
# Calcula o
|
|
76
|
-
# Retorna apenas o
|
|
85
|
+
# Calcula o digito verificador para conta corrente do Itau.
|
|
86
|
+
# Retorna apenas o digito verificador da conta, ou nil se nao for
|
|
87
|
+
# possivel calcular.
|
|
77
88
|
def agencia_conta_corrente_dv
|
|
78
|
-
|
|
89
|
+
Brcobranca::Util::Itau.agencia_conta_corrente_dv(
|
|
90
|
+
agencia, conta_corrente
|
|
91
|
+
)
|
|
79
92
|
end
|
|
80
93
|
|
|
81
94
|
# Nosso número para exibir no boleto.
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Brcobranca
|
|
4
|
+
module Remessa
|
|
5
|
+
module Cnab240
|
|
6
|
+
class Itau < Brcobranca::Remessa::Cnab240::Base
|
|
7
|
+
validates_length_of :agencia, maximum: 4,
|
|
8
|
+
message: "deve ter 4 dígitos."
|
|
9
|
+
validates_length_of :conta_corrente, maximum: 5,
|
|
10
|
+
message: "deve ter 5 dígitos."
|
|
11
|
+
validates_length_of :carteira, maximum: 3,
|
|
12
|
+
message: "deve ter 3 dígitos."
|
|
13
|
+
|
|
14
|
+
def initialize(campos = {})
|
|
15
|
+
# emissao_boleto/distribuicao_boleto/codigo_carteira/
|
|
16
|
+
# forma_cadastramento nao fazem parte do layout do Segmento P do
|
|
17
|
+
# Itau (ver #monta_segmento_p), mas precisam de um valor de 1
|
|
18
|
+
# digito para passar nas validacoes genericas de Cnab240::Base.
|
|
19
|
+
campos = { especie_titulo: "01",
|
|
20
|
+
emissao_boleto: "0",
|
|
21
|
+
distribuicao_boleto: "0" }.merge!(campos)
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def agencia=(valor)
|
|
26
|
+
@agencia = valor.to_s.rjust(4, "0") if valor
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def conta_corrente=(valor)
|
|
30
|
+
@conta_corrente = valor.to_s.rjust(5, "0") if valor
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def carteira=(valor)
|
|
34
|
+
@carteira = valor.to_s.rjust(3, "0") if valor
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def cod_banco
|
|
38
|
+
"341"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def nome_banco
|
|
42
|
+
"BANCO ITAU SA".ljust(30, " ")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def versao_layout_arquivo
|
|
46
|
+
"040"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def versao_layout_lote
|
|
50
|
+
"030"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def exclusivo_servico
|
|
54
|
+
"00"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Digito verificador de agencia/conta corrente.
|
|
58
|
+
#
|
|
59
|
+
# @return [String]
|
|
60
|
+
def agencia_conta_corrente_dv
|
|
61
|
+
Brcobranca::Util::Itau.agencia_conta_corrente_dv(
|
|
62
|
+
agencia, conta_corrente
|
|
63
|
+
).to_s
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Digito verificador do nosso numero.
|
|
67
|
+
#
|
|
68
|
+
# Calculado sobre o nosso numero ja com 8 posicoes (mesmo valor
|
|
69
|
+
# gravado no segmento P), e nao sobre o valor "cru" informado pelo
|
|
70
|
+
# usuario - ver #monta_segmento_p e #formata_nosso_numero.
|
|
71
|
+
#
|
|
72
|
+
# @return [String]
|
|
73
|
+
def nosso_numero_dv(pagamento)
|
|
74
|
+
Brcobranca::Util::Itau.nosso_numero_dv(
|
|
75
|
+
agencia, conta_corrente, carteira, formata_nosso_numero(pagamento)
|
|
76
|
+
).to_s
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Nosso numero com exatamente 8 posicoes.
|
|
80
|
+
#
|
|
81
|
+
# O nosso numero pode vir do chamador (ex.: sequencia interna do
|
|
82
|
+
# Odoo) com mais de 8 digitos; nesse caso ficam os 8 ultimos
|
|
83
|
+
# digitos (o mesmo criterio usado para interpretar o nosso numero
|
|
84
|
+
# no arquivo de retorno), em vez de simplesmente preencher com
|
|
85
|
+
# zeros a esquerda sem cortar o excedente.
|
|
86
|
+
#
|
|
87
|
+
# @return [String]
|
|
88
|
+
def formata_nosso_numero(pagamento)
|
|
89
|
+
pagamento.nosso_numero.to_s.rjust(8, "0")[-8..-1]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Informacoes da conta corrente do cedente no header de lote.
|
|
93
|
+
#
|
|
94
|
+
# CAMPO TAMANHO
|
|
95
|
+
# zeros 1
|
|
96
|
+
# agencia 4
|
|
97
|
+
# brancos 1
|
|
98
|
+
# zeros 7
|
|
99
|
+
# conta corrente 5
|
|
100
|
+
# brancos 1
|
|
101
|
+
# DAC ag/conta 1
|
|
102
|
+
#
|
|
103
|
+
# @return [String]
|
|
104
|
+
def info_conta
|
|
105
|
+
zeros = "".rjust(7, "0")
|
|
106
|
+
"0#{agencia} #{zeros}#{conta_corrente} #{agencia_conta_corrente_dv}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Sem uso de codigo de convenio pelo Itau neste layout (header arquivo)
|
|
110
|
+
#
|
|
111
|
+
# @return [String]
|
|
112
|
+
def codigo_convenio
|
|
113
|
+
"".rjust(20, " ")
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Sem uso de codigo de convenio pelo Itau neste layout (header lote)
|
|
117
|
+
#
|
|
118
|
+
# @return [String]
|
|
119
|
+
def convenio_lote
|
|
120
|
+
"".rjust(20, " ")
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def uso_exclusivo_banco
|
|
124
|
+
"".rjust(20, " ")
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def uso_exclusivo_empresa
|
|
128
|
+
"".rjust(20, " ")
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Complemento do header de arquivo
|
|
132
|
+
#
|
|
133
|
+
# @return [String]
|
|
134
|
+
def complemento_header
|
|
135
|
+
"#{''.rjust(14, ' ')}#{''.rjust(3, '0')}#{''.rjust(12, ' ')}"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Complemento do trailer de lote
|
|
139
|
+
#
|
|
140
|
+
# @return [String]
|
|
141
|
+
def complemento_trailer
|
|
142
|
+
"".rjust(217, " ")
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def dv_agencia_cobradora
|
|
146
|
+
"0"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Prazo para baixa com exatamente 2 posicoes.
|
|
150
|
+
#
|
|
151
|
+
# O valor padrao herdado de Brcobranca::Remessa::Pagamento e "000"
|
|
152
|
+
# (3 digitos, dimensionado para o layout generico de outros bancos)
|
|
153
|
+
# e nao e truncado por um rjust simples, o que descasa o segmento P
|
|
154
|
+
# do Itau (campo de 2 digitos, posicoes 225-226) em 1 byte quando o
|
|
155
|
+
# chamador nao informa esse campo explicitamente.
|
|
156
|
+
#
|
|
157
|
+
# @return [String]
|
|
158
|
+
def dias_baixa(pagamento)
|
|
159
|
+
pagamento.dias_baixa.to_s.rjust(2, "0")[-2..-1]
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Monta o registro segmento P do arquivo.
|
|
163
|
+
#
|
|
164
|
+
# Layout especifico do Itau (manual "Cobranca FEBRABAN 240", item
|
|
165
|
+
# 3.1, Segmento P) - o campo "N. da carteira" (3 digitos, posicoes
|
|
166
|
+
# 038-040) nao corresponde ao hook generico `codigo_carteira` da
|
|
167
|
+
# classe base (1 digito), por isso o segmento e montado por inteiro.
|
|
168
|
+
#
|
|
169
|
+
# CAMPO POSICAO TAMANHO
|
|
170
|
+
# codigo banco 001-003 3
|
|
171
|
+
# lote de servico 004-007 4
|
|
172
|
+
# tipo de registro 008 1
|
|
173
|
+
# num. sequencial do registro no lote 009-013 5
|
|
174
|
+
# cod. segmento 014 1
|
|
175
|
+
# uso exclusivo 015 1
|
|
176
|
+
# cod. movimento remessa 016-017 2
|
|
177
|
+
# zeros 018 1
|
|
178
|
+
# agencia 019-022 4
|
|
179
|
+
# brancos 023 1
|
|
180
|
+
# zeros 024-030 7
|
|
181
|
+
# conta corrente 031-035 5
|
|
182
|
+
# brancos 036 1
|
|
183
|
+
# DAC agencia/conta 037 1
|
|
184
|
+
# numero da carteira 038-040 3
|
|
185
|
+
# nosso numero 041-048 8
|
|
186
|
+
# DAC nosso numero 049 1
|
|
187
|
+
# brancos 050-057 8
|
|
188
|
+
# zeros 058-062 5
|
|
189
|
+
# numero do documento 063-072 10
|
|
190
|
+
# brancos 073-077 5
|
|
191
|
+
# data de vencimento 078-085 8
|
|
192
|
+
# valor do titulo 086-100 15
|
|
193
|
+
# agencia cobradora 101-105 5
|
|
194
|
+
# DAC agencia cobradora 106 1
|
|
195
|
+
# especie do titulo 107-108 2
|
|
196
|
+
# aceite 109 1
|
|
197
|
+
# data de emissao do titulo 110-117 8
|
|
198
|
+
# zeros 118 1
|
|
199
|
+
# data base juros de mora 119-126 8
|
|
200
|
+
# valor de mora por dia de atraso 127-141 15
|
|
201
|
+
# zeros 142 1
|
|
202
|
+
# data limite do 1o desconto 143-150 8
|
|
203
|
+
# valor do 1o desconto 151-165 15
|
|
204
|
+
# valor do IOF 166-180 15
|
|
205
|
+
# valor do abatimento 181-195 15
|
|
206
|
+
# identificacao do titulo na empresa 196-220 25
|
|
207
|
+
# codigo para negativacao/protesto 221 1
|
|
208
|
+
# prazo para negativacao/protesto 222-223 2
|
|
209
|
+
# codigo para baixa 224 1
|
|
210
|
+
# prazo para baixa 225-226 2
|
|
211
|
+
# zeros 227-239 13
|
|
212
|
+
# brancos 240 1
|
|
213
|
+
#
|
|
214
|
+
# @return [String]
|
|
215
|
+
def monta_segmento_p(pagamento, nro_lote, sequencial)
|
|
216
|
+
segmento_p = ""
|
|
217
|
+
segmento_p += cod_banco
|
|
218
|
+
segmento_p << nro_lote.to_s.rjust(4, "0")
|
|
219
|
+
segmento_p << "3"
|
|
220
|
+
segmento_p << sequencial.to_s.rjust(5, "0")
|
|
221
|
+
segmento_p << "P"
|
|
222
|
+
segmento_p << " "
|
|
223
|
+
segmento_p << pagamento.identificacao_ocorrencia
|
|
224
|
+
segmento_p << "0"
|
|
225
|
+
segmento_p << agencia
|
|
226
|
+
segmento_p << " "
|
|
227
|
+
segmento_p << "".rjust(7, "0")
|
|
228
|
+
segmento_p << conta_corrente
|
|
229
|
+
segmento_p << " "
|
|
230
|
+
segmento_p << agencia_conta_corrente_dv
|
|
231
|
+
segmento_p << carteira
|
|
232
|
+
segmento_p << formata_nosso_numero(pagamento)
|
|
233
|
+
segmento_p << nosso_numero_dv(pagamento)
|
|
234
|
+
segmento_p << "".rjust(8, " ")
|
|
235
|
+
segmento_p << "".rjust(5, "0")
|
|
236
|
+
segmento_p << pagamento.formata_documento_ou_numero(10, " ")
|
|
237
|
+
segmento_p << "".rjust(5, " ")
|
|
238
|
+
segmento_p << pagamento.data_vencimento.strftime("%d%m%Y")
|
|
239
|
+
segmento_p << pagamento.formata_valor(15)
|
|
240
|
+
segmento_p << "".rjust(5, "0")
|
|
241
|
+
segmento_p << dv_agencia_cobradora
|
|
242
|
+
segmento_p << especie_titulo
|
|
243
|
+
segmento_p << aceite
|
|
244
|
+
segmento_p << pagamento.data_emissao.strftime("%d%m%Y")
|
|
245
|
+
segmento_p << "0"
|
|
246
|
+
segmento_p << data_mora(pagamento)
|
|
247
|
+
segmento_p << pagamento.formata_valor_mora(15)
|
|
248
|
+
segmento_p << "0"
|
|
249
|
+
segmento_p << pagamento.formata_data_desconto("%d%m%Y")
|
|
250
|
+
segmento_p << pagamento.formata_valor_desconto(15)
|
|
251
|
+
segmento_p << pagamento.formata_valor_iof(15)
|
|
252
|
+
segmento_p << pagamento.formata_valor_abatimento(15)
|
|
253
|
+
segmento_p << pagamento.formata_documento_ou_numero(25, " ")
|
|
254
|
+
segmento_p << pagamento.codigo_protesto
|
|
255
|
+
segmento_p << pagamento.dias_protesto.to_s.rjust(2, "0")
|
|
256
|
+
segmento_p << codigo_baixa(pagamento)
|
|
257
|
+
segmento_p << dias_baixa(pagamento)
|
|
258
|
+
segmento_p << "".rjust(13, "0")
|
|
259
|
+
segmento_p << " "
|
|
260
|
+
segmento_p
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# Monta o registro segmento Q do arquivo.
|
|
264
|
+
#
|
|
265
|
+
# Layout especifico do Itau - o nome do pagador ocupa 30 posicoes
|
|
266
|
+
# (com 10 posicoes em branco a seguir) e o nome do sacador/avalista
|
|
267
|
+
# ocupa 30 posicoes, diferente do padrao generico de 40 posicoes sem
|
|
268
|
+
# espacamento usado pela classe base.
|
|
269
|
+
#
|
|
270
|
+
# CAMPO POSICAO TAMANHO
|
|
271
|
+
# codigo banco 001-003 3
|
|
272
|
+
# lote de servico 004-007 4
|
|
273
|
+
# tipo de registro 008 1
|
|
274
|
+
# num. sequencial do registro no lote 009-013 5
|
|
275
|
+
# cod. segmento 014 1
|
|
276
|
+
# brancos 015 1
|
|
277
|
+
# cod. movimento remessa 016-017 2
|
|
278
|
+
# tipo insc. pagador 018 1
|
|
279
|
+
# documento pagador 019-033 15
|
|
280
|
+
# nome pagador 034-063 30
|
|
281
|
+
# brancos 064-073 10
|
|
282
|
+
# logradouro 074-113 40
|
|
283
|
+
# bairro 114-128 15
|
|
284
|
+
# cep 129-133 5
|
|
285
|
+
# sufixo cep 134-136 3
|
|
286
|
+
# cidade 137-151 15
|
|
287
|
+
# uf 152-153 2
|
|
288
|
+
# tipo insc. sacador/avalista 154 1
|
|
289
|
+
# documento sacador/avalista 155-169 15
|
|
290
|
+
# nome sacador/avalista 170-199 30
|
|
291
|
+
# brancos 200-209 10
|
|
292
|
+
# zeros 210-212 3
|
|
293
|
+
# brancos 213-240 28
|
|
294
|
+
#
|
|
295
|
+
# @return [String]
|
|
296
|
+
def monta_segmento_q(pagamento, nro_lote, sequencial)
|
|
297
|
+
segmento_q = ""
|
|
298
|
+
segmento_q += cod_banco
|
|
299
|
+
segmento_q << nro_lote.to_s.rjust(4, "0")
|
|
300
|
+
segmento_q << "3"
|
|
301
|
+
segmento_q << sequencial.to_s.rjust(5, "0")
|
|
302
|
+
segmento_q << "Q"
|
|
303
|
+
segmento_q << " "
|
|
304
|
+
segmento_q << pagamento.identificacao_ocorrencia
|
|
305
|
+
segmento_q << pagamento.identificacao_sacado(false)
|
|
306
|
+
segmento_q << pagamento.documento_sacado.to_s.rjust(15, "0")
|
|
307
|
+
segmento_q << pagamento.nome_sacado.format_size(30)
|
|
308
|
+
segmento_q << "".rjust(10, " ")
|
|
309
|
+
segmento_q << pagamento.endereco_sacado.format_size(40)
|
|
310
|
+
segmento_q << pagamento.bairro_sacado.format_size(15)
|
|
311
|
+
segmento_q << pagamento.cep_sacado[0..4]
|
|
312
|
+
segmento_q << pagamento.cep_sacado[5..7]
|
|
313
|
+
segmento_q << pagamento.cidade_sacado.format_size(15)
|
|
314
|
+
segmento_q << pagamento.uf_sacado
|
|
315
|
+
segmento_q << pagamento.identificacao_avalista(false)
|
|
316
|
+
segmento_q << pagamento.documento_avalista.to_s.rjust(15, "0")
|
|
317
|
+
segmento_q << pagamento.nome_avalista.format_size(30)
|
|
318
|
+
segmento_q << "".rjust(10, " ")
|
|
319
|
+
segmento_q << "".rjust(3, "0")
|
|
320
|
+
segmento_q << "".rjust(28, " ")
|
|
321
|
+
segmento_q
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
end
|
|
@@ -151,16 +151,49 @@ module Brcobranca
|
|
|
151
151
|
nosso_numero.somente_numeros.ljust(20, ' ')
|
|
152
152
|
end
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
# Campo 30.3P - Codigo do desconto 1.
|
|
155
|
+
# Manual Sicredi: '0' - Sem desconto | '1' - Valor fixo ate a data
|
|
156
|
+
# informada | '2' - Percentual ate a data informada.
|
|
157
|
+
# Para o codigo '0' o valor e a data do desconto devem ser zerados.
|
|
158
|
+
# Deve respeitar o valor informado pelo beneficiario.
|
|
159
|
+
def codigo_desconto(pagamento)
|
|
160
|
+
if pagamento.cod_desconto == '0'
|
|
161
|
+
pagamento.data_desconto = nil
|
|
162
|
+
pagamento.valor_desconto = 0.0
|
|
163
|
+
end
|
|
164
|
+
pagamento.cod_desconto
|
|
156
165
|
end
|
|
157
166
|
|
|
158
167
|
def codigo_baixa(_pagamento)
|
|
159
168
|
'1'
|
|
160
169
|
end
|
|
161
170
|
|
|
171
|
+
# Campo 39.3P - No de dias para baixa/devolucao.
|
|
172
|
+
# Manual Sicredi: o Sicredi nao utiliza esse campo, preencher com zeros.
|
|
162
173
|
def dias_baixa(_pagamento)
|
|
163
|
-
'
|
|
174
|
+
'000'
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Campo 19.3P - Seu Numero (posicoes 63-77).
|
|
178
|
+
# Manual Sicredi: "Embora no layout constem 15 posicoes, o Sicredi
|
|
179
|
+
# apenas validara as 10 primeiras (campos 63-72), ou seja, da esquerda
|
|
180
|
+
# para a direita. Nao pode conter espaco."
|
|
181
|
+
# O numero deve entao ser alinhado a esquerda e o restante preenchido
|
|
182
|
+
# com zeros (o campo nao pode conter espaco).
|
|
183
|
+
def numero(pagamento)
|
|
184
|
+
pagamento.documento_ou_numero.to_s.gsub(/[^0-9A-Za-z]/, '').ljust(15, '0')[0...15]
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Campos 17.3Q, 18.3Q e 19.3Q - Beneficiario Final.
|
|
188
|
+
# Manual Sicredi: nao havendo Beneficiario Final o tipo deve ser "0"
|
|
189
|
+
# e o campo CPF/CNPJ (posicoes 155-169) deve ficar em branco.
|
|
190
|
+
# O BRCobranca preenche o CPF/CNPJ com zeros quando nao informado.
|
|
191
|
+
def monta_segmento_q(pagamento, nro_lote, sequencial)
|
|
192
|
+
segmento_q = super
|
|
193
|
+
return segmento_q unless pagamento.documento_avalista.to_s.strip.empty?
|
|
194
|
+
|
|
195
|
+
segmento_q[153, 16] = "0#{''.rjust(15, ' ')}"
|
|
196
|
+
segmento_q
|
|
164
197
|
end
|
|
165
198
|
|
|
166
199
|
def data_mora(pagamento)
|
|
@@ -3,7 +3,328 @@
|
|
|
3
3
|
module Brcobranca
|
|
4
4
|
module Remessa
|
|
5
5
|
module Cnab240
|
|
6
|
-
|
|
6
|
+
# Banco Unicred (136)
|
|
7
|
+
#
|
|
8
|
+
# Layout proprio do Unicred, baseado no manual "COBRANCA UNICRED -
|
|
9
|
+
# TROCA ELETRONICA CEDENTE CNAB 240 E 400" (item 6), disponivel em
|
|
10
|
+
# docs/unicred. Difere do padrao generico FEBRABAN principalmente no
|
|
11
|
+
# segmento P (posicao do nosso numero, carteira com 2 posicoes e
|
|
12
|
+
# diversos campos tratados como filler) e no segmento R, onde ficam as
|
|
13
|
+
# mensagens do titulo.
|
|
14
|
+
class Unicred < Brcobranca::Remessa::Cnab240::Base
|
|
15
|
+
# Parametro de movimento vinculado ao cedente no momento do
|
|
16
|
+
# cadastramento (campo 22 do header de arquivo - UN001).
|
|
17
|
+
attr_accessor :parametro_movimento
|
|
18
|
+
|
|
19
|
+
validates_presence_of :agencia, :conta_corrente, :digito_conta, :documento_cedente,
|
|
20
|
+
message: 'não pode estar em branco.'
|
|
21
|
+
validates_length_of :agencia, is: 4, message: 'deve ter 4 dígitos.'
|
|
22
|
+
validates_length_of :conta_corrente, maximum: 12, message: 'deve ter no máximo 12 dígitos.'
|
|
23
|
+
validates_length_of :digito_conta, is: 1, message: 'deve ter 1 dígito.'
|
|
24
|
+
validates_length_of :carteira, is: 2, message: 'deve ter 2 dígitos.'
|
|
25
|
+
validates_length_of :parametro_movimento, is: 3, message: 'deve ter 3 dígitos.'
|
|
26
|
+
validates_inclusion_of :carteira, in: %w[21], message: 'não existente para este banco.'
|
|
27
|
+
|
|
28
|
+
# Nova instancia do Unicred
|
|
29
|
+
def initialize(campos = {})
|
|
30
|
+
campos = {
|
|
31
|
+
carteira: '21',
|
|
32
|
+
parametro_movimento: '000',
|
|
33
|
+
emissao_boleto: '2',
|
|
34
|
+
distribuicao_boleto: '2',
|
|
35
|
+
especie_titulo: '02',
|
|
36
|
+
forma_cadastramento: '1',
|
|
37
|
+
tipo_documento: '1'
|
|
38
|
+
}.merge!(campos)
|
|
39
|
+
super(campos)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def agencia=(valor)
|
|
43
|
+
@agencia = valor.to_s.rjust(4, '0') if valor
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def carteira=(valor)
|
|
47
|
+
@carteira = valor.to_s.rjust(2, '0') if valor
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Codigo do banco na camara de compensacao
|
|
51
|
+
# @return [String] 3 caracteres numericos.
|
|
52
|
+
def cod_banco
|
|
53
|
+
'136'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Nome do banco
|
|
57
|
+
# @return [String] 30 caracteres.
|
|
58
|
+
def nome_banco
|
|
59
|
+
'UNICRED'.ljust(30, ' ')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Versao do layout do arquivo (campo 20 do header de arquivo)
|
|
63
|
+
def versao_layout_arquivo
|
|
64
|
+
'085'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Versao do layout do lote (campo 7 do header de lote)
|
|
68
|
+
def versao_layout_lote
|
|
69
|
+
'044'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Densidade de gravacao do arquivo: 1600 BPI
|
|
73
|
+
def densidade_gravacao
|
|
74
|
+
'01600'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Digito verificador da agencia, calculado pelo modulo 11 com o mesmo
|
|
78
|
+
# criterio usado na remessa CNAB 400 do Unicred.
|
|
79
|
+
# @return [String] 1 caractere.
|
|
80
|
+
def digito_agencia
|
|
81
|
+
agencia.modulo11(mapeamento: { 10 => 'X' }).to_s
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Nosso numero com o digito verificador (campo 13 do segmento P).
|
|
85
|
+
# @return [String] 11 caracteres numericos.
|
|
86
|
+
def formata_nosso_numero(nosso_numero)
|
|
87
|
+
numero = nosso_numero.to_s.somente_numeros.rjust(10, '0')
|
|
88
|
+
"#{numero}#{numero.modulo11(mapeamento: { 10 => 0, 11 => 0 })}"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# O Unicred nao utiliza o codigo do convenio: campo 7 do header de
|
|
92
|
+
# arquivo e campo 11 do header de lote sao filler.
|
|
93
|
+
def codigo_convenio
|
|
94
|
+
''.rjust(20, ' ')
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
alias convenio_lote codigo_convenio
|
|
98
|
+
|
|
99
|
+
# Informacoes da conta do cedente
|
|
100
|
+
# (header de arquivo 053-072 / header de lote 054-073)
|
|
101
|
+
#
|
|
102
|
+
# @return [String] 20 caracteres.
|
|
103
|
+
def info_conta
|
|
104
|
+
# CAMPO TAMANHO
|
|
105
|
+
# agencia 5
|
|
106
|
+
# dv agencia 1
|
|
107
|
+
# conta corrente 12
|
|
108
|
+
# dv conta 1
|
|
109
|
+
# filler 1
|
|
110
|
+
"#{agencia.rjust(5, '0')}#{digito_agencia}#{conta_corrente.to_s.rjust(12, '0')}#{digito_conta}0"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Campos 22 e 23 do header de arquivo (posicoes 172 a 191):
|
|
114
|
+
# parametro de movimento seguido do campo reservado ao banco.
|
|
115
|
+
def uso_exclusivo_banco
|
|
116
|
+
"#{parametro_movimento}#{''.rjust(17, ' ')}"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Campo 24 do header de arquivo (posicoes 192 a 211)
|
|
120
|
+
def uso_exclusivo_empresa
|
|
121
|
+
''.rjust(20, ' ')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Campo 25 do header de arquivo (posicoes 212 a 240)
|
|
125
|
+
def complemento_header
|
|
126
|
+
''.rjust(29, ' ')
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Complemento do trailer de lote (posicoes 24 a 240)
|
|
130
|
+
#
|
|
131
|
+
# @return [String] 217 caracteres.
|
|
132
|
+
def complemento_trailer
|
|
133
|
+
# CAMPO TAMANHO
|
|
134
|
+
# qtde de titulos em cobranca simples 6
|
|
135
|
+
# valor total dos titulos em cobranca simples 17
|
|
136
|
+
# qtde/valor dos titulos em cobranca vinculada 23
|
|
137
|
+
# qtde/valor dos titulos em cobranca caucionada 23
|
|
138
|
+
# qtde/valor dos titulos em cobranca descontada 23
|
|
139
|
+
# numero do aviso de lancamento 8
|
|
140
|
+
# uso exclusivo FEBRABAN 117
|
|
141
|
+
cobranca_simples = "#{quantidade_titulos_cobranca}#{valor_titulos_carteira(17)}"
|
|
142
|
+
"#{cobranca_simples}#{''.rjust(69, '0')}#{''.rjust(125, ' ')}"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Complemento do segmento R (posicoes 180 a 240)
|
|
146
|
+
#
|
|
147
|
+
# @return [String] 61 caracteres.
|
|
148
|
+
def complemento_r
|
|
149
|
+
# CAMPO TAMANHO
|
|
150
|
+
# uso exclusivo FEBRABAN 20
|
|
151
|
+
# filler 32
|
|
152
|
+
# uso exclusivo FEBRABAN 9
|
|
153
|
+
"#{''.rjust(20, ' ')}#{''.rjust(32, '0')}#{''.rjust(9, ' ')}"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Monta o registro header do lote
|
|
157
|
+
#
|
|
158
|
+
# No layout do Unicred as duas mensagens do header de lote (posicoes
|
|
159
|
+
# 104 a 183) e a data do credito (posicoes 200 a 207) sao filler - as
|
|
160
|
+
# mensagens do titulo trafegam no segmento R.
|
|
161
|
+
#
|
|
162
|
+
# @return [String]
|
|
163
|
+
#
|
|
164
|
+
def monta_header_lote(nro_lote)
|
|
165
|
+
header_lote = super
|
|
166
|
+
header_lote[103, 80] = ''.rjust(80, ' ')
|
|
167
|
+
header_lote[199, 8] = ''.rjust(8, ' ')
|
|
168
|
+
header_lote
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Monta o registro segmento P do arquivo
|
|
172
|
+
#
|
|
173
|
+
# CAMPO POSICAO TAMANHO
|
|
174
|
+
# codigo banco 001-003 3
|
|
175
|
+
# lote de servico 004-007 4
|
|
176
|
+
# tipo de registro 008 1
|
|
177
|
+
# num. sequencial do registro no lote 009-013 5
|
|
178
|
+
# cod. segmento 014 1
|
|
179
|
+
# uso exclusivo FEBRABAN 015 1
|
|
180
|
+
# cod. movimento remessa 016-017 2
|
|
181
|
+
# agencia 018-022 5
|
|
182
|
+
# dv agencia 023 1
|
|
183
|
+
# conta corrente 024-035 12
|
|
184
|
+
# dv conta 036 1
|
|
185
|
+
# filler 037 1
|
|
186
|
+
# nosso numero (com dv) 038-048 11
|
|
187
|
+
# filler 049-056 8
|
|
188
|
+
# carteira 057-058 2
|
|
189
|
+
# filler 059-062 4
|
|
190
|
+
# numero do documento (seu numero) 063-077 15
|
|
191
|
+
# data de vencimento 078-085 8
|
|
192
|
+
# valor nominal do titulo 086-100 15
|
|
193
|
+
# agencia cobradora 101-105 5
|
|
194
|
+
# dv agencia cobradora 106 1
|
|
195
|
+
# filler 107-108 2
|
|
196
|
+
# aceite 109 1
|
|
197
|
+
# data de emissao do titulo 110-117 8
|
|
198
|
+
# codigo do juros de mora 118 1
|
|
199
|
+
# filler 119-126 8
|
|
200
|
+
# juros de mora por dia/taxa 127-141 15
|
|
201
|
+
# codigo do desconto 1 142 1
|
|
202
|
+
# data do desconto 1 143-150 8
|
|
203
|
+
# valor/percentual do desconto 1 151-165 15
|
|
204
|
+
# filler 166-180 15
|
|
205
|
+
# valor do abatimento 181-195 15
|
|
206
|
+
# identificacao do titulo na empresa 196-220 25
|
|
207
|
+
# codigo para protesto 221 1
|
|
208
|
+
# prazo para protesto 222-223 2
|
|
209
|
+
# filler 224-227 4
|
|
210
|
+
# codigo da moeda 228-229 2
|
|
211
|
+
# numero do contrato 230-239 10
|
|
212
|
+
# uso exclusivo FEBRABAN 240 1
|
|
213
|
+
#
|
|
214
|
+
# @return [String]
|
|
215
|
+
#
|
|
216
|
+
def monta_segmento_p(pagamento, nro_lote, sequencial)
|
|
217
|
+
segmento_p = ''
|
|
218
|
+
segmento_p += cod_banco
|
|
219
|
+
segmento_p << nro_lote.to_s.rjust(4, '0')
|
|
220
|
+
segmento_p << '3'
|
|
221
|
+
segmento_p << sequencial.to_s.rjust(5, '0')
|
|
222
|
+
segmento_p << 'P'
|
|
223
|
+
segmento_p << ' '
|
|
224
|
+
segmento_p << pagamento.identificacao_ocorrencia
|
|
225
|
+
segmento_p << agencia.rjust(5, '0')
|
|
226
|
+
segmento_p << digito_agencia
|
|
227
|
+
segmento_p << conta_corrente.to_s.rjust(12, '0')
|
|
228
|
+
segmento_p << digito_conta.to_s
|
|
229
|
+
segmento_p << '0'
|
|
230
|
+
segmento_p << formata_nosso_numero(pagamento.nosso_numero)
|
|
231
|
+
segmento_p << ''.rjust(8, ' ')
|
|
232
|
+
segmento_p << carteira
|
|
233
|
+
segmento_p << '0 0 '
|
|
234
|
+
segmento_p << numero(pagamento)
|
|
235
|
+
segmento_p << pagamento.data_vencimento.strftime('%d%m%Y')
|
|
236
|
+
segmento_p << pagamento.formata_valor(15)
|
|
237
|
+
segmento_p << ''.rjust(5, ' ')
|
|
238
|
+
segmento_p << ' '
|
|
239
|
+
segmento_p << ''.rjust(2, '0')
|
|
240
|
+
segmento_p << aceite
|
|
241
|
+
segmento_p << pagamento.data_emissao.strftime('%d%m%Y')
|
|
242
|
+
segmento_p << pagamento.tipo_mora
|
|
243
|
+
segmento_p << ''.rjust(8, '0')
|
|
244
|
+
segmento_p << pagamento.formata_valor_mora(15)
|
|
245
|
+
segmento_p << codigo_desconto(pagamento)
|
|
246
|
+
segmento_p << pagamento.formata_data_desconto('%d%m%Y')
|
|
247
|
+
segmento_p << pagamento.formata_valor_desconto(15)
|
|
248
|
+
segmento_p << ''.rjust(15, '0')
|
|
249
|
+
segmento_p << pagamento.formata_valor_abatimento(15)
|
|
250
|
+
segmento_p << identificacao_titulo_empresa(pagamento)
|
|
251
|
+
segmento_p << pagamento.codigo_protesto
|
|
252
|
+
segmento_p << pagamento.dias_protesto.to_s.rjust(2, '0')
|
|
253
|
+
segmento_p << '0'
|
|
254
|
+
segmento_p << ''.rjust(3, ' ')
|
|
255
|
+
segmento_p << '09'
|
|
256
|
+
segmento_p << ''.rjust(10, '0')
|
|
257
|
+
segmento_p << ' '
|
|
258
|
+
segmento_p
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# Monta o registro segmento R do arquivo
|
|
262
|
+
#
|
|
263
|
+
# No layout do Unicred os campos de desconto 2/3 e de multa sao filler;
|
|
264
|
+
# o segmento carrega a informacao ao sacado e as duas mensagens.
|
|
265
|
+
#
|
|
266
|
+
# CAMPO POSICAO TAMANHO
|
|
267
|
+
# codigo banco 001-003 3
|
|
268
|
+
# lote de servico 004-007 4
|
|
269
|
+
# tipo de registro 008 1
|
|
270
|
+
# num. sequencial do registro no lote 009-013 5
|
|
271
|
+
# cod. segmento 014 1
|
|
272
|
+
# uso exclusivo FEBRABAN 015 1
|
|
273
|
+
# cod. movimento remessa 016-017 2
|
|
274
|
+
# filler (desconto 2 e desconto 3) 018-065 48
|
|
275
|
+
# filler 066 1
|
|
276
|
+
# filler (multa) 067-089 23
|
|
277
|
+
# informacao ao sacado 090-099 10
|
|
278
|
+
# mensagem 1 100-139 40
|
|
279
|
+
# mensagem 2 140-179 40
|
|
280
|
+
# complemento 180-240 61
|
|
281
|
+
#
|
|
282
|
+
# @return [String]
|
|
283
|
+
#
|
|
284
|
+
def monta_segmento_r(pagamento, nro_lote, sequencial)
|
|
285
|
+
segmento_r = ''
|
|
286
|
+
segmento_r += cod_banco
|
|
287
|
+
segmento_r << nro_lote.to_s.rjust(4, '0')
|
|
288
|
+
segmento_r << '3'
|
|
289
|
+
segmento_r << sequencial.to_s.rjust(5, '0')
|
|
290
|
+
segmento_r << 'R'
|
|
291
|
+
segmento_r << ' '
|
|
292
|
+
segmento_r << pagamento.identificacao_ocorrencia
|
|
293
|
+
segmento_r << ''.rjust(48, '0')
|
|
294
|
+
segmento_r << ' '
|
|
295
|
+
segmento_r << ''.rjust(23, '0')
|
|
296
|
+
segmento_r << ''.rjust(10, ' ')
|
|
297
|
+
segmento_r << mensagem_1.to_s.format_size(40)
|
|
298
|
+
segmento_r << mensagem_2.to_s.format_size(40)
|
|
299
|
+
segmento_r << complemento_r
|
|
300
|
+
segmento_r
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
# Monta o registro trailer do arquivo
|
|
304
|
+
#
|
|
305
|
+
# CAMPO POSICAO TAMANHO
|
|
306
|
+
# codigo banco 001-003 3
|
|
307
|
+
# lote de servico 004-007 4
|
|
308
|
+
# tipo de registro 008 1
|
|
309
|
+
# uso exclusivo FEBRABAN 009-017 9
|
|
310
|
+
# qtde de lotes do arquivo 018-023 6
|
|
311
|
+
# qtde de registros do arquivo 024-029 6
|
|
312
|
+
# qtde de contas para conciliacao 030-035 6
|
|
313
|
+
# uso exclusivo FEBRABAN 036-240 205
|
|
314
|
+
#
|
|
315
|
+
# @return [String]
|
|
316
|
+
#
|
|
317
|
+
def monta_trailer_arquivo(nro_lotes, sequencial)
|
|
318
|
+
trailer_arquivo = ''
|
|
319
|
+
trailer_arquivo += cod_banco
|
|
320
|
+
trailer_arquivo << '99999'
|
|
321
|
+
trailer_arquivo << ''.rjust(9, ' ')
|
|
322
|
+
trailer_arquivo << nro_lotes.to_s.rjust(6, '0')
|
|
323
|
+
trailer_arquivo << sequencial.to_s.rjust(6, '0')
|
|
324
|
+
trailer_arquivo << ''.rjust(6, '0')
|
|
325
|
+
trailer_arquivo << ''.rjust(205, ' ')
|
|
326
|
+
trailer_arquivo
|
|
327
|
+
end
|
|
7
328
|
end
|
|
8
329
|
end
|
|
9
330
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "parseline"
|
|
4
4
|
|
|
5
5
|
module Brcobranca
|
|
6
6
|
module Retorno
|
|
@@ -13,13 +13,15 @@ module Brcobranca
|
|
|
13
13
|
codigo_banco = codigo_banco_do_arquivo(file)
|
|
14
14
|
|
|
15
15
|
case codigo_banco
|
|
16
|
-
when
|
|
16
|
+
when "033"
|
|
17
17
|
Brcobranca::Retorno::Cnab240::Santander.load_lines(file, options)
|
|
18
|
-
when
|
|
18
|
+
when "341"
|
|
19
|
+
Brcobranca::Retorno::Cnab240::Itau.load_lines(file, options)
|
|
20
|
+
when "085"
|
|
19
21
|
Brcobranca::Retorno::Cnab240::Ailos.load_lines(file, options)
|
|
20
|
-
when
|
|
22
|
+
when "748"
|
|
21
23
|
Brcobranca::Retorno::Cnab240::Sicredi.load_lines(file, options)
|
|
22
|
-
when
|
|
24
|
+
when "756"
|
|
23
25
|
Brcobranca::Retorno::Cnab240::Sicoob.load_lines(file, options)
|
|
24
26
|
else
|
|
25
27
|
Brcobranca::Retorno::RetornoCnab240.load_lines(file, options)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Brcobranca
|
|
4
|
+
module Retorno
|
|
5
|
+
module Cnab240
|
|
6
|
+
class Itau < Brcobranca::Retorno::Cnab240::Base
|
|
7
|
+
# Regex para remocao de headers/trailers e registros diferentes de T
|
|
8
|
+
# ou U.
|
|
9
|
+
REGEX_DE_EXCLUSAO_DE_REGISTROS_NAO_T_OU_U =
|
|
10
|
+
/^((?!^.{7}3.{5}[TU].*$).)*$/
|
|
11
|
+
|
|
12
|
+
def self.load_lines(file, options = {})
|
|
13
|
+
default_options = {
|
|
14
|
+
except: REGEX_DE_EXCLUSAO_DE_REGISTROS_NAO_T_OU_U
|
|
15
|
+
}
|
|
16
|
+
options = default_options.merge(options)
|
|
17
|
+
|
|
18
|
+
lines = Line.load_lines(file, options)
|
|
19
|
+
lines.each_slice(2).inject([]) do |retornos, cnab_lines|
|
|
20
|
+
validate_par_t_u!(cnab_lines)
|
|
21
|
+
retornos << generate_retorno_based_on_cnab_lines(cnab_lines)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Garante que cada grupo de linhas T/U produzido por .load_lines
|
|
26
|
+
# esta completo e na ordem esperada antes de virar um retorno.
|
|
27
|
+
#
|
|
28
|
+
# Um arquivo corrompido ou truncado pode gerar um grupo com so a
|
|
29
|
+
# linha T (sem a U correspondente) ou fora de ordem; sem essa
|
|
30
|
+
# checagem, generate_retorno_based_on_cnab_lines trataria
|
|
31
|
+
# silenciosamente qualquer linha que nao seja T como se fosse U,
|
|
32
|
+
# produzindo um retorno com dados de liquidacao incorretos/parciais.
|
|
33
|
+
def self.validate_par_t_u!(cnab_lines)
|
|
34
|
+
return if cnab_lines.size == 2 &&
|
|
35
|
+
cnab_lines[0].tipo_registro == "T" &&
|
|
36
|
+
cnab_lines[1].tipo_registro == "U"
|
|
37
|
+
|
|
38
|
+
sequencial = cnab_lines.first&.sequencial
|
|
39
|
+
raise ArgumentError,
|
|
40
|
+
"Par de registros T/U invalido ou incompleto no retorno " \
|
|
41
|
+
"do Itau (sequencial: #{sequencial.inspect})"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.generate_retorno_based_on_cnab_lines(cnab_lines)
|
|
45
|
+
retorno = new
|
|
46
|
+
cnab_lines.each do |line|
|
|
47
|
+
if line.tipo_registro == "T"
|
|
48
|
+
Line::REGISTRO_T_FIELDS.each do |attr|
|
|
49
|
+
retorno.send(:"#{attr}=", line.send(attr))
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
Line::REGISTRO_U_FIELDS.each do |attr|
|
|
53
|
+
retorno.send(:"#{attr}=", line.send(attr))
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
retorno
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Linha de mapeamento do retorno do arquivo CNAB 240 do Itau.
|
|
61
|
+
#
|
|
62
|
+
# O registro CNAB 240 possui 2 tipos de registros que juntos geram
|
|
63
|
+
# um registro de retorno bancario. O primeiro e do tipo T que
|
|
64
|
+
# retorna os dados gerais sobre o titulo/pagador. O segundo e do
|
|
65
|
+
# tipo U que retorna os valores da liquidacao.
|
|
66
|
+
#
|
|
67
|
+
# Os nomes de campo reutilizam, sempre que fazem sentido, o
|
|
68
|
+
# vocabulario generico ja definido em Brcobranca::Retorno::Base (em
|
|
69
|
+
# vez de nomes especificos do Itau), pois e esse vocabulario que
|
|
70
|
+
# fica exposto para quem consome a classe via
|
|
71
|
+
# Brcobranca::Retorno::Cnab240::Base (ex.: a API HTTP do
|
|
72
|
+
# boleto_cnab_api so serializa os atributos ja conhecidos dessa
|
|
73
|
+
# lista generica).
|
|
74
|
+
#
|
|
75
|
+
# Posicoes conforme manual "Cobranca FEBRABAN 240" do Itau, item
|
|
76
|
+
# 3.2 (Arquivo Retorno), Segmentos T e U.
|
|
77
|
+
class Line < Base
|
|
78
|
+
extend ParseLine::FixedWidth # Extendendo parseline
|
|
79
|
+
|
|
80
|
+
REGISTRO_T_FIELDS = %w[
|
|
81
|
+
codigo_registro codigo_ocorrencia agencia_com_dv carteira
|
|
82
|
+
nosso_numero cedente_com_dv documento_numero data_vencimento
|
|
83
|
+
valor_titulo agencia_recebedora_com_dv valor_tarifa
|
|
84
|
+
motivo_ocorrencia sequencial
|
|
85
|
+
].freeze
|
|
86
|
+
REGISTRO_U_FIELDS = %w[
|
|
87
|
+
juros_mora desconto_concedito valor_abatimento iof_desconto
|
|
88
|
+
valor_recebido outros_recebimento data_ocorrencia data_credito
|
|
89
|
+
].freeze
|
|
90
|
+
|
|
91
|
+
attr_accessor :tipo_registro
|
|
92
|
+
|
|
93
|
+
fixed_width_layout do |parse|
|
|
94
|
+
# comuns aos registros T e U
|
|
95
|
+
parse.field :codigo_registro, 7..7
|
|
96
|
+
parse.field :sequencial, 8..12
|
|
97
|
+
parse.field :tipo_registro, 13..13
|
|
98
|
+
parse.field :codigo_ocorrencia, 15..16
|
|
99
|
+
|
|
100
|
+
# segmento T
|
|
101
|
+
parse.field :agencia_com_dv, 18..21
|
|
102
|
+
parse.field :cedente_com_dv, 30..36
|
|
103
|
+
parse.field :carteira, 37..39
|
|
104
|
+
parse.field :nosso_numero, 40..47
|
|
105
|
+
parse.field :documento_numero, 58..67
|
|
106
|
+
parse.field :data_vencimento, 73..80
|
|
107
|
+
parse.field :valor_titulo, 81..95
|
|
108
|
+
parse.field :agencia_recebedora_com_dv, 99..104
|
|
109
|
+
parse.field :valor_tarifa, 198..212
|
|
110
|
+
parse.field :motivo_ocorrencia, 213..220
|
|
111
|
+
|
|
112
|
+
# segmento U
|
|
113
|
+
parse.field :juros_mora, 17..31
|
|
114
|
+
parse.field :desconto_concedito, 32..46
|
|
115
|
+
parse.field :valor_abatimento, 47..61
|
|
116
|
+
parse.field :iof_desconto, 62..76
|
|
117
|
+
parse.field :valor_recebido, 77..91
|
|
118
|
+
parse.field :outros_recebimento, 92..106
|
|
119
|
+
parse.field :data_ocorrencia, 137..144
|
|
120
|
+
parse.field :data_credito, 145..152
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Brcobranca
|
|
4
|
+
module Util
|
|
5
|
+
# Regras de calculo de digito verificador (DAC) compartilhadas entre as
|
|
6
|
+
# implementacoes de Boleto e Remessa/Retorno CNAB do Itau (341), para
|
|
7
|
+
# evitar duplicacao e manter as duas em sincronia.
|
|
8
|
+
module Itau
|
|
9
|
+
# Carteiras cujo DAC do nosso numero e calculado apenas com
|
|
10
|
+
# "carteira/nosso_numero", sem agencia/conta.
|
|
11
|
+
CARTEIRAS_SEM_AGENCIA_CONTA = %w[112 126 131 146 150 168].freeze
|
|
12
|
+
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
# Digito verificador (modulo 10) da agencia/conta corrente.
|
|
16
|
+
#
|
|
17
|
+
# @return [Integer]
|
|
18
|
+
def agencia_conta_corrente_dv(agencia, conta_corrente)
|
|
19
|
+
"#{agencia}#{conta_corrente}".modulo10
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Digito verificador (modulo 10) do nosso numero.
|
|
23
|
+
#
|
|
24
|
+
# Para a grande maioria das carteiras, e calculado sobre
|
|
25
|
+
# "agencia/conta_corrente/carteira/nosso_numero". Excecao: carteiras em
|
|
26
|
+
# CARTEIRAS_SEM_AGENCIA_CONTA, calculado apenas sobre
|
|
27
|
+
# "carteira/nosso_numero".
|
|
28
|
+
#
|
|
29
|
+
# @return [Integer]
|
|
30
|
+
def nosso_numero_dv(agencia, conta_corrente, carteira, nosso_numero)
|
|
31
|
+
if CARTEIRAS_SEM_AGENCIA_CONTA.include?(carteira.to_s)
|
|
32
|
+
"#{carteira}#{nosso_numero}".modulo10
|
|
33
|
+
else
|
|
34
|
+
"#{agencia}#{conta_corrente}#{carteira}#{nosso_numero}".modulo10
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/brcobranca/version.rb
CHANGED
data/lib/brcobranca.rb
CHANGED
|
@@ -148,6 +148,7 @@ module Brcobranca
|
|
|
148
148
|
|
|
149
149
|
module Cnab240
|
|
150
150
|
autoload :Base, 'brcobranca/retorno/cnab240/base'
|
|
151
|
+
autoload :Itau, "brcobranca/retorno/cnab240/itau"
|
|
151
152
|
autoload :Santander, 'brcobranca/retorno/cnab240/santander'
|
|
152
153
|
autoload :Sicredi, 'brcobranca/retorno/cnab240/sicredi'
|
|
153
154
|
autoload :Sicoob, 'brcobranca/retorno/cnab240/sicoob'
|
|
@@ -186,6 +187,7 @@ module Brcobranca
|
|
|
186
187
|
autoload :Base, 'brcobranca/remessa/cnab240/base'
|
|
187
188
|
autoload :BaseCorrespondente, 'brcobranca/remessa/cnab240/base_correspondente'
|
|
188
189
|
autoload :Caixa, 'brcobranca/remessa/cnab240/caixa'
|
|
190
|
+
autoload :Itau, "brcobranca/remessa/cnab240/itau"
|
|
189
191
|
autoload :BancoBrasil, 'brcobranca/remessa/cnab240/banco_brasil'
|
|
190
192
|
autoload :Santander, 'brcobranca/remessa/cnab240/santander'
|
|
191
193
|
autoload :Sicoob, 'brcobranca/remessa/cnab240/sicoob'
|
|
@@ -200,5 +202,6 @@ module Brcobranca
|
|
|
200
202
|
module Util
|
|
201
203
|
autoload :Empresa, 'brcobranca/util/empresa'
|
|
202
204
|
autoload :Errors, 'brcobranca/util/errors'
|
|
205
|
+
autoload :Itau, "brcobranca/util/itau"
|
|
203
206
|
end
|
|
204
207
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brcobranca
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 13.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kivanio Barbosa
|
|
@@ -150,6 +150,7 @@ files:
|
|
|
150
150
|
- lib/brcobranca/remessa/cnab240/base.rb
|
|
151
151
|
- lib/brcobranca/remessa/cnab240/base_correspondente.rb
|
|
152
152
|
- lib/brcobranca/remessa/cnab240/caixa.rb
|
|
153
|
+
- lib/brcobranca/remessa/cnab240/itau.rb
|
|
153
154
|
- lib/brcobranca/remessa/cnab240/santander.rb
|
|
154
155
|
- lib/brcobranca/remessa/cnab240/sicoob.rb
|
|
155
156
|
- lib/brcobranca/remessa/cnab240/sicoob_banco_brasil.rb
|
|
@@ -175,6 +176,7 @@ files:
|
|
|
175
176
|
- lib/brcobranca/retorno/cnab240/ailos.rb
|
|
176
177
|
- lib/brcobranca/retorno/cnab240/base.rb
|
|
177
178
|
- lib/brcobranca/retorno/cnab240/caixa.rb
|
|
179
|
+
- lib/brcobranca/retorno/cnab240/itau.rb
|
|
178
180
|
- lib/brcobranca/retorno/cnab240/santander.rb
|
|
179
181
|
- lib/brcobranca/retorno/cnab240/sicoob.rb
|
|
180
182
|
- lib/brcobranca/retorno/cnab240/sicredi.rb
|
|
@@ -194,6 +196,7 @@ files:
|
|
|
194
196
|
- lib/brcobranca/util/date.rb
|
|
195
197
|
- lib/brcobranca/util/empresa.rb
|
|
196
198
|
- lib/brcobranca/util/errors.rb
|
|
199
|
+
- lib/brcobranca/util/itau.rb
|
|
197
200
|
- lib/brcobranca/validations.rb
|
|
198
201
|
- lib/brcobranca/version.rb
|
|
199
202
|
homepage: https://github.com/kivanio/brcobranca
|
|
@@ -215,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
215
218
|
version: '0'
|
|
216
219
|
requirements:
|
|
217
220
|
- GhostScript > 9.0, para gerar PDF e código de Barras
|
|
218
|
-
rubygems_version:
|
|
221
|
+
rubygems_version: 4.0.16
|
|
219
222
|
specification_version: 4
|
|
220
223
|
summary: Gem que permite trabalhar com boletos e CNABs para bancos brasileiros.
|
|
221
224
|
test_files: []
|