cnab240 0.0.17 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/cnab240.gemspec +2 -1
  3. data/lib/cnab240/arquivo/arquivo.rb +89 -60
  4. data/lib/cnab240/arquivo/builder.rb +162 -154
  5. data/lib/cnab240/arquivo/estrutura.rb +159 -95
  6. data/lib/cnab240/arquivo/lote.rb +57 -57
  7. data/lib/cnab240/arquivo/v40/header.rb +30 -30
  8. data/lib/cnab240/arquivo/v40/trailer.rb +11 -11
  9. data/lib/cnab240/arquivo/v80/header.rb +28 -27
  10. data/lib/cnab240/arquivo/v80/trailer.rb +11 -11
  11. data/lib/cnab240/arquivo/v83/header.rb +38 -0
  12. data/lib/cnab240/arquivo/v83/trailer.rb +17 -0
  13. data/lib/cnab240/arquivo/v86/header.rb +27 -28
  14. data/lib/cnab240/arquivo/v86/trailer.rb +12 -12
  15. data/lib/cnab240/arquivo/v87/header.rb +38 -0
  16. data/lib/cnab240/arquivo/v87/trailer.rb +18 -0
  17. data/lib/cnab240/ext/attribute_accessors.rb +2 -2
  18. data/lib/cnab240/ext/bindata.rb +9 -9
  19. data/lib/cnab240/ext/default_mixin.rb +11 -12
  20. data/lib/cnab240/ext/filler.rb +16 -16
  21. data/lib/cnab240/ext/lstring.rb +5 -5
  22. data/lib/cnab240/ext/segmento_mixin.rb +4 -4
  23. data/lib/cnab240/helper/helper.rb +15 -0
  24. data/lib/cnab240/helper/pagamento_bb.rb +51 -0
  25. data/lib/cnab240/helper/pagamento_bradesco.rb +49 -0
  26. data/lib/cnab240/helper/pagamento_itau.rb +34 -49
  27. data/lib/cnab240/helper/pagamento_sicoob.rb +55 -0
  28. data/lib/cnab240/pagamentos/v40/header.rb +35 -37
  29. data/lib/cnab240/pagamentos/v40/trailer.rb +13 -13
  30. data/lib/cnab240/pagamentos/v80/header.rb +45 -45
  31. data/lib/cnab240/pagamentos/v80/trailer.rb +13 -13
  32. data/lib/cnab240/pagamentos/v83/header.rb +45 -0
  33. data/lib/cnab240/pagamentos/v83/trailer.rb +18 -0
  34. data/lib/cnab240/pagamentos/v86/header.rb +44 -44
  35. data/lib/cnab240/pagamentos/v86/titulos/header.rb +44 -44
  36. data/lib/cnab240/pagamentos/v86/titulos/trailer.rb +14 -14
  37. data/lib/cnab240/pagamentos/v86/trailer.rb +14 -14
  38. data/lib/cnab240/pagamentos/v86/tributos/header.rb +45 -45
  39. data/lib/cnab240/pagamentos/v86/tributos/trailer.rb +12 -12
  40. data/lib/cnab240/pagamentos/v87/header.rb +46 -0
  41. data/lib/cnab240/pagamentos/v87/titulos/header.rb +46 -0
  42. data/lib/cnab240/pagamentos/v87/titulos/trailer.rb +18 -0
  43. data/lib/cnab240/pagamentos/v87/trailer.rb +18 -0
  44. data/lib/cnab240/pagamentos/v87/tributos/header.rb +47 -0
  45. data/lib/cnab240/pagamentos/v87/tributos/trailer.rb +17 -0
  46. data/lib/cnab240/segmentos/v40/segmento_a.rb +45 -48
  47. data/lib/cnab240/segmentos/v80/agencia_itau.rb +11 -12
  48. data/lib/cnab240/segmentos/v80/agencia_outros.rb +9 -10
  49. data/lib/cnab240/segmentos/v80/segmento_a.rb +59 -61
  50. data/lib/cnab240/segmentos/v83/segmento_a.rb +42 -0
  51. data/lib/cnab240/segmentos/v83/segmento_b.rb +40 -0
  52. data/lib/cnab240/segmentos/v83/segmento_j.rb +33 -0
  53. data/lib/cnab240/segmentos/v83/segmento_z.rb +19 -0
  54. data/lib/cnab240/segmentos/v86/segmento_a.rb +42 -45
  55. data/lib/cnab240/segmentos/v86/segmento_b.rb +38 -39
  56. data/lib/cnab240/segmentos/v86/segmento_c.rb +23 -24
  57. data/lib/cnab240/segmentos/v86/segmento_j.rb +25 -26
  58. data/lib/cnab240/segmentos/v86/segmento_j52.rb +22 -24
  59. data/lib/cnab240/segmentos/v86/segmento_n.rb +50 -51
  60. data/lib/cnab240/segmentos/v86/segmento_n1.rb +13 -15
  61. data/lib/cnab240/segmentos/v86/segmento_n2.rb +15 -17
  62. data/lib/cnab240/segmentos/v86/segmento_n3.rb +15 -17
  63. data/lib/cnab240/segmentos/v86/segmento_n4.rb +17 -19
  64. data/lib/cnab240/segmentos/v86/segmento_n5.rb +15 -17
  65. data/lib/cnab240/segmentos/v86/segmento_n6.rb +15 -17
  66. data/lib/cnab240/segmentos/v86/segmento_n7.rb +16 -18
  67. data/lib/cnab240/segmentos/v86/segmento_n8.rb +15 -18
  68. data/lib/cnab240/segmentos/v86/segmento_o.rb +20 -21
  69. data/lib/cnab240/segmentos/v86/segmento_w.rb +16 -17
  70. data/lib/cnab240/segmentos/v86/segmento_w1.rb +12 -13
  71. data/lib/cnab240/segmentos/v86/segmento_z.rb +14 -14
  72. data/lib/cnab240/segmentos/v87/segmento_a.rb +44 -0
  73. data/lib/cnab240/segmentos/v87/segmento_b.rb +40 -0
  74. data/lib/cnab240/segmentos/v87/segmento_c.rb +32 -0
  75. data/lib/cnab240/segmentos/v87/segmento_j.rb +33 -0
  76. data/lib/cnab240/segmentos/v87/segmento_j52.rb +32 -0
  77. data/lib/cnab240/segmentos/v87/segmento_n.rb +59 -0
  78. data/lib/cnab240/segmentos/v87/segmento_n1.rb +19 -0
  79. data/lib/cnab240/segmentos/v87/segmento_n2.rb +21 -0
  80. data/lib/cnab240/segmentos/v87/segmento_n3.rb +21 -0
  81. data/lib/cnab240/segmentos/v87/segmento_n4.rb +23 -0
  82. data/lib/cnab240/segmentos/v87/segmento_n5.rb +21 -0
  83. data/lib/cnab240/segmentos/v87/segmento_n6.rb +21 -0
  84. data/lib/cnab240/segmentos/v87/segmento_n7.rb +21 -0
  85. data/lib/cnab240/segmentos/v87/segmento_n8.rb +22 -0
  86. data/lib/cnab240/segmentos/v87/segmento_o.rb +27 -0
  87. data/lib/cnab240/segmentos/v87/segmento_w.rb +24 -0
  88. data/lib/cnab240/segmentos/v87/segmento_w1.rb +16 -0
  89. data/lib/cnab240/segmentos/v87/segmento_z.rb +19 -0
  90. data/lib/cnab240/version.rb +1 -2
  91. data/lib/cnab240.rb +54 -24
  92. metadata +64 -133
  93. data/.gitignore +0 -19
  94. data/.rspec +0 -2
  95. data/.travis.yml +0 -4
  96. data/Gemfile +0 -6
  97. data/LICENSE +0 -22
  98. data/README.md +0 -135
  99. data/docs/vendor/febraban/subcpadr12_layout_padrao_V86.pdf +0 -0
  100. data/docs/vendor/itau/SISPAG_CNAB_240.pdf +0 -0
  101. data/docs/vendor/itau/sisdeb_cnab_240.pdf +0 -0
  102. data/spec/arquivo/arquivo_spec.rb +0 -95
  103. data/spec/arquivo/v40/header_spec.rb +0 -68
  104. data/spec/arquivo/v40/trailer_spec.rb +0 -25
  105. data/spec/arquivo/v80/header_spec.rb +0 -60
  106. data/spec/arquivo/v80/trailer_spec.rb +0 -26
  107. data/spec/arquivo/v86/header_spec.rb +0 -89
  108. data/spec/arquivo/v86/trailer_spec.rb +0 -27
  109. data/spec/bindata/bindata_spec.rb +0 -55
  110. data/spec/cnab240_spec.rb +0 -22
  111. data/spec/helper/pagamento_itau_spec.rb +0 -83
  112. data/spec/hom/hom_spec.rb +0 -65
  113. data/spec/hom/retorno/SB22112AIT.RET +0 -5
  114. data/spec/hom/retorno/SB23112AIT.RET +0 -5
  115. data/spec/pagamentos/v40/header_spec.rb +0 -59
  116. data/spec/pagamentos/v40/lote_spec.rb +0 -25
  117. data/spec/pagamentos/v40/trailer_spec.rb +0 -28
  118. data/spec/pagamentos/v80/header_spec.rb +0 -52
  119. data/spec/pagamentos/v80/lote_spec.rb +0 -25
  120. data/spec/pagamentos/v80/trailer_spec.rb +0 -28
  121. data/spec/pagamentos/v86/header_spec.rb +0 -53
  122. data/spec/pagamentos/v86/lote_spec.rb +0 -38
  123. data/spec/pagamentos/v86/titulos/header_spec.rb +0 -51
  124. data/spec/pagamentos/v86/titulos/lote_spec.rb +0 -37
  125. data/spec/pagamentos/v86/titulos/trailer_spec.rb +0 -30
  126. data/spec/pagamentos/v86/trailer_spec.rb +0 -30
  127. data/spec/pagamentos/v86/tributos/header_spec.rb +0 -53
  128. data/spec/pagamentos/v86/tributos/lote_spec.rb +0 -43
  129. data/spec/pagamentos/v86/tributos/trailer_spec.rb +0 -27
  130. data/spec/segmentos/v40/segmento_a_spec.rb +0 -70
  131. data/spec/segmentos/v80/segmento_a_spec.rb +0 -70
  132. data/spec/segmentos/v86/segmento_a_spec.rb +0 -65
  133. data/spec/segmentos/v86/segmento_b_spec.rb +0 -67
  134. data/spec/segmentos/v86/segmento_c_spec.rb +0 -51
  135. data/spec/segmentos/v86/segmento_j52_spec.rb +0 -55
  136. data/spec/segmentos/v86/segmento_j_spec.rb +0 -55
  137. data/spec/segmentos/v86/segmento_n1_spec.rb +0 -43
  138. data/spec/segmentos/v86/segmento_n2_spec.rb +0 -46
  139. data/spec/segmentos/v86/segmento_n3_spec.rb +0 -45
  140. data/spec/segmentos/v86/segmento_n4_spec.rb +0 -47
  141. data/spec/segmentos/v86/segmento_n5_spec.rb +0 -45
  142. data/spec/segmentos/v86/segmento_n6_spec.rb +0 -45
  143. data/spec/segmentos/v86/segmento_n7_spec.rb +0 -46
  144. data/spec/segmentos/v86/segmento_n8_spec.rb +0 -45
  145. data/spec/segmentos/v86/segmento_n_spec.rb +0 -73
  146. data/spec/segmentos/v86/segmento_o_spec.rb +0 -50
  147. data/spec/segmentos/v86/segmento_spec.rb +0 -12
  148. data/spec/segmentos/v86/segmento_w_spec.rb +0 -51
  149. data/spec/segmentos/v86/segmento_z_spec.rb +0 -42
  150. data/spec/spec_helper.rb +0 -10
  151. data/spec/tmp/.gitkeep +0 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f7abc2f60eafc559fb95f0efd7875b96426b2faf
4
+ data.tar.gz: d07c23e2e17044cde19afd54237cd44ce7d0ad3d
5
+ SHA512:
6
+ metadata.gz: a44d8711e5af6c8b68f49c2bb63f8112e9b01a4103c7b53fd825f9f68f8d969af0a99ce97d16331dba6ea30d93081a93ac5ce5151a0c2222163b94034689353c
7
+ data.tar.gz: e5c9c0ab4916bee2193c2e330b781df9388dc5421ebbdd02c03bd74ed755e981de60f42aca0ce405e7d21d38b1beb289555804a8c2fb535982e2427d90ab9339
data/cnab240.gemspec CHANGED
@@ -3,6 +3,7 @@ require File.expand_path('../lib/cnab240/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
5
  gem.add_development_dependency "rspec"
6
+ gem.add_development_dependency "debugger"
6
7
  gem.add_dependency "bindata"
7
8
 
8
9
  gem.authors = ["Eduardo Mourao"]
@@ -13,7 +14,7 @@ Gem::Specification.new do |gem|
13
14
 
14
15
  gem.rubyforge_project = "cnab240"
15
16
 
16
- gem.files = `git ls-files`.split($\)
17
+ gem.files = Dir.glob('lib/**/*') + ['Rakefile'] + ['cnab240.gemspec']
17
18
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
19
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
20
  gem.name = "cnab240"
@@ -1,61 +1,90 @@
1
1
  module Cnab240::Arquivo
2
- class Arquivo
3
-
4
- attr_accessor :header
5
- attr_accessor :lotes
6
- attr_accessor :trailer
7
- attr_accessor :versao
8
-
9
- def initialize(versao = "V86")
10
- @versao = versao
11
- @header = eval("Cnab240::#{versao}::Arquivo::Header").new
12
- @trailer = eval("Cnab240::#{versao}::Arquivo::Trailer").new
13
- @lotes = []
14
- end
15
-
16
- def linhas
17
- self.auto_fill if Cnab240.auto_fill_enabled
18
- a = []
19
- a << @header.linha
20
- @lotes.each do |lote|
21
- lote.linhas.each do |linha|
22
- a << linha
23
- end
24
- end
25
- a << @trailer.linha
26
- a
27
- end
28
-
29
- def <<(lote)
30
- lote.arquivo = self
31
- @lotes << lote
32
- end
33
-
34
- def string
35
- linhas.join("\r\n") << "\r\n"
36
- end
37
-
38
- def save_to_file(filename)
39
- begin
40
- File.delete(filename) # LoL
41
- rescue
42
- end
43
- File.open(filename, 'w') {|f| f.write(string) }
44
- end
45
-
46
- def self.load_from_file(filename)
47
- Cnab240::Builder.new(filename).arquivos
48
- end
49
-
50
-
51
- def auto_fill
52
- trailer.totais_qtde_lotes = lotes.length.to_s
53
- qtd_registros = lotes.length * 2 # header e trailer de cada lote
54
- lotes.each { |l| qtd_registros += l.segmentos.length } # segmentos
55
- qtd_registros += 2 # header e trailer de arquivo
56
- trailer.totais_qtde_registros = qtd_registros.to_s
57
- end
58
-
59
- end
60
-
61
- end
2
+ class Arquivo
3
+
4
+ attr_accessor :header
5
+ attr_accessor :lotes
6
+ attr_accessor :trailer
7
+ attr_accessor :versao
8
+
9
+ def initialize(versao = "V86")
10
+ @versao = versao
11
+ @header = eval("Cnab240::#{versao}::Arquivo::Header").new
12
+ @trailer = eval("Cnab240::#{versao}::Arquivo::Trailer").new
13
+ @lotes = []
14
+ end
15
+
16
+ def linhas
17
+ self.auto_fill if Cnab240.auto_fill_enabled
18
+ a = []
19
+ a << @header.linha
20
+ @lotes.each do |lote|
21
+ lote.linhas.each do |linha|
22
+ a << linha
23
+ end
24
+ end
25
+ a << @trailer.linha
26
+ a
27
+ end
28
+
29
+ def <<(lote)
30
+ lote.arquivo = self
31
+ @lotes << lote
32
+ end
33
+
34
+ def string
35
+ linhas.join("\r\n") << "\r\n"
36
+ end
37
+
38
+ # Writes +Cnab240::Arquivo::Arquivo+ contents into a +File+, overwriting its current contents.
39
+ #
40
+ # @example Save contents to a file.
41
+ # Cnab240::Arquivo::Arquivo.new.save_to_file('/tmp/cnab240.txt')
42
+ #
43
+ # @param [ String ] filename The file name to which the contents will be saved to.
44
+ #
45
+ # @return [ Integer ] The number of bytes written to the file.
46
+ #
47
+ # @since 0.0.20
48
+ def save_to_file(filename)
49
+ File.open(filename, 'w'){|f| f.write(string)}
50
+ end
51
+
52
+ # Loads contents from a +File+ into +Cnab240::Arquivo::Arquivo+ instances.
53
+ #
54
+ # @example Load contents from a file.
55
+ # Cnab240::Arquivo::Arquivo.load_from_file('/tmp/cnab240.txt')
56
+ #
57
+ # @param [ String ] filename The file name from which the contents will be read.
58
+ #
59
+ # @return [ Array<Cnab240::Arquivo::Arquivo> ] A list of +Cnab240::Arquivo::Arquivo+ instances representing the contents read.
60
+ #
61
+ # @since 0.0.20
62
+ def self.load_from_file(filename)
63
+ load(File.open(filename, 'r'))
64
+ end
65
+
66
+ # Loads contents from an object that implements the +IO+ interface into +Cnab240::Arquivo::Arquivo+ instances.
67
+ #
68
+ # @example Load contents from a file.
69
+ # Cnab240::Arquivo::Arquivo.load_from_file(File.open('/tmp/cnab240.txt', 'r'))
70
+ #
71
+ # @param [ IO ] file The I/O interface from which the contents will be read.
72
+ #
73
+ # @return [ Array<Cnab240::Arquivo::Arquivo> ] A list of +Cnab240::Arquivo::Arquivo+ instances representing the contents read.
74
+ #
75
+ # @since 0.0.20
76
+ def self.load(io)
77
+ Cnab240::Builder.new(io).arquivos
78
+ end
79
+
80
+ def auto_fill
81
+ trailer.totais_qtde_lotes = lotes.length.to_s
82
+ qtd_registros = lotes.length * 2 # header e trailer de cada lote
83
+ lotes.each { |l| qtd_registros += l.segmentos.length } # segmentos
84
+ qtd_registros += 2 # header e trailer de arquivo
85
+ trailer.totais_qtde_registros = qtd_registros.to_s
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -1,156 +1,164 @@
1
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 '080'
72
- # arquivos.last.versao = 'V80'
73
- # arquivos.last.header = Cnab240::V80::Arquivo::Header.read(line)
74
- when '085'
75
- arquivos.last.versao = 'V86'
76
- arquivos.last.header = Cnab240::V86::Arquivo::Header.read(line)
77
- when '040'
78
- arquivos.last.versao = 'V40'
79
- arquivos.last.header = Cnab240::V40::Arquivo::Header.read(line)
80
- when '000' # possivelmente V80 do itau
81
- if line[14..16] == '080'
82
- arquivos.last.versao = 'V80'
83
- arquivos.last.header = Cnab240::V80::Arquivo::Header.read(line)
84
- else
85
- raise "Versao de arquivo nao suportado: #{line[RANGE_LAYOUT_ARQUIVO]} na linha #{line_number}" if Cnab240.fallback == false
86
- arquivos.last.versao = 'V86'
87
- arquivos.last.header = Cnab240::V86::Arquivo::Header.read(line)
88
- end
89
- else
90
- raise "Versao de arquivo nao suportado: #{line[RANGE_LAYOUT_ARQUIVO]} na linha #{line_number}" if Cnab240.fallback == false
91
- arquivos.last.versao = 'V86'
92
- arquivos.last.header = Cnab240::V86::Arquivo::Header.read(line)
93
- end
94
- end
95
-
96
- def find_header_lote(line, line_number = -1)
97
- case line[RANGE_HEADER_LOTE]
98
- when '080'
99
- arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none, :versao => 'V80') do |l|
100
- l.header = Cnab240::V80::Pagamentos::Header.read(line)
101
- end
102
- when '030'
103
- case arquivos.last.versao
104
- when 'V80'
105
- arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
106
- l.header = Cnab240::V80::Pagamentos::Header.read(line)
107
- end
108
- when 'V40'
109
- arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
110
- l.header = Cnab240::V40::Pagamentos::Header.read(line)
111
- end
112
- else
113
- raise "Header de lote nao suportado para a versao de arquivo."
114
- end
115
- when '044'
116
- arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
117
- l.header = Cnab240::V86::Pagamentos::Header.read(line)
118
- end
119
- when '040'
120
- case arquivos.last.versao
121
- when 'V80'
122
- arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
123
- l.header = Cnab240::V80::Pagamentos::Header.read(line)
124
- end
125
- when 'V86'
126
- arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento_titulo_cobranca, :tipo => :none) do |l|
127
- l.header = Cnab240::V86::PagamentosTitulos::Header.read(line)
128
- end
129
- else
130
- raise "Header de lote nao suportado para a versao de arquivo."
131
- end
132
- when '011'
133
- arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento_titulo_tributos, :tipo => :none) do |l|
134
- l.header = Cnab240::V86::PagamentosTributos::Header.read(line)
135
- end
136
- else
137
- raise "Tipo de lote nao suportado: #{line[RANGE_HEADER_LOTE]} na linha #{line_number}"
138
- end
139
- end
140
-
141
- def find_segmento(line, line_number = -1)
142
- 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
143
- case line[RANGE_TIPO_OPERACAO_DETALHE]
144
- when 'J'
145
- if line[17..18] == '52'
146
- arquivos.last.lotes.last.read_segmento('J52', line)
147
- else
148
- arquivos.last.lotes.last.read_segmento('J', line)
149
- end
150
- else
151
- arquivos.last.lotes.last.read_segmento(line[RANGE_TIPO_OPERACAO_DETALHE], line)
152
- end
153
- end
154
-
155
- end
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(io = nil)
20
+ load(io) unless io.nil?
21
+ end
22
+
23
+ def load(io)
24
+ @arquivos = []
25
+ line_number = 0
26
+ io.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.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 '087'
72
+ arquivos.last.versao = 'V87'
73
+ arquivos.last.header = Cnab240::V87::Arquivo::Header.read(line)
74
+ when '085'
75
+ arquivos.last.versao = 'V86'
76
+ arquivos.last.header = Cnab240::V86::Arquivo::Header.read(line)
77
+ when '040'
78
+ arquivos.last.versao = 'V40'
79
+ arquivos.last.header = Cnab240::V40::Arquivo::Header.read(line)
80
+ when '000' # possivelmente V80 do itau
81
+ if line[14..16] == '080'
82
+ arquivos.last.versao = 'V80'
83
+ arquivos.last.header = Cnab240::V80::Arquivo::Header.read(line)
84
+ else
85
+ raise "Versao de arquivo nao suportado: #{line[RANGE_LAYOUT_ARQUIVO]} na linha #{line_number}" if Cnab240.fallback == false
86
+ arquivos.last.versao = 'V86'
87
+ arquivos.last.header = Cnab240::V86::Arquivo::Header.read(line)
88
+ end
89
+ else
90
+ raise "Versao de arquivo nao suportado: #{line[RANGE_LAYOUT_ARQUIVO]} na linha #{line_number}" if Cnab240.fallback == false
91
+ arquivos.last.versao = 'V86'
92
+ arquivos.last.header = Cnab240::V86::Arquivo::Header.read(line)
93
+ end
94
+ end
95
+
96
+ def find_header_lote(line, line_number = -1)
97
+ case line[RANGE_HEADER_LOTE]
98
+ when '080'
99
+ arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none, :versao => 'V80') do |l|
100
+ l.header = Cnab240::V80::Pagamentos::Header.read(line)
101
+ end
102
+ when '030'
103
+ case arquivos.last.versao
104
+ when 'V80'
105
+ arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
106
+ l.header = Cnab240::V80::Pagamentos::Header.read(line)
107
+ end
108
+ when 'V40'
109
+ arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
110
+ l.header = Cnab240::V40::Pagamentos::Header.read(line)
111
+ end
112
+ else
113
+ raise "Header de lote nao suportado para a versao de arquivo."
114
+ end
115
+ when '045'
116
+ arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
117
+ l.header = Cnab240::V87::Pagamentos::Header.read(line)
118
+ end
119
+ when '044'
120
+ arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
121
+ l.header = Cnab240::V86::Pagamentos::Header.read(line)
122
+ end
123
+ when '040'
124
+ case arquivos.last.versao
125
+ when 'V80'
126
+ arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento, :tipo => :none) do |l|
127
+ l.header = Cnab240::V80::Pagamentos::Header.read(line)
128
+ end
129
+ when 'V86'
130
+ arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento_titulo_cobranca, :tipo => :none) do |l|
131
+ l.header = Cnab240::V86::PagamentosTitulos::Header.read(line)
132
+ end
133
+ when 'V87'
134
+ arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento_titulo_cobranca, :tipo => :none) do |l|
135
+ l.header = Cnab240::V87::PagamentosTitulos::Header.read(line)
136
+ end
137
+ else
138
+ raise "Header de lote nao suportado para a versao de arquivo."
139
+ end
140
+ when '011'
141
+ arquivos.last.lotes << Cnab240::Lote.new(:operacao => :pagamento_titulo_tributos, :tipo => :none) do |l|
142
+ l.header = Cnab240::V86::PagamentosTributos::Header.read(line)
143
+ end
144
+ else
145
+ raise "Tipo de lote nao suportado: #{line[RANGE_HEADER_LOTE]} na linha #{line_number}"
146
+ end
147
+ end
148
+
149
+ def find_segmento(line, line_number = -1)
150
+ 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
151
+ case line[RANGE_TIPO_OPERACAO_DETALHE]
152
+ when 'J'
153
+ if line[17..18] == '52'
154
+ arquivos.last.lotes.last.read_segmento('J52', line)
155
+ else
156
+ arquivos.last.lotes.last.read_segmento('J', line)
157
+ end
158
+ else
159
+ arquivos.last.lotes.last.read_segmento(line[RANGE_TIPO_OPERACAO_DETALHE], line)
160
+ end
161
+ end
162
+
163
+ end
156
164
  end