cmxl 2.0 → 2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c172d6b56767a8860f57c4b802c7ed2ed2bae3658f6db104f44795a377bf067
4
- data.tar.gz: ececb262e0d6a40c97e7ca54dcac08208e1942792c5f493be179ba3c81ece6b7
3
+ metadata.gz: c6114278dc458c8f3890f6f04e72a33915c98f235fe0694ba8d7b02cc5f394d6
4
+ data.tar.gz: d47ca765f53acf8f86d9c51b25123975174fc83c86cc68b834f069606ecd8cd4
5
5
  SHA512:
6
- metadata.gz: f0f673453d6bbbc39313ed7ae86ff574c4c9d60a0ea5543283f38d1f3bf4f7477625e2bc87a1fbdc62714c86461735a7e16796edd54cd361d52d49d2eb05d8db
7
- data.tar.gz: a197094a3ccd4235f8811a456dbd54c43bc3b49a47062a72f7b9ee53610ddbb4e79ce97e53e0f90670a0c5e3cb5f08ef490792506dc6cc1202d5442c4f724710
6
+ metadata.gz: 9ac2f348609babd4cca9df8da0412f965057fed77d210e155f076c489d407541effd6da7012b00ff48f642baec2ae96b028bad0720f08ff50c4f2327d34dc7bf
7
+ data.tar.gz: cfae7ffcf5ffe4ee50b2afac7828f712a9511e5e1da6493a17a7d94681094fee7729b2687ee5a9fdc9bad7e031778841ed8cda3db44c6741a6810c54f736d25a
@@ -2,9 +2,9 @@ name: CI
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [master]
5
+ branches: [main]
6
6
  pull_request:
7
- branches: [master]
7
+ branches: [main]
8
8
 
9
9
  jobs:
10
10
  test:
@@ -13,6 +13,7 @@ jobs:
13
13
  strategy:
14
14
  matrix:
15
15
  ruby-version:
16
+ - 3.4
16
17
  - 3.3
17
18
  - 3.2
18
19
  - 3.1
data/.rspec CHANGED
@@ -1 +1,2 @@
1
- --color
1
+ --color
2
+ --require 'pry'
data/CHANGELOG.mdown CHANGED
@@ -1,5 +1,11 @@
1
1
  # NEXT release
2
2
 
3
+ # 2.1
4
+ - `[REFACTOR]` improve file parser to work with windows line breaks and any known header formats
5
+ - `[BUGFIX]` fix `strip_header` making it work on statements without headers
6
+ - `[HOUSEKEEPING]` use `main` instead of `master` as default branch
7
+ - `[ENHANCEMENT]` add support for ruby `3.4`
8
+
3
9
  # 2.0
4
10
  - `[REFACTOR]` **DEPRECATED:** `storno?` and related methods `storno_credit`, `storno_debit`. Use `reversal?` and related methods `reversal_credit?`, `reversal_debit?` instead
5
11
  - `[BUGFIX]` **DEPRECATED:** `funds_code` method returns the `credit_debit_indicator` from the SWIFT definition. Therefore the method is deprecated in favor of `credit_debit_indicator` method
data/README.md CHANGED
@@ -62,7 +62,7 @@ statements.each do |s|
62
62
  puts s.generation_date
63
63
  puts s.opening_balance.amount
64
64
  puts s.closing_balance.amount
65
- puts s.sha # SHA of the statement source - could be used as an identifier (see: https://github.com/railslove/cmxl/blob/master/lib/cmxl/statement.rb#L49-L55)
65
+ puts s.sha # SHA of the statement source - could be used as an identifier (see: https://github.com/railslove/cmxl/blob/main/lib/cmxl/statement.rb#L49-L55)
66
66
 
67
67
  s.transactions.each do |t|
68
68
  puts t.information
@@ -41,8 +41,8 @@ module Cmxl
41
41
  end
42
42
 
43
43
  def strip_headers!
44
- source.gsub!(/\A.+?(?=^:)/m, '') # beginning: strip every line in the beginning that does not start with a :
45
- source.gsub!(/^[^:]+\z/, '') # end: strip every line in the end that does not start with a :
44
+ source.gsub!(/\A.*?(?=^:)/m, '') # beginning: strip every line in the beginning that does not start with a :
45
+ source.gsub!(/^[^:]*\z/, '') # end: strip every line in the end that does not start with a :
46
46
  source.strip!
47
47
  end
48
48
 
data/lib/cmxl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cmxl
2
- VERSION = '2.0'.freeze
2
+ VERSION = '2.1'.freeze
3
3
  end
data/lib/cmxl.rb CHANGED
@@ -11,7 +11,11 @@ module Cmxl
11
11
  @config
12
12
  end
13
13
  @config = {
14
- statement_separator: /\n-\s*\n/m,
14
+ # One or more newlines
15
+ # followed by `-` at the beginning of a line.
16
+ # "Eats up" but does not require characters until the end of the line and more newlines.
17
+ # \R is a platform independent newline but in the negated group `[^\n\r]` that did not seem to work.
18
+ statement_separator: /\R+-[^\n\r]*\R*/m,
15
19
  raise_line_format_errors: true,
16
20
  strip_headers: false
17
21
  }
@@ -0,0 +1,44 @@
1
+ ABNANL2A
2
+ 940
3
+ ABNANL2A
4
+ :20:ABN AMRO BANK NV
5
+ :25:517852257
6
+ :28:19321/1
7
+ :60F:C110522EUR3236,28
8
+ :61:1105240524D9,N192NONREF
9
+ :86:GIRO 428428 KPN - DIGITENNE BETALINGSKENM. 000000042188659
10
+ 5314606715 BETREFT FACTUUR D.D. 20-05-2011
11
+ INCL. 1,44 BTW
12
+ :61:1105210523D11,59N426NONREF
13
+ :86:BEA NR:XXX1234 21.05.11/12.54 DIRCKIII FIL2500 KATWIJK,PAS999
14
+ :61:1105230523D11,63N426NONREF
15
+ :86:BEA NR:XXX1234 23.05.11/09.08 DIGROS FIL1015 KATWIJK Z,PAS999
16
+ :61:1105220523D11,8N426NONREF
17
+ :86:BEA NR:XXX1234 22.05.11/14.25 MC DONALDS A44 LEIDEN,PAS999
18
+ :61:1105210523D13,45N426NONREF
19
+ :86:BEA NR:XXX1234 21.05.11/12.09 PRINCE FIL. 55 KATWIJK Z,PAS999
20
+ :61:1105210523D15,49N426NONREF
21
+ :86:BEA NR:XXX1234 21.05.11/12.55 DIRX FIL6017 KATWIJK ZH ,PAS999
22
+
23
+ :61:1105210523D107,N426NONREF
24
+ :86:BEA NR:XXX1234 21.05.11/12.04 HANS ANDERS OPT./056 KAT,PAS999
25
+ :61:1105220523D141,48N426NONREF
26
+ :86:BEA NR:XXX1234 22.05.11/13.45 MYCOM DEN HAAG S-GRAVEN,PAS999
27
+ :62F:C110523EUR876,84
28
+
29
+ -
30
+
31
+ ABNANL2A
32
+ 940
33
+ ABNANL2A
34
+ :20:ABN AMRO BANK NV
35
+ :25:517852257
36
+ :28:19322/1
37
+ :60F:C110523EUR2876,84
38
+ :61:1105240524D9,49N426NONREF
39
+ :86:BEA NR:XXX1234 24.05.11/09.18 PETS PLACE KATWIJK KATWI,PAS999
40
+ :61:1105240524D15,N426NONREF
41
+ :86:52.89.39.882 MYCOM DEN HAAG S-GRAVEN,PAS999
42
+ :62F:C110524EUR1849,75
43
+
44
+ -
@@ -0,0 +1,16 @@
1
+ ä4:
2
+ :20:5566778899100112
3
+ :25:10020030/1234567
4
+ :28C:188/1
5
+ :60F:C130928SEK0,
6
+ :62F:C130930SEK0,
7
+ :64:C130930SEK0,
8
+
9
+ ä4:
10
+ :20:5566778899100169
11
+ :25:10020030/1234567
12
+ :28C:188/1
13
+ :60F:C130928SEK0,
14
+ :62F:C130930SEK0,
15
+ :64:C130930SEK0,
16
+
@@ -0,0 +1,16 @@
1
+ {1:D02AASDISLNETAXXXXXXXXXXXXX}
2
+ {2:E623XXXXXXXXAXXXN}
3
+ {4:
4
+ :20:1234567
5
+ :21:9876543210
6
+ :25:10020030/1234567
7
+ :28C:5/1
8
+ :60F:C160314EUR2187,95
9
+ :61:0211011102DR800,NSTONONREF//55555
10
+ :86:008?00DAUERAUFTRAG?100599?20Miete November?3010020030?31234567?32MUELLER?34339
11
+ :61:0211021102CR3000,NTRFNONREF//55555
12
+ :86:051?00UEBERWEISUNG?100599?20Gehalt Oktober?21Firma
13
+ Mustermann GmbH?3050060400?310847564700?32MUELLER?34339
14
+ :62F:C160315EUR4387,95
15
+ :86:Some random data
16
+ -}
@@ -95,4 +95,115 @@ describe 'parsing a statement' do
95
95
  expect(subject[0].transactions.count).to eql(1)
96
96
  end
97
97
  end
98
+
99
+ describe "MT940 abnamro" do
100
+ it "splits the file into on statement with the headers included" do
101
+ expected_data = <<~MT940.chomp
102
+ ABNANL2A
103
+ 940
104
+ ABNANL2A
105
+ :20:ABN AMRO BANK NV
106
+ :25:517852257
107
+ :28:19321/1
108
+ :60F:C110522EUR3236,28
109
+ :61:1105240524D9,N192NONREF
110
+ :86:GIRO 428428 KPN - DIGITENNE BETALINGSKENM. 000000042188659
111
+ 5314606715 BETREFT FACTUUR D.D. 20-05-2011
112
+ INCL. 1,44 BTW
113
+ :61:1105210523D11,59N426NONREF
114
+ :86:BEA NR:XXX1234 21.05.11/12.54 DIRCKIII FIL2500 KATWIJK,PAS999
115
+ :61:1105230523D11,63N426NONREF
116
+ :86:BEA NR:XXX1234 23.05.11/09.08 DIGROS FIL1015 KATWIJK Z,PAS999
117
+ :61:1105220523D11,8N426NONREF
118
+ :86:BEA NR:XXX1234 22.05.11/14.25 MC DONALDS A44 LEIDEN,PAS999
119
+ :61:1105210523D13,45N426NONREF
120
+ :86:BEA NR:XXX1234 21.05.11/12.09 PRINCE FIL. 55 KATWIJK Z,PAS999
121
+ :61:1105210523D15,49N426NONREF
122
+ :86:BEA NR:XXX1234 21.05.11/12.55 DIRX FIL6017 KATWIJK ZH ,PAS999
123
+
124
+ :61:1105210523D107,N426NONREF
125
+ :86:BEA NR:XXX1234 21.05.11/12.04 HANS ANDERS OPT./056 KAT,PAS999
126
+ :61:1105220523D141,48N426NONREF
127
+ :86:BEA NR:XXX1234 22.05.11/13.45 MYCOM DEN HAAG S-GRAVEN,PAS999
128
+ :62F:C110523EUR876,84
129
+ MT940
130
+ stub = instance_double(Cmxl::Statement)
131
+ allow(Cmxl::Statement).to receive(:new).and_return(stub)
132
+
133
+ Cmxl.parse(mt940_file('mt940-abnamro'))
134
+
135
+ expect(Cmxl::Statement).to have_received(:new).with(expected_data)
136
+ end
137
+
138
+ it 'splits the file into two statements' do
139
+ allow(Cmxl::Statement).to receive(:new)
140
+
141
+ Cmxl.parse(mt940_file('mt940-abnamro'))
142
+
143
+ expect(Cmxl::Statement).to have_received(:new).twice
144
+ end
145
+ end
146
+
147
+ describe 'MT940 handelsbank' do
148
+ it 'splits the file with the special characters correctly' do
149
+ expected_data = <<~MT940.chomp
150
+ 채4:
151
+ :20:5566778899100112
152
+ :25:10020030/1234567
153
+ :28C:188/1
154
+ :60F:C130928SEK0,
155
+ :62F:C130930SEK0,
156
+ :64:C130930SEK0,
157
+ MT940
158
+ stub = instance_double(Cmxl::Statement)
159
+ allow(Cmxl::Statement).to receive(:new).and_return(stub)
160
+
161
+ Cmxl.parse(mt940_file('mt940-handelsbank'))
162
+
163
+ expect(Cmxl::Statement).to have_received(:new).with(expected_data)
164
+ end
165
+
166
+ it 'splits the file into two statements' do
167
+ allow(Cmxl::Statement).to receive(:new)
168
+
169
+ Cmxl.parse(mt940_file('mt940-handelsbank'))
170
+
171
+ expect(Cmxl::Statement).to have_received(:new).twice
172
+ end
173
+ end
174
+
175
+ describe "MT940 windows line breaks" do
176
+ it 'splits the file with the special characters correctly' do
177
+ expected_data =
178
+ "{1:D02AASDISLNETAXXXXXXXXXXXXX}\r\n"\
179
+ "{2:E623XXXXXXXXAXXXN}\r\n"\
180
+ "{4:\r\n"\
181
+ ":20:1234567\r\n"\
182
+ ":21:9876543210\r\n"\
183
+ ":25:10020030/1234567\r\n"\
184
+ ":28C:5/1\r\n"\
185
+ ":60F:C160314EUR2187,95\r\n"\
186
+ ":61:0211011102DR800,NSTONONREF//55555\r\n"\
187
+ ":86:008?00DAUERAUFTRAG?100599?20Miete November?3010020030?31234567?32MUELLER?34339\r\n"\
188
+ ":61:0211021102CR3000,NTRFNONREF//55555\r\n"\
189
+ ":86:051?00UEBERWEISUNG?100599?20Gehalt Oktober?21Firma\r\n"\
190
+ "Mustermann GmbH?3050060400?310847564700?32MUELLER?34339\r\n"\
191
+ ":62F:C160315EUR4387,95\r\n"\
192
+ ":86:Some random data"
193
+ stub = instance_double(Cmxl::Statement)
194
+ allow(Cmxl::Statement).to receive(:new).and_return(stub)
195
+
196
+ Cmxl.parse(mt940_file('mt940-windows-line-breaks'))
197
+
198
+ expect(Cmxl::Statement).to have_received(:new).with(expected_data)
199
+ end
200
+
201
+ it 'splits the file into two statements' do
202
+ allow(Cmxl::Statement).to receive(:new)
203
+
204
+ Cmxl.parse(mt940_file('mt940-windows-line-breaks'))
205
+
206
+ expect(Cmxl::Statement).to have_received(:new).once
207
+ end
208
+ end
98
209
  end
@@ -101,7 +101,7 @@ describe Cmxl do
101
101
  end
102
102
  end
103
103
 
104
- describe 'statement issued over a years boudary' do
104
+ describe 'statement issued over a years boundary' do
105
105
  subject { Cmxl.parse(mt940_file('statement-mt940')).first.transactions.last }
106
106
 
107
107
  it { expect(subject.mt942?).to be_falsey }
@@ -167,4 +167,88 @@ describe Cmxl do
167
167
  it { expect(statement.generation_date).to eql(Date.new(2019, 1, 9)) }
168
168
  end
169
169
 
170
+ describe "header parsing" do
171
+ context "when strip_headers is enabled" do
172
+ around do |example|
173
+ existing_value = Cmxl.config[:strip_headers]
174
+ Cmxl.config[:strip_headers] = true
175
+ example.run
176
+ Cmxl.config[:strip_headers] = existing_value
177
+ end
178
+
179
+ it "removes any headers" do
180
+ data = <<~MT940.chomp
181
+ {1:D02AASDISLNETAXXXXXXXXXXXXX}
182
+ {2:E623XXXXXXXXAXXXN}
183
+ {4:
184
+ :20:MT940/78374
185
+ :25:xxxxxxxxxxxxxx
186
+ :28C:3/1
187
+ :60F:C160201INR0,00
188
+ :61:3622687806CR1368378,92NMSC37935531
189
+ :86:-TX TRN-REF NO.1156ADS5601187 EUR 13456/TSV
190
+ :62F:C141387INR11 27421,94
191
+ -}
192
+ MT940
193
+
194
+ result = Cmxl::Statement.new(data)
195
+
196
+ expect(result.fields.count).to eq(6)
197
+ end
198
+
199
+ it "does nothing if there are no headers" do
200
+ data = <<~MT940.chomp
201
+ :20:MT940/78374
202
+ :25:xxxxxxxxxxxxxx
203
+ :28C:3/1
204
+ :60F:C160201INR0,00
205
+ :61:3622687806CR1368378,92NMSC37935531
206
+ :86:-TX TRN-REF NO.1156ADS5601187 EUR 13456/TSV
207
+ :62F:C141387INR11 27421,94
208
+ MT940
209
+
210
+ result = Cmxl::Statement.new(data)
211
+
212
+ expect(result.fields.count).to eq(6)
213
+ end
214
+ end
215
+
216
+ context "when strip_headers is disabled" do
217
+ it "raise an parsing error exception if headers are present" do
218
+ data = <<~MT940.chomp
219
+ {1:D02AASDISLNETAXXXXXXXXXXXXX}
220
+ {2:E623XXXXXXXXAXXXN}
221
+ {4:
222
+ :20:MT940/78374
223
+ :25:xxxxxxxxxxxxxx
224
+ :28C:3/1
225
+ :60F:C160201INR0,00
226
+ :61:3622687806CR1368378,92NMSC37935531
227
+ :86:-TX TRN-REF NO.1156ADS5601187 EUR 13456/TSV
228
+ :62F:C141387INR11 27421,94
229
+ -}
230
+ MT940
231
+
232
+ expect{
233
+ Cmxl::Statement.new(data)
234
+ }.to raise_error(Cmxl::Field::LineFormatError)
235
+ end
236
+
237
+ it "extracts the field" do
238
+ data = <<~MT940.chomp
239
+ :20:MT940/78374
240
+ :25:xxxxxxxxxxxxxx
241
+ :28C:3/1
242
+ :60F:C160201INR0,00
243
+ :61:3622687806CR1368378,92NMSC37935531
244
+ :86:-TX TRN-REF NO.1156ADS5601187 EUR 13456/TSV
245
+ :62F:C141387INR11 27421,94
246
+ MT940
247
+
248
+ result = Cmxl::Statement.new(data)
249
+
250
+ expect(result.fields.count).to eq(6)
251
+ end
252
+ end
253
+ end
170
254
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cmxl
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.0'
4
+ version: '2.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bumann
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-01-10 00:00:00.000000000 Z
10
+ date: 2025-01-28 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rchardet
@@ -163,9 +163,12 @@ files:
163
163
  - spec/fixtures/lines/statement_supplementary_plain.txt
164
164
  - spec/fixtures/lines/vmk_summary_credit.txt
165
165
  - spec/fixtures/lines/vmk_summary_debit.txt
166
+ - spec/fixtures/mt940-abnamro.txt
166
167
  - spec/fixtures/mt940-deutsche_bank.txt
168
+ - spec/fixtures/mt940-handelsbank.txt
167
169
  - spec/fixtures/mt940-headers.txt
168
170
  - spec/fixtures/mt940-iso8859-1.txt
171
+ - spec/fixtures/mt940-windows-line-breaks.txt
169
172
  - spec/fixtures/mt940-with-colon-after-line-break.txt
170
173
  - spec/fixtures/mt940-with-detailed-end-balance.txt
171
174
  - spec/fixtures/mt940.txt
@@ -238,9 +241,12 @@ test_files:
238
241
  - spec/fixtures/lines/statement_supplementary_plain.txt
239
242
  - spec/fixtures/lines/vmk_summary_credit.txt
240
243
  - spec/fixtures/lines/vmk_summary_debit.txt
244
+ - spec/fixtures/mt940-abnamro.txt
241
245
  - spec/fixtures/mt940-deutsche_bank.txt
246
+ - spec/fixtures/mt940-handelsbank.txt
242
247
  - spec/fixtures/mt940-headers.txt
243
248
  - spec/fixtures/mt940-iso8859-1.txt
249
+ - spec/fixtures/mt940-windows-line-breaks.txt
244
250
  - spec/fixtures/mt940-with-colon-after-line-break.txt
245
251
  - spec/fixtures/mt940-with-detailed-end-balance.txt
246
252
  - spec/fixtures/mt940.txt