mt940_parser 1.0.5 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39104db11a7d233e6d20eb364248aafa38043c40
4
- data.tar.gz: 68fb60ee4af59dd5490736b0fe9906c5ea7d96fe
3
+ metadata.gz: 90c03b829e6f715e6255c89672b49fb07564e6de
4
+ data.tar.gz: 838b67c8f1e8552b2118fe2e224fb24c6f26341e
5
5
  SHA512:
6
- metadata.gz: 6851743254ef137afd2ec83744c73acf7a10f1cd990259ab12f0018f6e870274933d91820ef058ccfde578939d6547249b00186205affc6c32552b4421c34f20
7
- data.tar.gz: 95e73d8a4c876d3484f489edc5985ddceb809c7b2c3ba44ff525e869bf9596c0171ca7a53f739f720e705594d3fc1b7b2f6294eb2f1270b72a70cd3445f8f5ed
6
+ metadata.gz: d062a25b89d4d24d9eaaea209630c4b2cec15b6929e5c17ea35401875c0d87fe89d227b1073c8a82af03402af42a90f4ca60007c00ee7456d7049ab3295a50e2
7
+ data.tar.gz: ff659e396c6f01a5978b27e513b2254bd6e93cf40d10c2bc9fd08bf82a9b00643dacbcddc11f3780eb83349bed90b682af8c971162fd4ac781afd7ad41dc771d
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0-p594
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ rvm:
2
+ - 2.0.0
3
+ - 2.1
4
+ - ruby-head
5
+ - jruby-head
6
+ matrix:
7
+ allow_failures:
8
+ - rvm: ruby-head
9
+ - rvm: jruby-head
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
- ---
1
+ ---
2
2
  :major: 1
3
- :minor: 0
4
- :build:
5
- :patch: 5
3
+ :minor: 2
4
+ :patch: 0
5
+ :build:
@@ -1,5 +1,5 @@
1
1
  # this is a beautification wrapper around the low-level
2
- # MT940.parse command. use it in order to make dealing with
2
+ # MT940.parse command. use it in order to make dealing with
3
3
  # the data easier
4
4
  class MT940
5
5
 
@@ -10,20 +10,19 @@ class MT940
10
10
  def self.parse_file(file)
11
11
  self.parse(File.read(file))
12
12
  end
13
-
13
+
14
14
  def self.parse(data)
15
15
  messages = MT940.parse(data)
16
16
  messages.map { |msg| new(msg) }
17
17
  end
18
-
19
- def initialize(raw_mt940)
20
- @raw = raw_mt940
21
- @account = @raw.find { |line| line.class == MT940::Account }
18
+
19
+ def initialize(lines)
20
+ @account = lines.find { |line| line.class == MT940::Account }
22
21
  @statement_lines = []
23
- @raw.each_with_index do |line, i|
22
+ lines.each_with_index do |line, i|
24
23
  next unless line.class == MT940::StatementLine
25
- ensure_is_info_line!(@raw[i+1])
26
- @statement_lines << StatementLineBundle.new(@raw[i], @raw[i+1])
24
+ ensure_is_info_line!(lines[i+1])
25
+ @statement_lines << StatementLineBundle.new(lines[i], lines[i+1])
27
26
  end
28
27
  end
29
28
 
@@ -35,16 +34,16 @@ class MT940
35
34
  @account.account_number
36
35
  end
37
36
 
38
- private
39
-
37
+ private
38
+
40
39
  def ensure_is_info_line!(line)
41
40
  unless line.is_a?(MT940::StatementLineInformation)
42
- raise StandardError, "Unexpected Structure; expected StatementLineInformation, but was #{line.class}"
41
+ raise StandardError, "Unexpected Structure; expected StatementLineInformation, but was #{line.class}"
43
42
  end
44
43
  end
45
-
44
+
46
45
  end
47
-
46
+
48
47
  class StatementLineBundle
49
48
 
50
49
  METHOD_MAP = {
@@ -71,5 +70,5 @@ class MT940
71
70
  end
72
71
 
73
72
  end
74
-
75
- end
73
+
74
+ end
data/lib/mt940.rb CHANGED
@@ -3,10 +3,10 @@ require 'mt940/customer_statement_message'
3
3
  class MT940
4
4
  class Field
5
5
  attr_reader :modifier, :content
6
-
6
+
7
7
  DATE = /(\d{2})(\d{2})(\d{2})/
8
8
  SHORT_DATE = /(\d{2})(\d{2})/
9
-
9
+
10
10
  class << self
11
11
 
12
12
  def for(line)
@@ -24,16 +24,16 @@ class MT940
24
24
  '65' => FutureValutaBalance,
25
25
  '86' => StatementLineInformation
26
26
  }[number]
27
-
27
+
28
28
  raise StandardError, "Field #{number} is not implemented" unless klass
29
-
29
+
30
30
  klass.new(modifier, content)
31
31
  else
32
32
  raise StandardError, "Wrong line format: #{line.dump}"
33
33
  end
34
34
  end
35
35
  end
36
-
36
+
37
37
  def initialize(modifier, content)
38
38
  @modifier = modifier
39
39
  parse_content(content)
@@ -42,14 +42,14 @@ class MT940
42
42
  private
43
43
  def parse_amount_in_cents(amount)
44
44
  # don't use Integer(amount) function, because amount can be "008" - interpreted as octal number ("010" = 8)
45
- amount.gsub(',', '').to_i
45
+ amount.gsub(',', '').to_i
46
46
  end
47
-
47
+
48
48
  def parse_date(date)
49
49
  date.match(DATE)
50
50
  Date.new("20#{$1}".to_i, $2.to_i, $3.to_i)
51
51
  end
52
-
52
+
53
53
  def parse_entry_date(raw_entry_date, value_date)
54
54
  raw_entry_date.match(SHORT_DATE)
55
55
  entry_date = Date.new(value_date.year, $1.to_i, $2.to_i)
@@ -63,16 +63,16 @@ class MT940
63
63
  # 20
64
64
  class Job < Field
65
65
  attr_reader :reference
66
-
66
+
67
67
  def parse_content(content)
68
68
  @reference = content
69
69
  end
70
70
  end
71
-
71
+
72
72
  # 21
73
73
  class Reference < Job
74
74
  end
75
-
75
+
76
76
  # 25
77
77
  class Account < Field
78
78
  attr_reader :bank_code, :account_number, :account_currency
@@ -84,13 +84,13 @@ class MT940
84
84
  @bank_code, @account_number, @account_currency = $1, $2, $3
85
85
  end
86
86
  end
87
-
87
+
88
88
  # 28
89
89
  class Statement < Field
90
90
  attr_reader :number, :sheet
91
91
 
92
92
  CONTENT = /^(0|(\d{5,5})\/(\d{2,5}))$/
93
-
93
+
94
94
  def parse_content(content)
95
95
  content.match(CONTENT)
96
96
  if $1 == '0'
@@ -100,13 +100,13 @@ class MT940
100
100
  end
101
101
  end
102
102
  end
103
-
103
+
104
104
  # 60
105
105
  class AccountBalance < Field
106
106
  attr_reader :balance_type, :sign, :currency, :amount, :date
107
107
 
108
108
  CONTENT = /^(C|D)(\w{6})(\w{3})(\d{1,12},\d{0,2})$/
109
-
109
+
110
110
  def parse_content(content)
111
111
  content.match(CONTENT)
112
112
 
@@ -116,27 +116,27 @@ class MT940
116
116
  when 'M'
117
117
  :intermediate
118
118
  end
119
-
119
+
120
120
  @sign = case $1
121
121
  when 'C'
122
122
  :credit
123
123
  when 'D'
124
124
  :debit
125
125
  end
126
-
126
+
127
127
  raw_date = $2
128
128
  @currency = $3
129
129
  @amount = parse_amount_in_cents($4)
130
-
130
+
131
131
  @date = case raw_date
132
132
  when 'ALT', '0'
133
133
  nil
134
134
  when DATE
135
- Date.new("20#{$1}".to_i, $2.to_i, $3.to_i)
135
+ Date.new("20#{$1}".to_i, $2.to_i, $3.to_i)
136
136
  end
137
137
  end
138
138
  end
139
-
139
+
140
140
  # 61
141
141
  class StatementLine < Field
142
142
  attr_reader :date, :entry_date, :funds_code, :amount, :swift_code, :reference, :transaction_description
@@ -145,7 +145,7 @@ class MT940
145
145
 
146
146
  def parse_content(content)
147
147
  content.match(CONTENT)
148
-
148
+
149
149
  raw_date = $1
150
150
  raw_entry_date = $2
151
151
  @funds_code = case $3
@@ -158,25 +158,25 @@ class MT940
158
158
  when 'RD'
159
159
  :return_debit
160
160
  end
161
-
161
+
162
162
  @amount = parse_amount_in_cents($4)
163
163
  @swift_code = $5
164
164
  @reference = $6
165
165
  @transaction_description = $7
166
-
166
+
167
167
  @date = parse_date(raw_date)
168
168
  @entry_date = parse_entry_date(raw_entry_date, @date) if raw_entry_date
169
169
  end
170
-
170
+
171
171
  def value_date
172
172
  @date
173
173
  end
174
174
  end
175
-
175
+
176
176
  # 62
177
177
  class ClosingBalance < AccountBalance
178
178
  end
179
-
179
+
180
180
  # 64
181
181
  class ValutaBalance < AccountBalance
182
182
  end
@@ -184,23 +184,23 @@ class MT940
184
184
  # 65
185
185
  class FutureValutaBalance < AccountBalance
186
186
  end
187
-
187
+
188
188
  # 86
189
189
  class StatementLineInformation < Field
190
- attr_reader :code, :transaction_description, :prima_nota, :details, :bank_code, :account_number,
190
+ attr_reader :code, :transaction_description, :prima_nota, :details, :bank_code, :account_number,
191
191
  :account_holder, :text_key_extension, :not_implemented_fields
192
-
192
+
193
193
  def parse_content(content)
194
194
  content.match(/^(\d{3})((.).*)$/)
195
195
  @code = $1.to_i
196
-
196
+
197
197
  details = []
198
198
  account_holder = []
199
199
 
200
200
  if seperator = $3
201
201
  sub_fields = $2.scan(/#{Regexp.escape(seperator)}(\d{2})([^#{Regexp.escape(seperator)}]*)/)
202
-
203
-
202
+
203
+
204
204
  sub_fields.each do |(code, content)|
205
205
  case code.to_i
206
206
  when 0
@@ -225,19 +225,19 @@ class MT940
225
225
  end
226
226
  end
227
227
  end
228
-
228
+
229
229
  @details = details.join("\n")
230
230
  @account_holder = account_holder.join("\n")
231
231
  end
232
232
  end
233
-
233
+
234
234
 
235
235
  class << self
236
236
  def parse(text)
237
237
  raise "Invalid encoding!" unless text.valid_encoding?
238
238
  new_text = text.encode('utf-8').strip
239
239
  new_text << "\r\n" if new_text[-1,1] == '-'
240
- raw_sheets = new_text.split(/^-\r\n/).map { |sheet| sheet.gsub(/\r\n(?!:)/, '') }
240
+ raw_sheets = new_text.split(/^-\s*\r\n/).map { |sheet| sheet.gsub(/\r\n(?!:)/, '') }
241
241
  sheets = raw_sheets.map { |raw_sheet| parse_sheet(raw_sheet) }
242
242
  end
243
243
 
data/mt940_parser.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "mt940_parser"
8
- s.version = "1.0.5"
8
+ s.version = "1.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Thies C. Arntzen", "Phillip Oertel"]
12
- s.date = "2014-02-04"
12
+ s.date = "2015-01-07"
13
13
  s.email = "developers@betterplace.org"
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
@@ -17,7 +17,9 @@ Gem::Specification.new do |s|
17
17
  ]
18
18
  s.files = [
19
19
  ".document",
20
+ ".ruby-version",
20
21
  ".specification",
22
+ ".travis.yml",
21
23
  "Gemfile",
22
24
  "Gemfile.lock",
23
25
  "LICENSE",
@@ -58,11 +60,11 @@ Gem::Specification.new do |s|
58
60
  s.homepage = "http://github.com/betterplace/mt940_parser"
59
61
  s.licenses = ["MIT"]
60
62
  s.require_paths = ["lib"]
61
- s.rubygems_version = "1.8.24"
63
+ s.rubygems_version = "2.0.14"
62
64
  s.summary = "MT940 parses account statements in the SWIFT MT940 format."
63
65
 
64
66
  if s.respond_to? :specification_version then
65
- s.specification_version = 3
67
+ s.specification_version = 4
66
68
 
67
69
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
68
70
  s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
data/test/test_mt940.rb CHANGED
@@ -6,18 +6,9 @@ YAML::ENGINE.yamler = 'psych'
6
6
  # $DEBUG = true
7
7
  class TestMt940 < Test::Unit::TestCase
8
8
 
9
- def read_mt940_data(file)
10
- MT940.parse(IO.read(file))
11
- end
12
-
13
- def writeout(name, data)
14
-
15
- File.open(name, "w") { |f| f.write data }
16
- end
17
-
18
9
  def test_it_should_parse_fixture_files_correctly
19
10
  Dir[File.dirname(__FILE__) + "/fixtures/*.txt"].reject { |f| f =~ /sepa_snippet/ }.each do |file|
20
- data = read_mt940_data(file)
11
+ data = MT940.parse(IO.read(file))
21
12
  generated_structure_file = file.gsub(/.txt$/, ".yml")
22
13
 
23
14
  assert_equal YAML::load_file(generated_structure_file).to_yaml, data.to_yaml
@@ -33,4 +24,4 @@ class TestMt940 < Test::Unit::TestCase
33
24
  end
34
25
  end
35
26
 
36
- end
27
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mt940_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thies C. Arntzen
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-05 00:00:00.000000000 Z
12
+ date: 2015-01-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -62,7 +62,9 @@ extra_rdoc_files:
62
62
  - README.rdoc
63
63
  files:
64
64
  - .document
65
+ - .ruby-version
65
66
  - .specification
67
+ - .travis.yml
66
68
  - Gemfile
67
69
  - Gemfile.lock
68
70
  - LICENSE
@@ -119,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
121
  version: '0'
120
122
  requirements: []
121
123
  rubyforge_project:
122
- rubygems_version: 2.2.1
124
+ rubygems_version: 2.0.14
123
125
  signing_key:
124
126
  specification_version: 4
125
127
  summary: MT940 parses account statements in the SWIFT MT940 format.