bai_parser 1.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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MWQ0ZDFmZDZhODFmODA4OGI5OGFjZWM0M2Y0YzYzYWZlN2RiZWY1ZQ==
5
+ data.tar.gz: !binary |-
6
+ YjkwZWFjZjZjNjNkNTFiY2Q0MTc0ZjQwODkxZjZkM2EyOWIyMGVlOQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NzA4NmZkMWQ5NmEzZTBhNTllOTcyMTQ4MzkzOTk2OGRkZDNmYWM5NGNjNGM4
10
+ YzdjYjExMWJmMTVhYjIzNmQ3NTNkMzdjYzc5N2VmZDE4ZGM1ODUwMzUwZmMy
11
+ YmUzNDcxOWU5ZjU4MjAxOGQwZGY4MTE4YzcxOTE4YWQ0MDM3ZGQ=
12
+ data.tar.gz: !binary |-
13
+ MDZmNDAxMTg5MGQxODdlYmNiZjc3MTlmZmJjMDIyOGIzODc2NDg2ODM2NWRm
14
+ NjE1NWIxMjhjYWVlYjc3OGEzMWU3YjQzYzE5ZGQ2MmFmMTEwODM0MThjOTk2
15
+ NGNhZGNlZTM5YjhhZTk3MmVkZmFjYzVhNDE2OThmOWUxOWRiNzg=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bai_parser.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Sanjiv Patel
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Bai Parser
2
+
3
+ Ruby BAI2 Bank File parser. Takes a bank file as input and outputs the data as a Ruby hash. You can then use a custom writer class to output the data as needed for your purposes.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'bai_parser'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install bai_parser
18
+
19
+ ## Usage
20
+
21
+ ``` ruby
22
+ require "bai_parser"
23
+ data = BAI::Parser.parse "BAI-File-From-Bank.bai"
24
+
25
+ # Then you can use a custom writer to output the data as needed such as to a csv file
26
+ MyCustomBAIWriter.write data
27
+
28
+ # For a quick test to see the parsed data, run the executable against your data file and it will print the data to the screen
29
+ bai_parse bai-file.txt
30
+ ```
31
+
32
+ ## Contributing
33
+
34
+ 1. Fork it
35
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
36
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
37
+ 4. Push to the branch (`git push origin my-new-feature`)
38
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bai_parser/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "bai_parser"
8
+ spec.version = BaiParser::VERSION
9
+ spec.authors = ["Sanjiv Patel"]
10
+ spec.email = ["sanjp2.0@gmail.com"]
11
+ spec.description = %q{Ruby BAI2 Bank File parser}
12
+ spec.summary = %q{Takes a bank file as input and outputs the data as a Ruby hash. You can then use a custom writer class to output the data as needed for your purposes.}
13
+ spec.homepage = "https://github.com/sanjp/bai_parser"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
data/bin/bai_parse ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bai_parser'
4
+ require 'pp'
5
+
6
+ pp BaiParser::Parser.parse ARGV[0]
@@ -0,0 +1,3 @@
1
+ module BaiParser
2
+ VERSION = "1.0.0"
3
+ end
data/lib/bai_parser.rb ADDED
@@ -0,0 +1,154 @@
1
+ require "bai_parser/version"
2
+
3
+ module BaiParser
4
+
5
+ class Parser
6
+
7
+ RECORD_CODES = {'01' => :file_header,
8
+ '02' => :group_header,
9
+ '03' => :account_identifier,
10
+ '16' => :transaction_detail,
11
+ '49' => :account_trailer,
12
+ '88' => :continuation,
13
+ '98' => :group_trailer,
14
+ '99' => :file_trailer }
15
+
16
+ FIELDS = {:file_header => [:record_code,:sender_identification, :receiver_identification, :file_creation_date, :file_creation_time,
17
+ :file_identification_number, :physical_record_length, :block_size, :version_number],
18
+ :group_header => [:record_code,:ultimate_receiver_identification, :originator_identification, :group_status, :as_of_date,
19
+ :as_of_time, :currency_code, :as_of_date_modifier],
20
+ :group_trailer => [:record_code,:group_control_total, :number_of_accounts, :number_of_records],
21
+ :account_trailer => [:record_code,:account_control_total, :number_of_records],
22
+ :file_trailer => [:record_code,:file_control_total, :number_of_groups, :number_of_records]
23
+ }
24
+
25
+ def initialize
26
+ @data = {}
27
+ end
28
+
29
+ def self.parse(filename)
30
+ p = self.new
31
+ p.parse filename
32
+ end
33
+
34
+ def default_record_parse(type, record)
35
+ h = Hash.new
36
+ values = record.split(',')
37
+ FIELDS[type].each do |k|
38
+ h[k] = values.shift
39
+ end
40
+ return h
41
+ end
42
+
43
+ def file_header(record)
44
+ @data[:file_header] = default_record_parse(:file_header, record)
45
+ end
46
+
47
+ def group_header(record)
48
+ @group = Hash.new
49
+ @group[:group_header] = default_record_parse(:group_header, record)
50
+ end
51
+
52
+ def account_identifier(record)
53
+ @account = Hash.new
54
+ h = Hash.new
55
+ h[:record_code], record = next_field record
56
+ h[:customer_account_number], record = next_field record
57
+ h[:currency_code], record = next_field record
58
+ h[:summaries] ||= []
59
+ loop do
60
+ s, record = parse_transaction(record)
61
+ h[:summaries] << s
62
+ break if record == ''
63
+ end
64
+ @account[:account_identifier] = h
65
+ end
66
+
67
+ def parse_transaction(record, detail=false)
68
+ h = Hash.new
69
+ h[:type_code], record = next_field record
70
+ h[:amount], record = next_field record
71
+ unless detail
72
+ h[:item_count], record = next_field record
73
+ end
74
+ h[:funds_type], record = next_field record
75
+ case h[:funds_type]
76
+ when 'S'
77
+ h[:immediate_availability_amount], record = next_field record
78
+ h[:one_day_availability_amount], record = next_field record
79
+ h[:more_than_one_day_availability_amount], record = next_field record
80
+ when 'V'
81
+ h[:value_date], record = next_field record
82
+ h[:value_time], record = next_field record
83
+ when 'D'
84
+ h[:number_of_availability_distributions], record = next_field record
85
+ h[:distributed_availabilties] = []
86
+ h[:number_of_availability_distributions].times do
87
+ days, record = next_field record
88
+ amount, record = next_field record
89
+ if days and amount
90
+ h[:distributed_availabilties] << {availability_in_days: days, availability_amount: amount}
91
+ end
92
+ end
93
+ end
94
+ return [h, record]
95
+ end
96
+
97
+
98
+ def transaction_detail(record)
99
+ t = Hash.new
100
+ t[:record_code], record = next_field record
101
+ h, record = parse_transaction(record, true)
102
+ t.merge! h
103
+ t[:bank_reference_number], record = next_field record
104
+ t[:customer_reference_number], record = next_field record
105
+ t[:text] = record
106
+ (@account[:transactions] ||= []) << t
107
+ end
108
+
109
+ def account_trailer(record)
110
+ @account[:account_trailer] = default_record_parse(:account_trailer, record)
111
+ (@group[:accounts] ||= []) << @account
112
+ end
113
+
114
+ def group_trailer(record)
115
+ @group[:group_trailer] = default_record_parse(:group_trailer, record)
116
+ (@data[:groups] ||= []) << @group
117
+ end
118
+
119
+ def file_trailer(record)
120
+ @data[:file_trailer] = default_record_parse(:file_trailer, record)
121
+ end
122
+
123
+ def next_field(record)
124
+ a, b, c = record.partition(',')
125
+ return [a, c]
126
+ end
127
+
128
+ def parse(filename)
129
+ f = File.open(filename)
130
+ record = next_line = f.gets.chomp
131
+ count = 1
132
+ loop do
133
+ loop do # gather continuation lines
134
+ next_line = f.gets
135
+ break if next_line.nil?
136
+ next_line.chomp!
137
+ count += 1
138
+ if next_line[0..1] == '88'
139
+ record.sub!(/\/\s*$/,',')
140
+ record += next_line[3..-1]
141
+ else
142
+ break
143
+ end
144
+ end
145
+ record.sub!(/\/\s*$/,'')
146
+ self.send RECORD_CODES[record[0..1]], record
147
+ break if next_line.nil?
148
+ record = next_line
149
+ end
150
+ return @data
151
+ end
152
+ end
153
+
154
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bai_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Sanjiv Patel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Ruby BAI2 Bank File parser
42
+ email:
43
+ - sanjp2.0@gmail.com
44
+ executables:
45
+ - bai_parse
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - bai_parser.gemspec
55
+ - bin/bai_parse
56
+ - lib/bai_parser.rb
57
+ - lib/bai_parser/version.rb
58
+ homepage: https://github.com/sanjp/bai_parser
59
+ licenses:
60
+ - MIT
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.2.1
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Takes a bank file as input and outputs the data as a Ruby hash. You can
82
+ then use a custom writer class to output the data as needed for your purposes.
83
+ test_files: []
84
+ has_rdoc: