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,48 @@
1
+ :940:
2
+ :20:940S130403
3
+ :25:NL50RABO0123456789
4
+ :28C:0
5
+ :60F:C130402EUR000000001147,95
6
+ :61:130403D000000000127,50N102EREF
7
+ NL96RBOS0523149468
8
+ :86:/EREF/02-04-2013 22:56 1120000153447185/BENM//NAME/Nespresso Nede
9
+ rland B.V./REMI/674725433 1120000153447185 14144467636004962
10
+ /ISDT/2013-04-03
11
+ :61:130403C000000000169,90N122NONREF
12
+ 0663616476
13
+ :86:/ORDP//NAME/Bedrijf B.V./REMI/NR.201303-111/11.3.2013
14
+ NR.201303-112/11.3.2013/ISDT/2013-04-03
15
+ :62F:C130403EUR000000001190,35
16
+ :20:940S130404
17
+ :25:NL50RABO0123456789
18
+ :28C:0
19
+ :60F:C130403EUR000000001190,35
20
+ :61:130404D000000000585,60N071NONREF
21
+ P004500018
22
+ :86:/BENM//NAME/DIVV afd parkeergebouwewn/REMI/Factuur 307472/ISDT/20
23
+ 13-04-04
24
+ :61:130404C000000001640,76N127NONREF
25
+ 0117888613
26
+ :86:/ORDP//NAME/DLN CONSULTING/REMI/factuurnummer 201303-128cursus ce
27
+ rtified PO/ISDT/2013-04-04
28
+ :61:130404D000000000674,73N060NONREF
29
+ P004238192
30
+ :86:/BENM//NAME/INFRACOM INTERNET BV/REMI/BETALINGSKENM. 231732INCASS
31
+ O FACTUUR 231732INCASSO 02-04-2013INFRACOM INTERNET BV*ZWOLLE
32
+ /ISDT/2013-04-04
33
+ :61:130401D000000000130,29N093NONREF
34
+ :86:/REMI/KostenPeriode 01-01-2013 t/m 31-03-2013/ISDT/2013-04-01
35
+ :61:130404C000000002050,95N122NONREF
36
+ 0691765731
37
+ :86:/ORDP//NAME/Wehkamp BV
38
+ 04
39
+ :61:130404C000000001923,90N541EREF
40
+ NL82RBOS0602069890
41
+ :86:/EREF/1134027115/ORDP//NAME/BEDRIJF NV/ADDR/STRAATWEG 68 123
42
+ 2 AA AMSTERDAM THE NETHERLANDS NL/REMI/Ref: 201302-080/ISDT/2013-04-
43
+ 04
44
+ :61:130404C000000013431,00N122NONREF
45
+ 0477502946
46
+ :86:/ORDP//NAME/EVEREST BV/REMI/12420/20001512 201303-088 XX201303-08
47
+ 8XX ZILVERLINE TRAINING1098 TW AMSTERDAM/ISDT/2013-04-04
48
+ :62F:C130404EUR000000018846,34
@@ -0,0 +1,10 @@
1
+ :940:
2
+ :20:940S130403
3
+ :25:NL50RABO0123456789
4
+ :28C:0
5
+ :60F:C130402EUR000000005000,00
6
+ :61:131227D000000002000,00N086EREF
7
+ NL86INGB0002445588
8
+ :86:/EREF/123456789/BENM//NAME/Belastingdienst/REMI//CDTRREFTP//CD/SC
9
+ OR/ISSR/CUR/CDTRREF/1234567899874563/ISDT/2013-12-27
10
+ :62F:C131227EUR000000003000,00
@@ -0,0 +1,14 @@
1
+ :940:
2
+ :20:940S130403
3
+ :25:NL50RABO0123456789
4
+ :28C:0
5
+ :60F:C130402EUR000000005000,00
6
+ :61:140303D000000000100,00N544EREF
7
+ NL12INGB0987654321
8
+ :86:/EREF/195937094/BENM//NAME/abcdefghijklmno abcdef/REMI/Factuur 20
9
+ 14-002/ISDT/2014-03-03
10
+ :61:140303D000000000000,01N544EREF
11
+ NL12INGB0987654321
12
+ :86:/EREF/195937094/BENM//NAME/abcdefghijklmno abcdef/REMI/Factuur 20
13
+ 14-002/ISDT/2014-03-03
14
+ :62F:C130403EUR000000005100,00
@@ -0,0 +1,11 @@
1
+ :940:
2
+ :20:940S130403
3
+ :25:NL50RABO9123456789
4
+ :28C:0
5
+ :60F:C130402EUR000000000000,00
6
+ :61:130403C000000000100,00N102EREF
7
+ NL96RBOS0523149468
8
+ :86:/EREF/02-04-2013 22:56 1120000153447185/BENM//NAME/Nespresso Nede
9
+ rland B.V./REMI/674725433 1120000153447185 14144467636004962
10
+ /ISDT/2013-04-03
11
+ :62F:C130403EUR00000000100,00
@@ -0,0 +1,10 @@
1
+ :940:
2
+ :20:940S130403
3
+ :25:NL50RABO0123456789
4
+ :28C:0
5
+ :60F:C130402EUR000000001000,00
6
+ :61:130403C000000000100,00N690NONREF
7
+ NL03RABO1098765432
8
+ :86:/ORDP//NAME/J AAP B.V./REMI/xxxx xxxxxxxx yyyyyyyyy
9
+ /ISDT/2013-12-05
10
+ :62F:C130404EUR000000001100,00
@@ -0,0 +1,6 @@
1
+ :940:
2
+ :20:940A121005
3
+ :25:1291.99.348EUR
4
+ :28:00000/00
5
+ :60F:D121004EUR000000000012,00
6
+ :62F:D121005EUR000000000012,00
@@ -0,0 +1,14 @@
1
+ :20:1308728725026/1
2
+ :25:TRIODOSBANK/0390123456
3
+ :28:1
4
+ :60F:C110101EUR4975,09
5
+ :61:110101D15,70N000NONREF
6
+ :86:000>100987654321
7
+ >20ALGEMENE TUSSENREKENING KOS>21TEN VAN 01-10-2010 TOT EN M
8
+ >22ET 31-12-2010>310390123456
9
+ :61:110125D700,00N000NONREF
10
+ :86:000>100133967858
11
+ >20 HUUR>21 KANTOOR - FEB 2010
12
+ :62F:C110201EUR4370,79
13
+ -
14
+
@@ -0,0 +1,29 @@
1
+ :940:
2
+ :20:940A120918
3
+ :25:1567.50.961EUR
4
+ :28:00000/00
5
+ :60F:C120917EUR000000009265,12
6
+ :61:120918D000000006098,75N084P002445588 Belastingdienst Apeldoor
7
+ :86:BETALINGSKENM. 0189827218201120
8
+ :61:120918D000000000500,00N0620266050522 Arvato Fin Serv Ltd
9
+ :86:BETALINGSKENM. 3010675705
10
+ :86:GOOGLE GOOG6291713437
11
+ :86:1402786401
12
+ :62F:C120918EUR000000002666,37
13
+ :20:940A121024
14
+ :25:9914.30.727EUR
15
+ :28:00000/00
16
+ :60F:C121023EUR000000000352,84
17
+ :62F:C121024EUR000000000352,84
18
+ :20:940A121101
19
+ :25:3462.483.153 EUR
20
+ :28:00000/00
21
+ :60F:C121101EUR000000005000,00
22
+ :62F:C121101EUR000000005000,00
23
+ :20:940A121029
24
+ :25:1325.76.155EUR
25
+ :28:00000/00
26
+ :60F:D121026EUR000000000012,00
27
+ :61:121028C000000000250,00N6990156750961 ZILVERLINE B.V. /FREEMLE
28
+ :86:Saldo aanvullen
29
+ :62F:C121029EUR000000000238,00
@@ -0,0 +1,22 @@
1
+ 940 00
2
+ :20:MPBZ
3
+ :25:0001234567
4
+ :28C:000
5
+ :60F:C100722EUR0,00
6
+ :61:100722D25,03NOV NONREF
7
+ :86: RC AFREKENING BETALINGSVERKEER
8
+ BETREFT REKENING 4715589 PERIODE: 01-10-2010 / 31-12-2010
9
+ ING Bank N.V. tarifering ING
10
+ :61:100722D3,03NOV NONREF
11
+ :86:0111111111 GPSEOUL SPOEDBETALING MPBZS1016000047 GPSEOUL
12
+ :61:100722D1,11NGT TMG TANGO
13
+ :86:0111111111 ING iDEAL KN: TMG TANGO TRANSACTIENR 0050000534527978 10­06­2010 15:32 TMG TANGO ING Bank inzake GPKyoto
14
+ :61:100722D20,00NGM NONREF
15
+ :86: ABN AMRO BANK>AMSTERDAM 22­07­2010 09:57 002 5595781
16
+ :61:100722D1,10NGT NONREF
17
+ :86:0111111111 GPPeking 170000001AC
18
+ :61:100722C3,68NVZ NONREF
19
+ :86:0111111111 EJ46GREENP100610T1456 CLIEOP TMG GPHONGKONG AMSTERDAM
20
+ :62F:C100723EUR3,47
21
+ :86:D000004C000002D25,24C28,71
22
+ -XXX
@@ -0,0 +1,244 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe "MT940::Base" do
4
+
5
+ context 'classis mt940' do
6
+ before :each do
7
+ @file_name = File.dirname(__FILE__) + '/fixtures/abnamro.txt'
8
+ @bank_statements = MT940::Base.parse_mt940(@file_name)["517852257"]
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 == 10
15
+ end
16
+
17
+ it 'get the opening balance and date' do
18
+ @bank_statements.first.previous_balance.amount.should == 3236.28
19
+ @bank_statements.first.previous_balance.date.should == Date.new(2011, 5, 22)
20
+ end
21
+
22
+ it 'get the closing balance and date' do
23
+ @bank_statements.last.new_balance.amount.should == 1849.75
24
+ @bank_statements.last.new_balance.date.should == Date.new(2011, 5, 24)
25
+ end
26
+
27
+ context 'Transaction' do
28
+
29
+ it 'have a bank_account' do
30
+ @transaction.bank_account.should == '517852257'
31
+ end
32
+
33
+ it 'have an amount' do
34
+ @transaction.amount.should == -9.00
35
+ end
36
+
37
+ context 'Description' do
38
+ it 'have the correct description in case of a GIRO account' do
39
+ @transaction.description.should == 'KPN - DIGITENNE BETALINGSKENM. 000000042188659 5314606715 BETREFT FACTUUR D.D. 20-05-2011 INCL. 1,44 BTW'
40
+ end
41
+
42
+ it 'have the correct description in case of a regular bank' do
43
+ @transactions.last.description.should == 'MYCOM DEN HAAG S-GRAVEN,PAS999'
44
+ end
45
+ end
46
+
47
+ it 'have a date' do
48
+ @transaction.date.should == Date.new(2011, 5, 24)
49
+ end
50
+
51
+ it 'return its bank' do
52
+ @transaction.bank.should == 'Abnamro'
53
+ end
54
+
55
+ it 'have a currency' do
56
+ @transaction.currency.should == 'EUR'
57
+ end
58
+
59
+ context 'Contra account' do
60
+ it 'be determined in case of a GIRO account' do
61
+ @transaction.contra_account.should == '000428428'
62
+ end
63
+
64
+ it 'be determined in case of a regular bank' do
65
+ @transactions.last.contra_account.should == '528939882'
66
+ end
67
+ end
68
+ end
69
+ end
70
+ context 'sepa mt940' do
71
+ before :each do
72
+ @file_name = File.dirname(__FILE__) + '/fixtures/abnamro_structured.txt'
73
+ @bank_statements = MT940::Base.parse_mt940(@file_name)["123212321"]
74
+ @transactions = @bank_statements.flat_map(&:transactions)
75
+ end
76
+
77
+ it 'have the correct number of transactions' do
78
+ @transactions.size.should == 10
79
+ end
80
+
81
+ it 'get the opening balance and date' do
82
+ @bank_statements.first.previous_balance.amount.should == 10000.9
83
+ @bank_statements.first.previous_balance.date.should == Date.new(2014, 1, 12)
84
+ end
85
+
86
+ it 'get the closing balance and date' do
87
+ @bank_statements.last.new_balance.amount.should == 3976.9
88
+ @bank_statements.last.new_balance.date.should == Date.new(2014, 1, 27)
89
+ end
90
+
91
+ context 'Transaction' do
92
+
93
+ let(:transaction) { @transactions[1] }
94
+
95
+ it 'have a bank_account' do
96
+ transaction.bank_account.should == '123212321'
97
+ end
98
+
99
+ it 'have an amount' do
100
+ transaction.amount.should == -10
101
+ end
102
+
103
+ it 'have the correct description in case of a regular bank' do
104
+ transaction.description.should == 'BEA NR:NND130 13.01.14/11.00 XXXXX 99 XXXXXX BV AMSTE,PAS123'
105
+ end
106
+
107
+ it 'have a date' do
108
+ transaction.date.should == Date.new(2014, 1, 13)
109
+ end
110
+
111
+ it 'return its bank' do
112
+ transaction.bank.should == 'Abnamro'
113
+ end
114
+
115
+ it 'have a currency' do
116
+ transaction.currency.should == 'EUR'
117
+ end
118
+
119
+ end
120
+
121
+ context 'sepa overboeking' do
122
+
123
+ let(:transaction) { @transactions[2] }
124
+
125
+ it 'have a bank_account' do
126
+ transaction.bank_account.should == '123212321'
127
+ end
128
+
129
+ it 'have an amount' do
130
+ transaction.amount.should == -10
131
+ end
132
+
133
+ it 'have the correct description in case of a regular bank' do
134
+ transaction.description.should == "SAVINGS 3798473"
135
+ end
136
+
137
+ it 'have a date' do
138
+ transaction.date.should == Date.new(2014, 1, 13)
139
+ end
140
+
141
+ it 'return its bank' do
142
+ transaction.bank.should == 'Abnamro'
143
+ end
144
+
145
+ it 'have a currency' do
146
+ transaction.currency.should == 'EUR'
147
+ end
148
+
149
+ it 'has a contra account' do
150
+ transaction.contra_account.should == '987654321'
151
+ end
152
+
153
+ it 'has a contra account iban' do
154
+ transaction.contra_account_iban.should == 'NL25ABNA0987654321'
155
+ end
156
+
157
+ it 'has a contra account owner' do
158
+ transaction.contra_account_owner.should == 'FOOBAR'
159
+ end
160
+ end
161
+
162
+ context 'sepa ideal' do
163
+ let(:transaction) { @transactions[3] }
164
+
165
+ it 'have a bank_account' do
166
+ transaction.bank_account.should == '123212321'
167
+ end
168
+
169
+ it 'have an amount' do
170
+ transaction.amount.should == -4
171
+ end
172
+
173
+ it 'have the correct description in case of a regular bank' do
174
+ transaction.description.should == %Q{4851430136 0030000 735822580 NS E-TICKET(S)KENMERK: 26-01-2014 18:14 003000 0735822580}
175
+ end
176
+
177
+ it 'have a date' do
178
+ transaction.date.should == Date.new(2014, 1, 26)
179
+ end
180
+
181
+ it 'return its bank' do
182
+ transaction.bank.should == 'Abnamro'
183
+ end
184
+
185
+ it 'have a currency' do
186
+ transaction.currency.should == 'EUR'
187
+ end
188
+
189
+ it 'has a contra account' do
190
+ transaction.contra_account.should == '888888888'
191
+ end
192
+
193
+ it 'has a contra account iban' do
194
+ transaction.contra_account_iban.should == 'NL70ABNA0888888888'
195
+ end
196
+
197
+ it 'has a contra account owner' do
198
+ transaction.contra_account_owner.should == 'NS GROEP INZAKE NSR IDEA'
199
+ end
200
+
201
+ end
202
+
203
+ context 'SEPA ACCEPTGIROBETALING' do
204
+ let(:transaction) { @transactions[5] }
205
+
206
+ it 'have a bank_account' do
207
+ transaction.bank_account.should == '123212321'
208
+ end
209
+
210
+ it 'have an amount' do
211
+ transaction.amount.should == -1000
212
+ end
213
+
214
+ it 'have the correct description in case of a regular bank' do
215
+ transaction.description.should == %Q{BETALINGSKENM.: 1234567890098876 ID DEBITEUR: 777777777}
216
+ end
217
+
218
+ it 'have a date' do
219
+ transaction.date.should == Date.new(2014, 1, 26)
220
+ end
221
+
222
+ it 'return its bank' do
223
+ transaction.bank.should == 'Abnamro'
224
+ end
225
+
226
+ it 'have a currency' do
227
+ transaction.currency.should == 'EUR'
228
+ end
229
+
230
+ it 'has a contra account' do
231
+ transaction.contra_account.should == '2445588'
232
+ end
233
+
234
+ it 'has a contra account iban' do
235
+ transaction.contra_account_iban.should == 'NL86INGB0002445588'
236
+ end
237
+
238
+ it 'has a contra account owner' do
239
+ transaction.contra_account_owner.should == 'BELASTINGDIENST'
240
+ end
241
+
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,48 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe "Base" do
4
+
5
+ context 'MT940::Base' do
6
+ it 'read the transactions with the filename of the MT940 file' do
7
+ file_name = File.dirname(__FILE__) + '/fixtures/ing.txt'
8
+ @transactions = MT940::Base.parse_mt940(file_name)["1234567"].flat_map(&:transactions)
9
+ @transactions.size.should == 6
10
+ end
11
+
12
+ it 'read the transactions with the handle to the mt940 file itself' do
13
+ file_name = File.dirname(__FILE__) + '/fixtures/ing.txt'
14
+ file = File.open(file_name)
15
+ @transactions = MT940::Base.parse_mt940(file)["1234567"].flat_map(&:transactions)
16
+ @transactions.size.should == 6
17
+ end
18
+
19
+ #Tempfile is used by Paperclip, so the following will work:
20
+ #MT940::Base.transactions(@mt940_file.attachment.to_file)
21
+ it 'read the transactions with the handle of a Tempfile' do
22
+ file = Tempfile.new('temp')
23
+ file.write(':940:')
24
+ file.rewind
25
+ @transactions = MT940::Base.parse_mt940(file)
26
+ @transactions.size.should == 0
27
+ file.unlink
28
+ end
29
+
30
+ it 'raise an exception if the file does not exist' do
31
+ file_name = File.dirname(__FILE__) + '/fixtures/123.txt'
32
+ expect {MT940::Base.parse_mt940(file_name)}.to raise_exception Errno::ENOENT
33
+ end
34
+
35
+ it 'raise an ArgumentError if a wrong argument was given' do
36
+ expect {MT940::Base.parse_mt940(Hash.new)}.to raise_exception ArgumentError
37
+ end
38
+ end
39
+
40
+ context 'Unknown MT940 file' do
41
+ it 'return its bank' do
42
+ file_name = File.dirname(__FILE__) + '/fixtures/unknown.txt'
43
+ @transactions = MT940::Base.parse_mt940(file_name)["1234567"].flat_map(&:transactions)
44
+ @transactions.first.bank.should == 'Unknown'
45
+ end
46
+ end
47
+
48
+ end