cnab240 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +61 -8
- data/docs/vendor/itau/sisdeb_cnab_240.pdf +0 -0
- data/lib/cnab240/arquivo/arquivo.rb +14 -57
- data/lib/cnab240/arquivo/builder.rb +118 -0
- data/lib/cnab240/arquivo/estrutura.rb +68 -45
- data/lib/cnab240/arquivo/lote.rb +13 -5
- data/lib/cnab240/arquivo/v40/header.rb +46 -0
- data/lib/cnab240/arquivo/v40/trailer.rb +17 -0
- data/lib/cnab240/arquivo/{header.rb → v86/header.rb} +2 -2
- data/lib/cnab240/arquivo/{trailer.rb → v86/trailer.rb} +1 -1
- data/lib/cnab240/helper/remessa.rb +29 -0
- data/lib/cnab240/pagamentos/v40/header.rb +55 -0
- data/lib/cnab240/pagamentos/v40/trailer.rb +18 -0
- data/lib/cnab240/pagamentos/{header.rb → v86/header.rb} +1 -2
- data/lib/cnab240/pagamentos/{titulos → v86/titulos}/header.rb +1 -1
- data/lib/cnab240/pagamentos/{titulos → v86/titulos}/trailer.rb +1 -1
- data/lib/cnab240/pagamentos/{trailer.rb → v86/trailer.rb} +1 -1
- data/lib/cnab240/pagamentos/{tributos → v86/tributos}/header.rb +1 -1
- data/lib/cnab240/pagamentos/{tributos → v86/tributos}/trailer.rb +1 -1
- data/lib/cnab240/segmentos/{segmento_a.rb → v40/segmento_a.rb} +3 -1
- data/lib/cnab240/segmentos/v86/segmento_a.rb +47 -0
- data/lib/cnab240/segmentos/{segmento_b.rb → v86/segmento_b.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_c.rb → v86/segmento_c.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_j.rb → v86/segmento_j.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_j52.rb → v86/segmento_j52.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_n.rb → v86/segmento_n.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_n1.rb → v86/segmento_n1.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_n2.rb → v86/segmento_n2.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_n3.rb → v86/segmento_n3.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_n4.rb → v86/segmento_n4.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_n5.rb → v86/segmento_n5.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_n6.rb → v86/segmento_n6.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_n7.rb → v86/segmento_n7.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_n8.rb → v86/segmento_n8.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_o.rb → v86/segmento_o.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_w.rb → v86/segmento_w.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_w1.rb → v86/segmento_w1.rb} +1 -1
- data/lib/cnab240/segmentos/{segmento_z.rb → v86/segmento_z.rb} +1 -1
- data/lib/cnab240/version.rb +1 -1
- data/lib/cnab240.rb +39 -26
- data/spec/arquivo/arquivo_spec.rb +13 -5
- data/spec/arquivo/v40/header_spec.rb +68 -0
- data/spec/arquivo/v40/trailer_spec.rb +25 -0
- data/spec/arquivo/{header_spec.rb → v86/header_spec.rb} +6 -6
- data/spec/arquivo/{trailer_spec.rb → v86/trailer_spec.rb} +3 -3
- data/spec/cnab240_spec.rb +4 -4
- data/spec/pagamentos/v40/header_spec.rb +59 -0
- data/spec/pagamentos/v40/lote_spec.rb +24 -0
- data/spec/pagamentos/v40/trailer_spec.rb +28 -0
- data/spec/pagamentos/{header_spec.rb → v86/header_spec.rb} +3 -3
- data/spec/pagamentos/{lote_spec.rb → v86/lote_spec.rb} +4 -4
- data/spec/pagamentos/{titulos → v86/titulos}/header_spec.rb +3 -3
- data/spec/pagamentos/{titulos → v86/titulos}/lote_spec.rb +4 -4
- data/spec/pagamentos/{titulos → v86/titulos}/trailer_spec.rb +3 -3
- data/spec/pagamentos/{trailer_spec.rb → v86/trailer_spec.rb} +3 -3
- data/spec/pagamentos/{tributos → v86/tributos}/header_spec.rb +3 -3
- data/spec/pagamentos/{tributos → v86/tributos}/lote_spec.rb +4 -4
- data/spec/pagamentos/{tributos → v86/tributos}/trailer_spec.rb +3 -3
- data/spec/segmentos/{segmento_a_spec.rb → v40/segmento_a_spec.rb} +2 -2
- data/spec/segmentos/v86/segmento_a_spec.rb +65 -0
- data/spec/segmentos/{segmento_b_spec.rb → v86/segmento_b_spec.rb} +2 -2
- data/spec/segmentos/{segmento_c_spec.rb → v86/segmento_c_spec.rb} +2 -2
- data/spec/segmentos/{segmento_j52_spec.rb → v86/segmento_j52_spec.rb} +2 -2
- data/spec/segmentos/{segmento_j_spec.rb → v86/segmento_j_spec.rb} +2 -2
- data/spec/segmentos/{segmento_n1_spec.rb → v86/segmento_n1_spec.rb} +2 -2
- data/spec/segmentos/{segmento_n2_spec.rb → v86/segmento_n2_spec.rb} +2 -2
- data/spec/segmentos/{segmento_n3_spec.rb → v86/segmento_n3_spec.rb} +2 -2
- data/spec/segmentos/{segmento_n4_spec.rb → v86/segmento_n4_spec.rb} +2 -2
- data/spec/segmentos/{segmento_n5_spec.rb → v86/segmento_n5_spec.rb} +2 -2
- data/spec/segmentos/{segmento_n6_spec.rb → v86/segmento_n6_spec.rb} +2 -2
- data/spec/segmentos/{segmento_n7_spec.rb → v86/segmento_n7_spec.rb} +2 -2
- data/spec/segmentos/{segmento_n8_spec.rb → v86/segmento_n8_spec.rb} +2 -2
- data/spec/segmentos/{segmento_n_spec.rb → v86/segmento_n_spec.rb} +3 -3
- data/spec/segmentos/{segmento_o_spec.rb → v86/segmento_o_spec.rb} +2 -2
- data/spec/segmentos/{segmento_spec.rb → v86/segmento_spec.rb} +1 -1
- data/spec/segmentos/{segmento_w_spec.rb → v86/segmento_w_spec.rb} +2 -2
- data/spec/segmentos/{segmento_z_spec.rb → v86/segmento_z_spec.rb} +2 -2
- metadata +167 -137
data/README.md
CHANGED
@@ -2,7 +2,22 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://secure.travis-ci.org/eduardordm/cnab240.png)](http://travis-ci.org/eduardordm/cnab240)
|
4
4
|
|
5
|
-
Esta é uma implementação do Layout Padrão Febraban 240 posições,
|
5
|
+
Esta é uma implementação do Layout Padrão Febraban 240 posições, e algumas variações. Provavelmente vou adicionar o CNAB 400 na mesma gem. Talvez adicione também um puxadinho para voce poder usar o ActiveRecord.
|
6
|
+
|
7
|
+
|
8
|
+
Os padrões da febraban são fruto de incompêtencia que ultrapassa os limites do patético. Espero que essa implementação lhe poupe algumas horas de sofrimento.
|
9
|
+
|
10
|
+
|
11
|
+
Adicionar mais implementações é simples. Leia os testes. Aos poucos vou adicionando alguma documentação.
|
12
|
+
|
13
|
+
|
14
|
+
## Variações suportadas:
|
15
|
+
|
16
|
+
Somente pagamentos. Veja pasta docs/
|
17
|
+
|
18
|
+
- Layout Padrão FEBRABAN 240 posições V8.6
|
19
|
+
- Layout FEBRABAN 240 posições V4.0 (Itaú - SISDEB)
|
20
|
+
|
6
21
|
|
7
22
|
## Instalação
|
8
23
|
|
@@ -20,15 +35,53 @@ Ou adicione no seu chiqueiro:
|
|
20
35
|
|
21
36
|
## Como usar
|
22
37
|
|
23
|
-
|
38
|
+
Por enquanto sem muita documentação (veja os testes).
|
24
39
|
|
25
|
-
|
40
|
+
Em algum lugar voce pode criar um arquivo de inicialização (não é obrigatório):
|
26
41
|
|
27
|
-
|
42
|
+
A única configuração suportada até o momento é a de valores-padrão para campos:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
Cnab240.setup do |config|
|
46
|
+
# configuracoes aqui
|
47
|
+
config.defaults[:empresa_tipo] = "1"
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
Voce pode criar arquivos, e adicionar lotes. A versão é automaticamente a 8.6, se preferir voce pode escolher outra versão. Utilize o operador << do arquivo para adicionar lotes.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
arquivo = Arquivo::Arquivo.new
|
55
|
+
lote = Lote.new(:operacao => :pagamento, :tipo => :remessa)
|
56
|
+
# preencha os zilhoes de campos
|
57
|
+
arquivo << lote
|
58
|
+
arquivo.save_to_file("arquivo.test")
|
59
|
+
```
|
60
|
+
Quando um lote é criado, os segmento obrigatórios e métodos de acesso serão criados automagicamente. Para adicionar mais segmentos utilize o operador << do lote.
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
arquivo = Arquivo::Arquivo.new('V86')
|
64
|
+
lote = Lote.new(:operacao => :pagamento, :tipo => :remessa)
|
65
|
+
# preencha os zilhoes de campos
|
66
|
+
lote.segmento_a.favorecido_banco = '1'
|
67
|
+
arquivo << lote
|
68
|
+
arquivo.save_to_file("arquivo.test")
|
69
|
+
```
|
70
|
+
|
71
|
+
Ler do arquivo:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
arquivos = Arquivo::Arquivo.load_from_file("spec/tmp/arquivo.test") # array de objetos Arquivo
|
75
|
+
puts arquivos[0].header
|
76
|
+
```
|
77
|
+
|
78
|
+
## Considerações
|
79
|
+
|
80
|
+
- Tudo string. O arquivo é de strings, a implementação também.
|
81
|
+
|
82
|
+
## Contribuindo
|
28
83
|
|
29
|
-
|
84
|
+
Adicione testes, abra o pull request. Sem bikeshedding, wizardry ou craftismos pro meu lado!!! O código aqui deve ser de simples entendimento.
|
30
85
|
|
31
|
-
|
32
|
-
2. Sem bikeshedding.
|
33
|
-
3. Sem bikeshedding.
|
86
|
+
Meta code coverage: 100% para layout e marshalling. O resto, só se for muito importante.
|
34
87
|
|
Binary file
|
@@ -1,16 +1,18 @@
|
|
1
1
|
module Cnab240::Arquivo
|
2
2
|
class Arquivo
|
3
|
+
|
3
4
|
attr_accessor :header
|
4
5
|
attr_accessor :lotes
|
5
6
|
attr_accessor :trailer
|
7
|
+
attr_accessor :versao
|
6
8
|
|
7
|
-
def initialize
|
8
|
-
@
|
9
|
-
@
|
9
|
+
def initialize(versao = "V86")
|
10
|
+
@versao = versao
|
11
|
+
@header = eval("Cnab240::#{versao}::Arquivo::Header").new
|
12
|
+
@trailer = eval("Cnab240::#{versao}::Arquivo::Trailer").new
|
10
13
|
@lotes = []
|
11
14
|
end
|
12
15
|
|
13
|
-
|
14
16
|
def linhas
|
15
17
|
a = Array.new
|
16
18
|
a << @header.linha
|
@@ -23,6 +25,11 @@ module Cnab240::Arquivo
|
|
23
25
|
a
|
24
26
|
end
|
25
27
|
|
28
|
+
def <<(lote)
|
29
|
+
lote.arquivo = self
|
30
|
+
@lotes << lote
|
31
|
+
end
|
32
|
+
|
26
33
|
def string
|
27
34
|
linhas.join("\n")
|
28
35
|
end
|
@@ -35,60 +42,10 @@ module Cnab240::Arquivo
|
|
35
42
|
File.open(filename, 'w') {|f| f.write(string) }
|
36
43
|
end
|
37
44
|
|
38
|
-
def self.load_from_file(filename)
|
39
|
-
arquivos
|
40
|
-
line_number = 0
|
41
|
-
File.open(filename, "r").each_line do |line|
|
42
|
-
line.gsub!("\n", "")
|
43
|
-
line_number = line_number + 1
|
44
|
-
raise "Invalid line length: #{line.length} expected 240 at line number #{line_number}\n\t Line: [#{line}]" unless line.length == 240
|
45
|
-
case line[7..7] # ruby 1.8.7
|
46
|
-
when '0' # header de arquivo
|
47
|
-
arquivos << Arquivo.new
|
48
|
-
arquivos.last.header = Header.read(line)
|
49
|
-
when '1'
|
50
|
-
case line[13..15]
|
51
|
-
when '044'
|
52
|
-
arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
|
53
|
-
l.header = Cnab240::Pagamentos::Header.read(line)
|
54
|
-
end
|
55
|
-
when '040'
|
56
|
-
arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento_titulo_cobranca, :tipo => :none) do |l|
|
57
|
-
l.header = Cnab240::PagamentosTitulos::Header.read(line)
|
58
|
-
end
|
59
|
-
when '011'
|
60
|
-
arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento_titulo_tributos, :tipo => :none) do |l|
|
61
|
-
l.header = Cnab240::PagamentosTributos::Header.read(line)
|
62
|
-
end
|
63
|
-
else
|
64
|
-
raise "Invalid tipo de lote: #{line[13..15]} at line #{line_number}"
|
65
|
-
end
|
66
|
-
when '2'
|
67
|
-
raise NotImplementedError.new("Tipo de registro not implemented")
|
68
|
-
when '3'
|
69
|
-
raise "Invalid segmento de lote: #{line[13..13]} at line #{line_number}" unless ESTRUTURA[:segmentos_implementados].include? line[13..13].downcase.intern
|
70
|
-
case line[13..13]
|
71
|
-
when 'J'
|
72
|
-
if line[17..18] == '52'
|
73
|
-
arquivos.last.lotes.last.read_segmento('J52', line)
|
74
|
-
else
|
75
|
-
arquivos.last.lotes.last.read_segmento('J', line)
|
76
|
-
end
|
77
|
-
else
|
78
|
-
arquivos.last.lotes.last.read_segmento(line[13..13], line)
|
79
|
-
end
|
80
|
-
when '4'
|
81
|
-
raise NotImplementedError.new("Tipo de registro not implemented")
|
82
|
-
when '5'
|
83
|
-
arquivos.last.lotes.last.trailer.read(line)
|
84
|
-
when '9'
|
85
|
-
arquivos.last.trailer = Trailer.read(line)
|
86
|
-
else
|
87
|
-
raise "Invalid tipo de registro: #{line[7..7]} at line #{line_number} \n\t Line: [#{line}]"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
arquivos
|
45
|
+
def self.load_from_file(filename)
|
46
|
+
Cnab240::Builder.new(filename).arquivos
|
91
47
|
end
|
48
|
+
|
92
49
|
end
|
93
50
|
|
94
51
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Cnab240
|
2
|
+
class Builder
|
3
|
+
|
4
|
+
HEADER_ARQUIVO = '0'
|
5
|
+
HEADER_LOTE = '1'
|
6
|
+
INICIAIS_LOTE = '2'
|
7
|
+
DETALHE = '3'
|
8
|
+
FINAIS_LOTE = '4'
|
9
|
+
TRAILER_LOTE = '5'
|
10
|
+
TRAILER_ARQUIVO = '9'
|
11
|
+
|
12
|
+
RANGE_TIPO_REGISTRO = 7..7
|
13
|
+
RANGE_LAYOUT_ARQUIVO = 163..165
|
14
|
+
RANGE_HEADER_LOTE = 13..15
|
15
|
+
RANGE_TIPO_OPERACAO_DETALHE = 13..13
|
16
|
+
|
17
|
+
attr_accessor :arquivos
|
18
|
+
|
19
|
+
def initialize(filename = nil)
|
20
|
+
load_from_file(filename) unless filename.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_from_file(filename)
|
24
|
+
@arquivos = []
|
25
|
+
line_number = 0
|
26
|
+
File.open(filename, "r").each_line do |line|
|
27
|
+
check_line_encoding line, ++line_number
|
28
|
+
case line[RANGE_TIPO_REGISTRO]
|
29
|
+
|
30
|
+
when HEADER_ARQUIVO
|
31
|
+
find_header_arquivo line, line_number
|
32
|
+
|
33
|
+
when HEADER_LOTE
|
34
|
+
find_header_lote line, line_number
|
35
|
+
|
36
|
+
when INICIAIS_LOTE
|
37
|
+
raise NotImplementedError.new("Tipo de registro nao suportado")
|
38
|
+
|
39
|
+
when DETALHE
|
40
|
+
find_segmento line, line_number
|
41
|
+
|
42
|
+
when FINAIS_LOTE
|
43
|
+
raise NotImplementedError.new("Tipo de registro not implemented")
|
44
|
+
|
45
|
+
when TRAILER_LOTE
|
46
|
+
arquivos.last.lotes.last.trailer.read(line)
|
47
|
+
|
48
|
+
when TRAILER_ARQUIVO
|
49
|
+
arquivos.last.trailer = Trailer.read(line)
|
50
|
+
|
51
|
+
else
|
52
|
+
raise "Invalid tipo de registro: #{line[RANGE_TIPO_REGISTRO]} at line #{line_number} \n\t Line: [#{line}]"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
arquivos
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def check_line_encoding(line, line_number = -1)
|
61
|
+
line = line.force_encoding("US-ASCII").encode("UTF-8", :invalid=>:replace) if line.respond_to?(:force_encoding)
|
62
|
+
line.gsub!("\r", "")
|
63
|
+
line.gsub!("\n", "")
|
64
|
+
raise "Invalid line length: #{line.length} expected 240 at line number #{line_number}\n\t Line: [#{line}]" unless line.length == 240
|
65
|
+
line
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_header_arquivo(line, line_number = -1)
|
69
|
+
arquivos << Cnab240::Arquivo::Arquivo.new
|
70
|
+
case line[RANGE_LAYOUT_ARQUIVO]
|
71
|
+
when '085'
|
72
|
+
arquivos.last.versao = 'V86'
|
73
|
+
arquivos.last.header = Cnab240::V86::Arquivo::Header.read(line)
|
74
|
+
when '040'
|
75
|
+
arquivos.last.versao = 'V40'
|
76
|
+
arquivos.last.header = Cnab240::V40::Arquivo::Header.read(line)
|
77
|
+
else
|
78
|
+
raise "Versao de arquivo nao suportado: #{line[RANGE_LAYOUT_ARQUIVO]} na linha #{line_number}" if Cnab240.fallback == false
|
79
|
+
arquivos.last.versao = 'V86'
|
80
|
+
arquivos.last.header = Cnab240::V86::Arquivo::Header.read(line)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def find_header_lote(line, line_number = -1)
|
85
|
+
case line[RANGE_HEADER_LOTE]
|
86
|
+
when '044'
|
87
|
+
arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
|
88
|
+
l.header = Cnab240::V86::Pagamentos::Header.read(line)
|
89
|
+
end
|
90
|
+
when '040'
|
91
|
+
arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento_titulo_cobranca, :tipo => :none) do |l|
|
92
|
+
l.header = Cnab240::V86::PagamentosTitulos::Header.read(line)
|
93
|
+
end
|
94
|
+
when '011'
|
95
|
+
arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento_titulo_tributos, :tipo => :none) do |l|
|
96
|
+
l.header = Cnab240::V86::PagamentosTributos::Header.read(line)
|
97
|
+
end
|
98
|
+
else
|
99
|
+
raise "Tipo de lote nao suportado: #{line[RANGE_HEADER_LOTE]} na linha #{line_number}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def find_segmento(line, line_number = -1)
|
104
|
+
raise "Invalid segmento de lote: #{line[RANGE_TIPO_OPERACAO_DETALHE]} at line #{line_number}" unless ESTRUTURA[arquivos.last.versao][:segmentos_implementados].include? line[RANGE_TIPO_OPERACAO_DETALHE].downcase.intern
|
105
|
+
case line[RANGE_TIPO_OPERACAO_DETALHE]
|
106
|
+
when 'J'
|
107
|
+
if line[17..18] == '52'
|
108
|
+
arquivos.last.lotes.last.read_segmento('J52', line)
|
109
|
+
else
|
110
|
+
arquivos.last.lotes.last.read_segmento('J', line)
|
111
|
+
end
|
112
|
+
else
|
113
|
+
arquivos.last.lotes.last.read_segmento(line[RANGE_TIPO_OPERACAO_DETALHE], line)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -1,61 +1,84 @@
|
|
1
1
|
module Cnab240
|
2
2
|
|
3
|
-
|
4
|
-
:segmentos_implementados => [:a
|
3
|
+
ESTRUTURA_V40 = {
|
4
|
+
:segmentos_implementados => [:a],
|
5
5
|
:pagamento => {
|
6
|
-
:header => Cnab240::Pagamentos::Header,
|
7
|
-
:trailer => Cnab240::Pagamentos::Trailer,
|
8
|
-
:segmentos => [:a
|
6
|
+
:header => Cnab240::V40::Pagamentos::Header,
|
7
|
+
:trailer => Cnab240::V40::Pagamentos::Trailer,
|
8
|
+
:segmentos => [:a],
|
9
9
|
:a => {
|
10
10
|
:remessa => true,
|
11
11
|
:retorno => true
|
12
|
-
},
|
13
|
-
:b => {
|
14
|
-
:remessa => true,
|
15
|
-
:retorno => true
|
16
|
-
},
|
17
|
-
:c => {
|
18
|
-
:remessa => false,
|
19
|
-
:retorno => false
|
20
12
|
}
|
21
|
-
}
|
13
|
+
}
|
14
|
+
}
|
22
15
|
|
23
|
-
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:segmentos => [:j, :j52],
|
27
|
-
:j => {
|
28
|
-
:remessa => true,
|
29
|
-
:retorno => true
|
30
|
-
},
|
31
|
-
:j52 => {
|
32
|
-
:remessa => false,
|
33
|
-
:retorno => false
|
34
|
-
}
|
35
|
-
},
|
16
|
+
ESTRUTURA_V86 = {
|
17
|
+
:segmentos_implementados => [:a, :b, :c, :j, :j52, :o, :n, :w, :z],
|
18
|
+
:pagamento => {
|
36
19
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
20
|
+
:header => Cnab240::V86::Pagamentos::Header,
|
21
|
+
:trailer => Cnab240::V86::Pagamentos::Trailer,
|
22
|
+
|
23
|
+
:segmentos => [:a, :b, :c],
|
24
|
+
:a => {
|
25
|
+
:remessa => true,
|
26
|
+
:retorno => true
|
27
|
+
},
|
28
|
+
:b => {
|
29
|
+
:remessa => true,
|
30
|
+
:retorno => true
|
31
|
+
},
|
32
|
+
:c => {
|
33
|
+
:remessa => false,
|
34
|
+
:retorno => false
|
35
|
+
}
|
48
36
|
},
|
49
|
-
|
50
|
-
|
51
|
-
|
37
|
+
|
38
|
+
:pagamento_titulo_cobranca => {
|
39
|
+
|
40
|
+
:header => Cnab240::V86::PagamentosTitulos::Header,
|
41
|
+
:trailer => Cnab240::V86::PagamentosTitulos::Trailer,
|
42
|
+
|
43
|
+
:segmentos => [:j, :j52],
|
44
|
+
:j => {
|
45
|
+
:remessa => true,
|
46
|
+
:retorno => true
|
47
|
+
},
|
48
|
+
:j52 => {
|
49
|
+
:remessa => false,
|
50
|
+
:retorno => false
|
51
|
+
}
|
52
52
|
},
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
|
54
|
+
:pagamento_titulo_tributos => {
|
55
|
+
|
56
|
+
:header => Cnab240::V86::PagamentosTributos::Header,
|
57
|
+
:trailer => Cnab240::V86::PagamentosTributos::Trailer,
|
58
|
+
|
59
|
+
:segmentos => [:o, :n, :w, :z],
|
60
|
+
:o => {
|
61
|
+
:remessa => true,
|
62
|
+
:retorno => true
|
63
|
+
},
|
64
|
+
:n => {
|
65
|
+
:remessa => true,
|
66
|
+
:retorno => true
|
67
|
+
},
|
68
|
+
:w => {
|
69
|
+
:remessa => false,
|
70
|
+
:retorno => false
|
71
|
+
},
|
72
|
+
:z => {
|
73
|
+
:remessa => false,
|
74
|
+
:retorno => false
|
75
|
+
}
|
56
76
|
}
|
57
|
-
|
77
|
+
}
|
58
78
|
|
79
|
+
ESTRUTURA = {
|
80
|
+
'V40' => ESTRUTURA_V40,
|
81
|
+
'V86' => ESTRUTURA_V86,
|
59
82
|
}
|
60
83
|
|
61
84
|
end
|
data/lib/cnab240/arquivo/lote.rb
CHANGED
@@ -1,22 +1,27 @@
|
|
1
1
|
module Cnab240
|
2
2
|
class Lote
|
3
|
+
|
3
4
|
attr_accessor :header
|
4
5
|
attr_accessor :segmentos
|
5
6
|
attr_accessor :trailer
|
6
7
|
attr_accessor :operacao
|
7
8
|
attr_accessor :tipo
|
9
|
+
attr_accessor :arquivo
|
8
10
|
|
9
11
|
def initialize(options = {})
|
10
12
|
@segmentos = {}
|
11
13
|
|
12
14
|
@operacao ||= options[:operacao]
|
13
15
|
@tipo ||= options[:tipo]
|
16
|
+
@versao ||= options[:versao]
|
17
|
+
@fallback ||= options[:fallback]
|
18
|
+
@versao ||= 'V86'
|
14
19
|
|
15
|
-
raise "Operacao nao suportada: #{operacao}" if ESTRUTURA[operacao].nil?
|
20
|
+
raise "Operacao nao suportada: #{operacao}" if ESTRUTURA[@versao][operacao].nil?
|
16
21
|
|
17
|
-
estrutura = ESTRUTURA[operacao]
|
22
|
+
estrutura = ESTRUTURA[@versao][operacao]
|
18
23
|
|
19
|
-
@header = estrutura[:header].new
|
24
|
+
@header = estrutura[:header].new
|
20
25
|
@trailer = estrutura[:trailer].new
|
21
26
|
|
22
27
|
yield self if block_given?
|
@@ -37,7 +42,10 @@ module Cnab240
|
|
37
42
|
end
|
38
43
|
|
39
44
|
def <<(s)
|
40
|
-
|
45
|
+
versao = arquivo.versao unless arquivo.nil?
|
46
|
+
versao ||= @versao
|
47
|
+
|
48
|
+
segmentos[s] = eval("Cnab240::#{versao}::Segmento#{s.to_s.upcase}.new")
|
41
49
|
segmentos[s].lote = self
|
42
50
|
add_segmento_accessors(s)
|
43
51
|
segmentos[s]
|
@@ -45,7 +53,7 @@ module Cnab240
|
|
45
53
|
|
46
54
|
def linhas
|
47
55
|
seg_array = Array.new
|
48
|
-
estrutura = ESTRUTURA[operacao]
|
56
|
+
estrutura = ESTRUTURA[@versao][operacao]
|
49
57
|
seg_array << @header.linha
|
50
58
|
estrutura[:segmentos].each do |s|
|
51
59
|
seg_array << @segmentos[s].linha unless @segmentos[s].nil?
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Cnab240::V40::Arquivo
|
2
|
+
class Header < BinData::Record
|
3
|
+
|
4
|
+
include Cnab240::DefaultMixin
|
5
|
+
|
6
|
+
string :controle_banco, :length => 3, :pad_byte => '0'
|
7
|
+
string :controle_lote, :length => 4, :initial_value => '0000', :pad_byte => '0'
|
8
|
+
string :controle_registro, :length => 1, :initial_value => '0', :pad_byte => '0'
|
9
|
+
|
10
|
+
string :cnab_g004_1, :length => 9, :initial_value => ' ', :pad_byte => ' '
|
11
|
+
|
12
|
+
string :empresa_tipo, :length => 1, :pad_byte => '0'
|
13
|
+
string :empresa_numero, :length => 14, :pad_byte => '0'
|
14
|
+
string :empresa_convenio, :length => 13, :pad_byte => ' '
|
15
|
+
|
16
|
+
string :brancos_1, :length => 7, :pad_byte => ' '
|
17
|
+
string :brancos_2, :length => 1, :pad_byte => '0'
|
18
|
+
|
19
|
+
string :empresa_agencia_codigo, :length => 4, :pad_byte => '0'
|
20
|
+
|
21
|
+
string :brancos_3, :length => 1, :pad_byte => ' '
|
22
|
+
string :brancos_4, :length => 7, :pad_byte => '0'
|
23
|
+
|
24
|
+
string :empresa_conta_numero, :length => 5, :pad_byte => '0'
|
25
|
+
string :brancos_5, :length => 1, :pad_byte => ' '
|
26
|
+
|
27
|
+
string :empresa_agencia_conta_dv, :length => 1, :pad_byte => ' '
|
28
|
+
string :empresa_nome, :length => 30, :pad_byte => ' '
|
29
|
+
|
30
|
+
string :banco_nome, :length => 30, :pad_byte => ' '
|
31
|
+
|
32
|
+
string :cnab_g004_2, :length => 10, :pad_byte => ' '
|
33
|
+
|
34
|
+
string :arquivo_codigo, :length => 1, :pad_byte => '0'
|
35
|
+
string :arquivo_data_geracao, :length => 8, :pad_byte => '0'
|
36
|
+
string :arquivo_hora_geracao,:length => 6, :pad_byte => '0'
|
37
|
+
string :arquivo_sequencia, :length => 6, :pad_byte => '0'
|
38
|
+
string :arquivo_layout, :length => 3, :initial_value => '040'
|
39
|
+
string :arquivo_densidade, :length => 5, :pad_byte => '0'
|
40
|
+
|
41
|
+
string :reservado_banco, :length => 20, :pad_byte => ' '
|
42
|
+
|
43
|
+
string :cnab_g004_3, :length => 49, :pad_byte => ' '
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Cnab240::V40::Arquivo
|
2
|
+
class Trailer < BinData::Record
|
3
|
+
|
4
|
+
include Cnab240::DefaultMixin
|
5
|
+
|
6
|
+
string :controle_banco, :length => 3, :pad_byte => '0'
|
7
|
+
string :controle_lote, :length => 4, :initial_value => '9999', :pad_byte => '0'
|
8
|
+
string :controle_registro, :length => 1, :initial_value => '9', :pad_byte => '0'
|
9
|
+
|
10
|
+
string :cnab_g004_1, :length => 9, :pad_byte => ' '
|
11
|
+
|
12
|
+
string :totais_qtde_lotes, :length => 6, :pad_byte => '0'
|
13
|
+
string :totais_qtde_registros, :length => 6, :pad_byte => '0'
|
14
|
+
|
15
|
+
string :cnab_g004_2, :length => 211, :pad_byte => ' '
|
16
|
+
end
|
17
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
module Cnab240::Arquivo
|
1
|
+
module Cnab240::V86::Arquivo
|
2
2
|
class Header < BinData::Record
|
3
3
|
|
4
|
-
|
4
|
+
include Cnab240::DefaultMixin
|
5
5
|
|
6
6
|
string :controle_banco, :length => 3, :pad_byte => '0'
|
7
7
|
string :controle_lote, :length => 4, :initial_value => '0000', :pad_byte => '0'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Cnab240
|
2
|
+
class Remessa
|
3
|
+
|
4
|
+
attr_accessor :arquivo
|
5
|
+
|
6
|
+
def initialize(campos = {})
|
7
|
+
@arquivo = Cnab240::Arquivo::Arquivo.new
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def add(operacao, campos = {})
|
12
|
+
raise "Operacao invalida" if ESTRUTURA[:operacao].nil?
|
13
|
+
@arquivo.lotes << lote = Cnab240::Lote.new(:operacao => campos[:operacao], :tipo => :remessa)
|
14
|
+
campos.each do |k,v|
|
15
|
+
lote.header.send("#{k}=", v) if lote.header.respond_to?("#{k}=")
|
16
|
+
|
17
|
+
lote.trailer.send("#{k}=", v) if lote.trailer.respond_to?("#{k}=")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def string
|
22
|
+
end
|
23
|
+
|
24
|
+
def save_to_file
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Cnab240::V40::Pagamentos
|
2
|
+
class Header < BinData::Record
|
3
|
+
|
4
|
+
include Cnab240::DefaultMixin
|
5
|
+
|
6
|
+
string :controle_banco, :length => 3, :pad_byte => '0'
|
7
|
+
string :controle_lote, :length => 4, :pad_byte => '0'
|
8
|
+
string :controle_registro, :length => 1, :initial_value => '1', :pad_byte => '0'
|
9
|
+
|
10
|
+
string :servico_operacao, :length => 1, :initial_value => 'C', :pad_byte => ' '
|
11
|
+
string :servico_tipo, :length => 2 , :pad_byte => '0'
|
12
|
+
string :servico_forma, :length => 2, :pad_byte => '0'
|
13
|
+
string :servico_layout, :length => 3, :initial_value => '030', :pad_byte => '0'
|
14
|
+
string :cnab_g004_1, :length => 1, :pad_byte => ' '
|
15
|
+
|
16
|
+
string :empresa_tipo, :length => 1, :pad_byte => '0'
|
17
|
+
string :empresa_numero, :length => 14, :pad_byte => '0'
|
18
|
+
string :empresa_convenio, :length => 13, :pad_byte => ' '
|
19
|
+
|
20
|
+
|
21
|
+
string :brancos_1, :length => 7, :pad_byte => ' '
|
22
|
+
string :brancos_2, :length => 1, :pad_byte => '0'
|
23
|
+
|
24
|
+
|
25
|
+
string :empresa_agencia_codigo, :length => 4, :pad_byte => '0'
|
26
|
+
|
27
|
+
string :brancos_3, :length => 1, :pad_byte => ' '
|
28
|
+
string :brancos_4, :length => 7, :pad_byte => '0'
|
29
|
+
|
30
|
+
string :empresa_conta_numero, :length => 5, :pad_byte => '0'
|
31
|
+
|
32
|
+
string :brancos_5, :length => 1, :pad_byte => ' '
|
33
|
+
|
34
|
+
string :empresa_agencia_conta_dv, :length => 1, :pad_byte => ' '
|
35
|
+
string :empresa_nome, :length => 30, :pad_byte => ' '
|
36
|
+
|
37
|
+
string :informacao_1, :length => 40, :pad_byte => ' '
|
38
|
+
|
39
|
+
string :endereco_logradouro, :length => 30, :pad_byte => ' '
|
40
|
+
string :endereco_numero, :length => 5, :pad_byte => '0'
|
41
|
+
string :endereco_complemento, :length => 15, :pad_byte => ' '
|
42
|
+
string :endereco_cidade, :length => 20, :pad_byte => ' '
|
43
|
+
string :endereco_cep, :length => 8, :pad_byte => '0'
|
44
|
+
string :endereco_estado, :length => 2, :pad_byte => ' '
|
45
|
+
|
46
|
+
string :cnab_g004_2, :length => 8, :pad_byte => ' '
|
47
|
+
string :ocorrencias, :length => 10, :pad_byte => ' '
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def auto_fill
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Cnab240::V40::Pagamentos
|
2
|
+
class Trailer < BinData::Record
|
3
|
+
|
4
|
+
include Cnab240::DefaultMixin
|
5
|
+
|
6
|
+
string :controle_banco, :length => 3, :pad_byte => '0'
|
7
|
+
string :controle_lote, :length => 4, :pad_byte => '0'
|
8
|
+
string :controle_registro, :length => 1, :initial_value => '5', :pad_byte => '0'
|
9
|
+
|
10
|
+
string :cnab_g004_1, :length => 9, :pad_byte => '0'
|
11
|
+
string :totais_qtde_registros, :length => 6, :pad_byte => '0'
|
12
|
+
string :totais_valor, :length => 18, :pad_byte => '0'
|
13
|
+
string :totais_qtde_moeda, :length => 18, :pad_byte => '0'
|
14
|
+
|
15
|
+
string :cnab_g004_2, :length => 171, :pad_byte => ' '
|
16
|
+
string :ocorrencias, :length => 10, :pad_byte => ' '
|
17
|
+
end
|
18
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Cnab240::Pagamentos
|
1
|
+
module Cnab240::V86::Pagamentos
|
2
2
|
class Header < BinData::Record
|
3
3
|
|
4
4
|
include Cnab240::DefaultMixin
|
@@ -11,7 +11,6 @@ module Cnab240::Pagamentos
|
|
11
11
|
string :servico_tipo, :length => 2 , :pad_byte => '0'
|
12
12
|
string :servico_forma, :length => 2, :pad_byte => '0'
|
13
13
|
string :servico_layout, :length => 3, :initial_value => '044', :pad_byte => '0'
|
14
|
-
|
15
14
|
string :cnab_g004_1, :length => 1, :pad_byte => ' '
|
16
15
|
|
17
16
|
string :empresa_tipo, :length => 1, :pad_byte => '0'
|