cremul-parser 0.0.4 → 0.0.5

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: 7825dfa6f85b710b139911059377276d2ecde921
4
- data.tar.gz: 6415ab1b5fe953431f2850f5255b79dfd8ed74ec
3
+ metadata.gz: f7d37e7ea9a0f2a71f205a8626cd1a3e3b40e0c2
4
+ data.tar.gz: 223f59f9bad82d84c45707f52bcba71e467d3664
5
5
  SHA512:
6
- metadata.gz: a5694b537a28413741e6f5882a62fc66b9add15782291be927f1945f763d2f0c022334fd22447f24a8486ad28626b67ec70f8058cfb4e274eb56c5a008c3df53
7
- data.tar.gz: 8cba193e51669dfb1da891f86259b307fb461defa7ec5e99eb87d31001a0f287da9f73b239b4cbb31addbe42a4d67a7dd568598a8a28d5caffee0ea60eee2963
6
+ metadata.gz: 559c0548efc556273b498b5501ebe69892ae6e664d1cce8cd617e254de65482b426d91760b703306029a2a25db34fa9437d2d6517969d1daf5d28742979e6a95
7
+ data.tar.gz: 9576276c7c842514c3988dc92c909d948aab3ac00f93137059e34725236ff415a5b7d7b1087bcb5516b6335c355278bf35fb2a035e538615ab46cc5c922571fc
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ spec/reports
16
16
  test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
+ CREMUL0002_23-05-14.DAT
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.0.5
4
+
5
+ - Refactored the ParserHelper to make it more DRY, and fixed a bug in CremulHeader regarding the parsing the
6
+ optional NAD-element in the header.
7
+ - Fixed a bug in CremulMoney which caused amounts with decimal mark to be parsed without the fractional part.
8
+ - Fixed a bug in CremulPaymentTx related to parsing the FII+OR segment when it contains a payer
9
+ account holder name in addition to the account number.
10
+
3
11
  ## 0.0.4
4
12
 
5
13
  Added support for files using a CNT:LIN symbol instead of CNT:LI as the standard says.
data/README.md CHANGED
@@ -46,8 +46,6 @@ f.close
46
46
 
47
47
  See the `parser_test.rb` file for more details.
48
48
 
49
- ## Version
50
-
51
49
  ## Copyright
52
50
 
53
51
  Copyright (c) 2014 Per Spilling (per@kodemaker.no). See LICENSE.txt for details.
@@ -6,22 +6,20 @@ class CremulHeader
6
6
  # bf_id : Beneficiary ID. When the beneficiary is an organization this will be the organzation-number,
7
7
  # and when the beneficiary is a person this will be the SSN, aka personnummer (NO).
8
8
 
9
- #attr_reader :header_segments, :msg_id, :created_date, :bf_id
10
9
  attr_reader :msg_id, :created_date, :bf_id
11
10
 
12
11
  # Expects an array with all segments in the CREMUL file
13
12
  def initialize(segments)
14
- #i = next_line_segment_index(segments, 0)
15
- #@header_segments = {}
16
- #segments[0,i].each {|s| @header_segments[s[0,3]] = s[3,s.size] }
17
-
18
13
  @msg_id = segments[msg_id_segment_index(segments)]
19
14
 
20
15
  d = segments[next_date_segment_index(segments, 0)].split(':')
21
16
  @created_date = Date.parse(d[1])
22
17
 
23
- nad = segments[next_nad_segment_index(segments, 0)]
24
- @bf_id = nad.split('+')[2].to_i
18
+ bf_nad_index = next_nad_segment_index(segments, 0) # may not be present in the header
19
+ unless bf_nad_index.nil?
20
+ nad = segments[bf_nad_index]
21
+ @bf_id = nad.split('+')[2].to_i
22
+ end
25
23
  end
26
24
 
27
25
  end
@@ -9,8 +9,8 @@ class CremulMoney
9
9
 
10
10
  def initialize(money_segment)
11
11
  m = money_segment.split(':')
12
-
13
- @amount = m[1].to_f
12
+ a = m[1].gsub(',', '.') # , is used as decimal mark
13
+ @amount = a.to_f
14
14
  if m.size == 3
15
15
  @currency = m[2].to_sym
16
16
  else
@@ -18,7 +18,11 @@ class CremulPaymentTx
18
18
  @posting_date = Date.parse(s[1])
19
19
 
20
20
  s = segments[next_fii_or_segment_index(segments, tx_segment_pos)].split('+')
21
- @payer_account_number = s[2]
21
+ if s[2].include? ':'
22
+ @payer_account_number = s[2].split(':')[0] # the part after the : is the payer account holder name
23
+ else
24
+ @payer_account_number = s[2]
25
+ end
22
26
 
23
27
  init_invoice_ref(segments, tx_segment_pos)
24
28
  init_free_text(segments, tx_segment_pos)
@@ -72,71 +72,66 @@ module Cremul
72
72
  segments.index { |x| /UNH.*/.match(x) }
73
73
  end
74
74
 
75
- def next_date_segment_index(segments, start_pos)
76
- index = segments[start_pos, segments.size].index { |x| /DTM.*/.match(x) }
77
- index += start_pos unless index.nil?
75
+ def find_index_by_regex(segments, start_pos, end_pos=nil, regex)
76
+ if end_pos.nil?
77
+ end_pos = next_tx_sequence_segment_index(segments, start_pos+1)
78
+ if end_pos.nil? # no more segments
79
+ end_pos = segments.size
80
+ end
81
+ end
82
+ index = nil
83
+ unless end_pos.nil?
84
+ index = segments[start_pos, end_pos-start_pos].index { |x| regex.match(x) }
85
+ index += start_pos unless index.nil?
86
+ end
78
87
  index
79
88
  end
80
89
 
81
- def next_amount_segment_index(segments, start_pos)
82
- index = segments[start_pos, segments.size].index { |x| /MOA.*/.match(x) }
83
- index += start_pos unless index.nil?
84
- index
90
+ def next_date_segment_index(segments, start_pos, end_pos=nil)
91
+ find_index_by_regex(segments, start_pos, end_pos, /DTM.*/)
92
+ end
93
+
94
+ def next_amount_segment_index(segments, start_pos, end_pos=nil)
95
+ find_index_by_regex(segments, start_pos, end_pos, /MOA.*/)
85
96
  end
86
97
 
87
98
  def next_line_segment_index(segments, start_pos)
88
- index = segments[start_pos, segments.size].index { |x| /LIN\+\d/.match(x) }
89
- index += start_pos unless index.nil?
90
- index
99
+ find_index_by_regex(segments, start_pos, segments.size, /LIN\+\d/)
91
100
  end
92
101
 
93
102
  def next_tx_sequence_segment_index(segments, start_pos)
94
- index = segments[start_pos, segments.size].index { |x| /SEQ\+\+\d/.match(x) }
95
- index += start_pos unless index.nil?
96
- index
103
+ find_index_by_regex(segments, start_pos, segments.size, /SEQ\+\+\d/)
97
104
  end
98
105
 
99
- def doc_segment_index(segments, start_pos)
100
- index = segments[start_pos, segments.size].index { |x| /DOC.*/.match(x) }
101
- index += start_pos unless index.nil?
102
- index
106
+ def doc_segment_index(segments, start_pos, end_pos=nil)
107
+ find_index_by_regex(segments, start_pos, end_pos, /DOC.*/)
103
108
  end
104
109
 
105
- def payment_details_segment_index(segments, start_pos)
106
- index = segments[start_pos, segments.size].index { |x| /FTX\+PMD.*/.match(x) }
107
- index += start_pos unless index.nil?
108
- index
110
+ def payment_details_segment_index(segments, start_pos, end_pos=nil)
111
+ find_index_by_regex(segments, start_pos, end_pos, /FTX\+PMD.*/)
109
112
  end
110
113
 
111
114
  # Optional segment with free text info regarding the payment
112
- def payment_advice_segment_index(segments, start_pos)
113
- index = segments[start_pos, segments.size].index { |x| /FTX\+AAG.*/.match(x) }
114
- index += start_pos unless index.nil?
115
- index
115
+ def payment_advice_segment_index(segments, start_pos, end_pos=nil)
116
+ find_index_by_regex(segments, start_pos, end_pos, /FTX\+AAG.*/)
116
117
  end
117
118
 
118
- def next_ref_segment_index(segments, start_pos)
119
- index = segments[start_pos, segments.size].index { |x| /RFF.*/.match(x) }
120
- index += start_pos unless index.nil?
121
- index
119
+ def next_ref_segment_index(segments, start_pos, end_pos=nil)
120
+ find_index_by_regex(segments, start_pos, end_pos, /RFF.*/)
122
121
  end
123
122
 
124
- def next_fii_bf_segment_index(segments, start_pos)
125
- index = segments[start_pos, segments.size].index { |x| /FII\+BF.*/.match(x) }
126
- index += start_pos unless index.nil?
127
- index
123
+ # Bank account of beneficiary
124
+ def next_fii_bf_segment_index(segments, start_pos, end_pos=nil)
125
+ find_index_by_regex(segments, start_pos, end_pos, /FII\+BF.*/)
128
126
  end
129
127
 
130
- def next_fii_or_segment_index(segments, start_pos)
131
- index = segments[start_pos, segments.size].index { |x| /FII\+OR.*/.match(x) }
132
- index += start_pos unless index.nil?
133
- index
128
+ # Bank account of payer
129
+ def next_fii_or_segment_index(segments, start_pos, end_pos=nil)
130
+ find_index_by_regex(segments, start_pos, end_pos, /FII\+OR.*/)
134
131
  end
135
132
 
136
- def next_nad_segment_index(segments, start_pos)
137
- index = segments[start_pos, segments.size].index { |x| /NAD.*/.match(x) }
138
- index += start_pos unless index.nil?
139
- index
133
+ def next_nad_segment_index(segments, start_pos, end_pos=nil)
134
+ find_index_by_regex(segments, start_pos, end_pos, /NAD.*/)
140
135
  end
141
136
 
142
137
  def line_count_segment_index(segments)
@@ -1,3 +1,3 @@
1
1
  module Cremul
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
@@ -2,7 +2,7 @@ UNA:+,? 'UNB+UNOC:3+00810506482+00975945065+140312:1546+01001386'UNH+1+CREMUL:D:
2
2
  96A:UN'BGM+435+2014031215350976'DTM+137:20140312:102'NAD+MR+00975945065'LIN+1'DT
3
3
  M+209:20140312:102'BUS++DO++233:25:124'MOA+349:1394:NOK'RFF+ACK:08012992096'DTM+
4
4
  171:20140312:102'FII+BF+12121212121'SEQ++1'DTM+203:20140312:102'FII+OR+123123123
5
- 12'RFF+AEK:12072200001'RFF+ACD:180229451'MOA+143:1394'NAD+PL+++Tømrer Morten Rog
5
+ 12:Tømrer Morten Rognebær AS'RFF+AEK:12072200001'RFF+ACD:180229451'MOA+143:1394'NAD+PL+++Tømrer Morten Rog
6
6
  nebær AS+Skjerpåkeren 17+STANGE++2335'NAD+BE+++FOND.FOR REGIONALE VERNEOMBUD++++
7
7
  0000'PRC+11'FTX+PMD+++Tømrer Morten Rognebær AS'CNT+LI:1'UNT+23+1'UNZ+1+01001386
8
8
  '
@@ -2,7 +2,7 @@ UNA:+,? 'UNB+UNOC:3+00810506482+00975945065+140312:1546+01001386'UNH+1+CREMUL:D:
2
2
  96A:UN'BGM+435+2014031215350976'DTM+137:20140312:102'NAD+MR+00975945065'LIN+1'DT
3
3
  M+209:20140312:102'BUS++DO++233:25:124'MOA+349:1394:NOK'RFF+ACK:08012992096'DTM+
4
4
  171:20140312:102'FII+BF+12121212121'SEQ++1'DTM+203:20140312:102'FII+OR+123123123
5
- 12'RFF+AEK:12072200001'RFF+ACD:180229451'MOA+143:1394'NAD+PL+++T�mrer Morten Rog
5
+ 12:T�mrer Morten Rogneb�r AS'RFF+AEK:12072200001'RFF+ACD:180229451'MOA+143:1394'NAD+PL+++T�mrer Morten Rog
6
6
  neb�r AS+Skjerp�keren 17+STANGE++2335'NAD+BE+++THE BENEFICIARY COMPANY++++
7
7
  0000'PRC+11'FTX+PMD+++T�mrer Morten Rogneb�r AS'CNT+LI:1'UNT+23+1'UNZ+1+01001386
8
8
  '
@@ -2,7 +2,7 @@ require_relative '../test_helper'
2
2
 
3
3
  describe CremulParser do
4
4
 
5
- describe 'parsing valid cremul files' do
5
+ describe 'parsing cremul files' do
6
6
  before do
7
7
  @parser = CremulParser.new
8
8
  end
@@ -41,6 +41,7 @@ describe CremulParser do
41
41
  tx.posting_date.must_equal d2014_03_12
42
42
  tx.money.amount.must_equal 1394.to_f
43
43
  tx.money.currency.must_equal :NOK
44
+ tx.payer_account_number.must_equal '12312312312'
44
45
  tx.references.size.must_equal 2
45
46
  tx.free_text.must_equal 'Tømrer Morten Rognebær AS'
46
47
 
@@ -107,7 +108,7 @@ describe CremulParser do
107
108
  line3.must_be_instance_of CremulLine
108
109
  line3.posting_date.must_equal d2011_01_11
109
110
  line3.money.must_be_instance_of CremulMoney
110
- line3.money.amount.must_equal '6740,40'.to_f
111
+ line3.money.amount.must_equal '6740.40'.to_f
111
112
  line3.money.currency.must_equal :NOK
112
113
  line3.transactions.size.must_equal 2
113
114
 
@@ -161,6 +162,29 @@ describe CremulParser do
161
162
 
162
163
  end
163
164
 
165
+ # the following test is commented out as the corresponding cremul test file is not included in the Git repo
166
+ =begin
167
+ it 'should parse a long file with multiple payment transactions' do
168
+ @parser.parse(File.open('files/CREMUL0002_23-05-14.dat'), 'ISO-8859-1')
169
+ @parser.segments.must_be_instance_of Array
170
+ @parser.msg.must_be_instance_of CremulMessage
171
+
172
+ msg = @parser.msg
173
+
174
+ froland_tx = msg.lines[1].transactions[1]
175
+ froland_tx.must_be_instance_of CremulPaymentTx
176
+ froland_tx.free_text.must_include 'kr 3.384.686,- Fradrag kr.106:.408,- Beregn.g.lag kr.3.278.2 78,-'
177
+
178
+ braekstad_tx = msg.lines[2].transactions[0]
179
+ braekstad_tx.invoice_ref.must_equal '20140453869'
180
+ end
181
+ =end
182
+
183
+
184
+ # ----------------------------------------------------------------------
185
+ # Some tests to handle file format errors (?) that we have encountered
186
+ # ----------------------------------------------------------------------
187
+
164
188
  it 'should parse a file with a CNT:LIN symbol instead of CNT:LI as the standard says' do
165
189
  @parser.parse(File.open('files/CREMUL0001_1.dat'), 'ISO-8859-1')
166
190
  @parser.segments.must_be_instance_of Array
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cremul-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Per Spilling
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-10 00:00:00.000000000 Z
11
+ date: 2014-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler