zilverline-mt940 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +15 -0
  2. data/.document +5 -0
  3. data/.gitignore +52 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG +56 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +26 -0
  8. data/LICENSE.txt +20 -0
  9. data/README.md +75 -0
  10. data/Rakefile +9 -0
  11. data/lib/mt940.rb +10 -0
  12. data/lib/mt940/bank_statement.rb +13 -0
  13. data/lib/mt940/banks/abnamro.rb +76 -0
  14. data/lib/mt940/banks/ing.rb +84 -0
  15. data/lib/mt940/banks/rabobank.rb +770 -0
  16. data/lib/mt940/banks/triodos.rb +20 -0
  17. data/lib/mt940/base.rb +165 -0
  18. data/lib/mt940/structured_format.rb +16 -0
  19. data/lib/mt940/transaction.rb +23 -0
  20. data/lib/mt940/version.rb +3 -0
  21. data/mt940.gemspec +32 -0
  22. data/spec/fixtures/abnamro.txt +41 -0
  23. data/spec/fixtures/abnamro_structured.txt +54 -0
  24. data/spec/fixtures/ing.txt +24 -0
  25. data/spec/fixtures/ing_structured.txt +31 -0
  26. data/spec/fixtures/rabobank.txt +140 -0
  27. data/spec/fixtures/rabobank_mt940_structured.txt +48 -0
  28. data/spec/fixtures/rabobank_mt940_structured_dutch_tax.txt +10 -0
  29. data/spec/fixtures/rabobank_mt940_structured_multi_line.txt +14 -0
  30. data/spec/fixtures/rabobank_mt940_structured_savings_account.txt +11 -0
  31. data/spec/fixtures/rabobank_mt940_structured_to_savings_account.txt +10 -0
  32. data/spec/fixtures/rabobank_with_debet_previous_balance.txt +6 -0
  33. data/spec/fixtures/triodos.txt +14 -0
  34. data/spec/fixtures/two_accounts.txt +29 -0
  35. data/spec/fixtures/unknown.txt +22 -0
  36. data/spec/mt940_abnamro_spec.rb +244 -0
  37. data/spec/mt940_base_spec.rb +48 -0
  38. data/spec/mt940_ing_spec.rb +227 -0
  39. data/spec/mt940_rabobank_spec.rb +376 -0
  40. data/spec/mt940_triodos_spec.rb +58 -0
  41. data/spec/mt940_two_accounts_spec.rb +49 -0
  42. data/spec/spec_helper.rb +4 -0
  43. metadata +137 -0
@@ -0,0 +1,227 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe "ING" do
4
+
5
+ context 'old mt940' do
6
+ before :each do
7
+ @file_name = File.dirname(__FILE__) + '/fixtures/ing.txt'
8
+ @bank_statements = MT940::Base.parse_mt940(@file_name)["1234567"]
9
+ @transactions = @bank_statements.flat_map(&:transactions)
10
+ @transaction = @transactions.first
11
+ end
12
+
13
+ it 'have the correct number of transactions' do
14
+ @transactions.size.should == 6
15
+ end
16
+
17
+ it 'get the opening balance and date' do
18
+ @bank_statements.first.previous_balance.amount.should == 0
19
+ @bank_statements.first.previous_balance.date.should == Date.new(2010, 7, 22)
20
+ end
21
+
22
+ it 'get the closing balance and date' do
23
+ @bank_statements.last.new_balance.amount.should == 3.47
24
+ @bank_statements.last.new_balance.date.should == Date.new(2010, 7, 23)
25
+ end
26
+
27
+ context 'Transaction' do
28
+
29
+ it 'have a bank_account' do
30
+ @transaction.bank_account.should == '1234567'
31
+ end
32
+
33
+ it 'have an amount' do
34
+ @transaction.amount.should == -25.03
35
+ end
36
+
37
+ it 'have a currency' do
38
+ @transaction.currency.should == 'EUR'
39
+ end
40
+
41
+ it 'have a date' do
42
+ @transaction.date.should == Date.new(2010, 7, 22)
43
+ end
44
+
45
+ it 'return its bank' do
46
+ @transaction.bank.should == 'Ing'
47
+ end
48
+
49
+ it "should return the type" do
50
+ @transaction.type.should == 'Overschrijving'
51
+ end
52
+
53
+ it 'have a description' do
54
+ @transactions.last.description.should == 'EJ46GREENP100610T1456 CLIEOP TMG GPHONGKONG AMSTERDAM'
55
+ end
56
+
57
+ it 'return the contra_account' do
58
+ @transactions.last.contra_account.should == 'NONREF'
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ context 'new mt940' do
66
+
67
+ before :each do
68
+ @file_name = File.dirname(__FILE__) + '/fixtures/ing_structured.txt'
69
+ @bank_statements = MT940::Base.parse_mt940(@file_name)["1234567"]
70
+ @transactions = @bank_statements.flat_map(&:transactions)
71
+ @transaction = @transactions.first
72
+ end
73
+
74
+ it 'has the correct number of transactions' do
75
+ @transactions.size.should == 7
76
+ end
77
+
78
+ it 'get the opening balance and date' do
79
+ @bank_statements.first.previous_balance.amount.should == 500
80
+ @bank_statements.first.previous_balance.date.should == Date.new(2013, 6, 30)
81
+ end
82
+
83
+ it 'get the closing balance and date' do
84
+ @bank_statements.last.new_balance.amount.should == 400
85
+ @bank_statements.last.new_balance.date.should == Date.new(2013, 10, 1)
86
+ end
87
+
88
+ context 'Transaction' do
89
+ before :each do
90
+ @transaction = @transactions[1]
91
+ end
92
+
93
+ it 'have a bank_account' do
94
+ @transaction.bank_account.should == '1234567'
95
+ end
96
+
97
+ it 'have an amount' do
98
+ @transaction.amount.should == 300
99
+ end
100
+
101
+ it 'have a currency' do
102
+ @transaction.currency.should == 'EUR'
103
+ end
104
+
105
+ it 'have a date' do
106
+ @transaction.date.should == Date.new(2013, 7, 1)
107
+ end
108
+
109
+ it 'return its bank' do
110
+ @transaction.bank.should == 'Ing'
111
+ end
112
+
113
+ it "should return the type" do
114
+ @transaction.type.should == 'Overschrijving'
115
+ end
116
+
117
+ it 'have a description' do
118
+ @transaction.description.should == 'VAN Zkl Kwartaal Spaarrekening'
119
+ end
120
+
121
+ it 'return the contra_account' do
122
+ @transaction.contra_account.should == '1234567'
123
+ end
124
+
125
+ end
126
+
127
+ context 'IBAN transaction' do
128
+ before :each do
129
+ @transaction = @transactions[2]
130
+ end
131
+
132
+ it 'have a bank_account' do
133
+ @transaction.bank_account.should == '1234567'
134
+ end
135
+
136
+ it 'have an amount' do
137
+ @transaction.amount.should == -400
138
+ end
139
+
140
+ it 'have a currency' do
141
+ @transaction.currency.should == 'EUR'
142
+ end
143
+
144
+ it 'have a date' do
145
+ @transaction.date.should == Date.new(2013, 7, 1)
146
+ end
147
+
148
+ it 'return its bank' do
149
+ @transaction.bank.should == 'Ing'
150
+ end
151
+
152
+ it "should return the type" do
153
+ @transaction.type.should == 'Internetbankieren'
154
+ end
155
+
156
+ it 'have a description' do
157
+ @transaction.description.should == 'kilometervergoed ing 2e kwartaal 2013'
158
+ end
159
+
160
+ it 'returns the contra_account' do
161
+ @transaction.contra_account.should == '987654321'
162
+ @transaction.contra_account_iban.should == 'NL57ABNA0987654321'
163
+ @transaction.contra_account_owner.should == 'J AAP'
164
+ end
165
+
166
+ end
167
+
168
+ context 'IBAN transaction from tax' do
169
+ before :each do
170
+ @transaction = @transactions[4]
171
+ end
172
+
173
+ it 'have a description' do
174
+ @transaction.description.should == 'BELASTINGDIENST BTW 2e kwartaal 2013 SCOR/CUR/8850426741301240'
175
+ end
176
+
177
+ it 'has an account and iban' do
178
+ @transaction.contra_account.should == '2445588'
179
+ @transaction.contra_account_iban.should == 'NL86INGB0002445588'
180
+ end
181
+
182
+ it 'is unable to parse the contra account owner' do
183
+
184
+ @transaction.contra_account_owner.should be_nil
185
+ end
186
+ end
187
+
188
+ context 'IBAN transaction with EREF NOTPROVIDED' do
189
+ before :each do
190
+ @transaction = @transactions[3]
191
+ end
192
+
193
+ it 'have a description' do
194
+ @transaction.description.should == 'parkeren'
195
+ end
196
+
197
+ it 'has an account and iban' do
198
+ @transaction.contra_account.should == '987654321'
199
+ @transaction.contra_account_iban.should == 'NL57ABNA0987654321'
200
+ end
201
+
202
+ it 'has a contra account owner' do
203
+ @transaction.contra_account_owner.should == 'J AAP / FOO B.V.'
204
+ end
205
+
206
+ end
207
+
208
+ context 'IBAN transaction with EREF' do
209
+ before :each do
210
+ @transaction = @transactions.last
211
+ end
212
+
213
+ it 'have a description' do
214
+ @transaction.description.should == 'J AAP kilometervergoeding 3e kwart aal'
215
+ end
216
+
217
+ it 'has an account and iban' do
218
+ @transaction.contra_account.should == '987654321'
219
+ @transaction.contra_account_iban.should == 'NL57ABNA0987654321'
220
+ end
221
+
222
+ it 'is unable to parse the contra account owner' do
223
+ @transaction.contra_account_owner.should be_nil
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,376 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe "Rabobank" do
4
+
5
+ context "parse whole file" do
6
+ let(:file_name) { File.dirname(__FILE__) + '/fixtures/rabobank.txt' }
7
+ let(:bank_statements) { MT940::Base.parse_mt940(file_name) }
8
+
9
+ it "should have the correct number of bank account's" do
10
+ bank_statements.keys.size.should == 1
11
+ end
12
+
13
+ it "should have the correct number of bank statements per bank account" do
14
+ bank_statements["212121211"].size.should == 23
15
+ end
16
+
17
+ context MT940::BankStatement do
18
+ let(:bank_statements_for_account) { bank_statements["212121211"] }
19
+
20
+ it "should have the correct number of transactions per bank statement" do
21
+ bank_statements_for_account[0].transactions.size.should == 1
22
+ bank_statements_for_account[1].transactions.size.should == 0
23
+ bank_statements_for_account[10].transactions.size.should == 2
24
+ end
25
+
26
+ context "single bank statement" do
27
+ let(:bank_statement) { bank_statements_for_account[0] }
28
+
29
+ it "should have a correct previous balance per statement" do
30
+ balance = bank_statement.previous_balance
31
+ balance.amount.should == 17431.67
32
+ balance.date.should == Date.new(2012, 9, 28)
33
+ balance.currency.should == "EUR"
34
+ end
35
+
36
+ it "should have a correct next balance per statement" do
37
+ balance = bank_statement.new_balance
38
+ balance.amount.should == 17381.67
39
+ balance.date.should == Date.new(2012, 10, 1)
40
+ balance.currency.should == "EUR"
41
+ end
42
+
43
+ it "should have an iban" do
44
+ bank_statement.bank_account_iban.should be_nil
45
+ end
46
+
47
+
48
+ context "debit transaction" do
49
+
50
+ let(:transaction) { bank_statement.transactions.first }
51
+
52
+ it "should have the correct amount" do
53
+ transaction.amount.should == -50
54
+ end
55
+
56
+ it "should have a description" do
57
+ transaction.description.should == "Incasso deposit Savings Account"
58
+ end
59
+
60
+ it "should have an account number" do
61
+ transaction.bank_account.should == "212121211"
62
+ end
63
+
64
+ it "should have a contra account number" do
65
+ transaction.contra_account.should == "1313131319"
66
+ end
67
+
68
+ it "should have a contra account owner" do
69
+ transaction.contra_account_owner.should == "J. DOE"
70
+ end
71
+
72
+ it "should have a bank" do
73
+ transaction.bank.should == "Rabobank"
74
+ end
75
+
76
+ it "should have a currency" do
77
+ transaction.currency.should == "EUR"
78
+ end
79
+
80
+ it "should have a date" do
81
+ transaction.date.should == Date.new(2012, 10, 1)
82
+ end
83
+
84
+ it "should have a type" do
85
+ transaction.type.should == "Machtiging Rabobank"
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
92
+ context "credit transaction" do
93
+ let(:transaction) { bank_statements_for_account[12].transactions[1] }
94
+
95
+ it "should have the correct amount" do
96
+ transaction.amount.should == 12100.00
97
+ end
98
+
99
+ it "should have the correct type" do
100
+ transaction.type.should == "Bijschrijving betaalopdracht"
101
+ end
102
+
103
+ it "should have the correct contra account" do
104
+ transaction.contra_account.should == "987654321"
105
+ end
106
+
107
+ it "should have the correct contra account owner" do
108
+ transaction.contra_account_owner.should == "COMPANY B.V."
109
+ end
110
+
111
+ end
112
+
113
+ context "transaction with a GIRO number" do
114
+ let(:transaction) { bank_statements_for_account[18].transactions.first }
115
+
116
+ it "should have the correct contra account" do
117
+ transaction.contra_account.should == "2445588"
118
+ end
119
+
120
+ it "should have the correct contra account owner" do
121
+ transaction.contra_account_owner.should == "Belastingdienst"
122
+ end
123
+ end
124
+
125
+ context "with a unknown contra account" do
126
+ let(:transaction) { bank_statements_for_account[3].transactions.first }
127
+
128
+ it "should have a NONREF as contra account" do
129
+ transaction.contra_account.should == "NONREF"
130
+ end
131
+
132
+ it "should have a contra account owner" do
133
+ transaction.contra_account_owner.should == "Kosten"
134
+ end
135
+
136
+ it "should have a type" do
137
+ transaction.type.should == "Afschrijving rente provisie kosten"
138
+ end
139
+ end
140
+
141
+ context "multi line description" do
142
+ let(:transaction) { bank_statements_for_account[5].transactions.first }
143
+
144
+ it "should have the correct description" do
145
+ transaction.description.should == "BETALINGSKENM. 490022201282 ARBEIDS ONG. VERZ. 00333333333 PERIODE 06.10.2012 - 06.11.2012"
146
+ end
147
+
148
+ it "should have a type" do
149
+ transaction.type.should == "Doorlopende machtiging algemeen"
150
+ end
151
+ end
152
+ end
153
+
154
+ end
155
+
156
+ context "deposit from savings account" do
157
+ let(:file_name) { File.dirname(__FILE__) + '/fixtures/rabobank_mt940_structured_to_savings_account.txt' }
158
+ let(:bank_statements) { MT940::Base.parse_mt940(file_name) }
159
+
160
+ it "should have the correct contra account number" do
161
+ bank_statement = bank_statements["123456789"][0]
162
+ transaction = bank_statement.transactions.first
163
+ transaction.contra_account.should == "1098765432"
164
+ transaction.contra_account_iban.should == "NL03RABO1098765432"
165
+ end
166
+
167
+ end
168
+
169
+ context "savings account" do
170
+ let(:file_name) { File.dirname(__FILE__) + '/fixtures/rabobank_mt940_structured_savings_account.txt' }
171
+ let(:bank_statements) { MT940::Base.parse_mt940(file_name) }
172
+
173
+ it "should have the correct accountnumber" do
174
+ bank_statements["9123456789"].size.should == 1
175
+ end
176
+
177
+ end
178
+
179
+ context "structured betalingskenmerk" do
180
+ let(:file_name) { File.dirname(__FILE__) + '/fixtures/rabobank_mt940_structured_dutch_tax.txt' }
181
+ let(:bank_statements) { MT940::Base.parse_mt940(file_name) }
182
+
183
+ it "should put a structuted betalingskenmerk in the description" do
184
+ bank_statement = bank_statements["123456789"][0]
185
+ transaction = bank_statement.transactions.first
186
+ transaction.description.should == "BETALINGSKENMERK 1234567899874563"
187
+ end
188
+ end
189
+
190
+ context "structured multiline description" do
191
+ let(:file_name) { File.dirname(__FILE__) + '/fixtures/rabobank_mt940_structured_multi_line.txt' }
192
+ let(:bank_statements) { MT940::Base.parse_mt940(file_name) }
193
+
194
+ it "handles multiline in the description" do
195
+ bank_statement = bank_statements["123456789"][0]
196
+ transaction = bank_statement.transactions.first
197
+ transaction.description.should == "Factuur 2014-002"
198
+ end
199
+
200
+ end
201
+
202
+ context "mt 940 structured" do
203
+ let(:file_name) { File.dirname(__FILE__) + '/fixtures/rabobank_mt940_structured.txt' }
204
+ let(:bank_statements) { MT940::Base.parse_mt940(file_name) }
205
+
206
+ it "should have the correct number of bank account's" do
207
+ bank_statements.keys.size.should == 1
208
+ end
209
+
210
+ it "should have the correct number of bank statements per bank account" do
211
+ bank_statements["123456789"].size.should == 2
212
+ end
213
+
214
+ context MT940::BankStatement do
215
+ let(:bank_statements_for_account) { bank_statements["123456789"] }
216
+
217
+ it "should have the correct number of transactions per bank statement" do
218
+ bank_statements_for_account[0].transactions.size.should == 2
219
+ bank_statements_for_account[1].transactions.size.should == 7
220
+ end
221
+
222
+ context "single bank statement" do
223
+ let(:bank_statement) { bank_statements_for_account[0] }
224
+
225
+ it "should have a correct previous balance per statement" do
226
+ balance = bank_statement.previous_balance
227
+ balance.amount.should == 1147.95
228
+ balance.date.should == Date.new(2013, 4, 2)
229
+ balance.currency.should == "EUR"
230
+ end
231
+
232
+ it "should have a correct next balance per statement" do
233
+ balance = bank_statement.new_balance
234
+ balance.amount.should == 1190.35
235
+ balance.date.should == Date.new(2013, 4, 3)
236
+ balance.currency.should == "EUR"
237
+ end
238
+
239
+ it "should have an iban" do
240
+ bank_statement.bank_account_iban.should == "NL50RABO0123456789"
241
+ end
242
+
243
+ context "debit transaction" do
244
+
245
+ let(:transaction) { bank_statement.transactions.first }
246
+
247
+ it "should have the correct amount" do
248
+ transaction.amount.should == -127.5
249
+ end
250
+
251
+ it "should have a description" do
252
+ transaction.description.should == "674725433 1120000153447185 14144467636004962"
253
+ end
254
+
255
+ it "should have an account number" do
256
+ transaction.bank_account.should == "123456789"
257
+ end
258
+
259
+ it "should have an iban number" do
260
+ transaction.bank_account_iban.should == "NL50RABO0123456789"
261
+ end
262
+
263
+ it "should have a contra account number" do
264
+ transaction.contra_account.should == "523149468"
265
+ end
266
+
267
+ it "should have a contra account iban" do
268
+ transaction.contra_account_iban.should == "NL96RBOS0523149468"
269
+ end
270
+
271
+ it "should have a contra account owner" do
272
+ transaction.contra_account_owner.should == "Nespresso Nederland B.V."
273
+ end
274
+
275
+ it "should have a bank" do
276
+ transaction.bank.should == "Rabobank"
277
+ end
278
+
279
+ it "should have a currency" do
280
+ transaction.currency.should == "EUR"
281
+ end
282
+
283
+ it "should have a date" do
284
+ transaction.date.should == Date.new(2013, 4, 3)
285
+ end
286
+
287
+ it "should have a type" do
288
+ transaction.type.should == "Betaalopdracht iDEAL"
289
+ end
290
+
291
+ end
292
+
293
+ end
294
+
295
+ context "credit transaction" do
296
+ let(:transaction) { bank_statements_for_account[0].transactions[1] }
297
+
298
+ it "should have the correct amount" do
299
+ transaction.amount.should == 169.90
300
+ end
301
+
302
+ it "should have the correct type" do
303
+ transaction.type.should == "Bijschrijving crediteurenbetaling"
304
+ end
305
+
306
+ it "should have the correct contra account" do
307
+ transaction.contra_account.should == "NONREF"
308
+ end
309
+
310
+ it "should have the correct contra account iban" do
311
+ transaction.contra_account_iban.should be_nil
312
+ end
313
+
314
+ it "should have the correct contra account owner" do
315
+ transaction.contra_account_owner.should == "Bedrijf B.V."
316
+ end
317
+
318
+ end
319
+
320
+ context "transaction with a GIRO number" do
321
+ let(:transaction) { bank_statements_for_account[1].transactions.first }
322
+
323
+ it "should have the correct contra account" do
324
+ transaction.contra_account.should == "4500018"
325
+ end
326
+
327
+ it "should have the correct contra account iban" do
328
+ transaction.contra_account_iban.should == "4500018"
329
+ end
330
+
331
+ it "should have the correct contra account owner" do
332
+ transaction.contra_account_owner.should == "DIVV afd parkeergebouwewn"
333
+ end
334
+ end
335
+
336
+ context "with a unknown contra account" do
337
+ let(:transaction) { bank_statements_for_account[1].transactions[3] }
338
+
339
+ it "should have a NONREF as contra account" do
340
+ transaction.contra_account.should == "NONREF"
341
+ end
342
+
343
+ it "should have a nil as contra account iban" do
344
+ transaction.contra_account_iban.should be_nil
345
+ end
346
+
347
+ it "should have a type" do
348
+ transaction.type.should == "Afschrijving rente provisie kosten"
349
+ end
350
+ end
351
+
352
+ context 'without a proper description' do
353
+ let(:transaction) { bank_statements_for_account[1].transactions[4] }
354
+
355
+ it 'should have an empty description' do
356
+ transaction.description.should == ''
357
+ end
358
+ end
359
+
360
+ end
361
+ end
362
+
363
+ it "should be able to handle a debet current balance" do
364
+ debet_file_name = File.dirname(__FILE__) + '/fixtures/rabobank_with_debet_previous_balance.txt'
365
+ bank_statement = MT940::Base.parse_mt940(debet_file_name)["129199348"].first
366
+
367
+ bank_statement.previous_balance.amount.should == -12
368
+ bank_statement.previous_balance.currency.should == "EUR"
369
+ bank_statement.previous_balance.date.should == Date.new(2012, 10, 4)
370
+
371
+ bank_statement.new_balance.amount.should == -12
372
+ bank_statement.new_balance.currency.should == "EUR"
373
+ bank_statement.new_balance.date.should == Date.new(2012, 10, 5)
374
+ end
375
+
376
+ end