zilverline-mt940 1.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.
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