cmxl 1.2.0 → 1.3.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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -2
- data/CHANGELOG.mdown +28 -18
- data/README.md +45 -26
- data/cmxl.gemspec +15 -16
- data/lib/cmxl.rb +9 -9
- data/lib/cmxl/field.rb +25 -18
- data/lib/cmxl/fields/account_balance.rb +7 -7
- data/lib/cmxl/fields/account_identification.rb +1 -1
- data/lib/cmxl/fields/floor_limit_indicator.rb +20 -0
- data/lib/cmxl/fields/reference.rb +3 -4
- data/lib/cmxl/fields/statement_details.rb +13 -13
- data/lib/cmxl/fields/transaction.rb +10 -1
- data/lib/cmxl/fields/transaction_supplementary.rb +11 -8
- data/lib/cmxl/fields/vmk_summary.rb +33 -0
- data/lib/cmxl/statement.rb +52 -22
- data/lib/cmxl/version.rb +1 -1
- data/spec/field_spec.rb +8 -9
- data/spec/fields/account_balance_spec.rb +18 -18
- data/spec/fields/account_identification_spec.rb +2 -6
- data/spec/fields/available_balance_spec.rb +1 -3
- data/spec/fields/closing_balance_spec.rb +2 -4
- data/spec/fields/entry_date_spec.rb +1 -1
- data/spec/fields/floor_limit_indicator_spec.rb +30 -0
- data/spec/fields/reference_spec.rb +2 -3
- data/spec/fields/statement_details_spec.rb +61 -56
- data/spec/fields/statement_number_spec.rb +0 -2
- data/spec/fields/transaction_spec.rb +4 -4
- data/spec/fields/transaction_supplementary_spec.rb +4 -4
- data/spec/fields/unknown_spec.rb +1 -2
- data/spec/fields/vmk_summary_spec.rb +23 -0
- data/spec/fixtures/lines/floor_limit_indicator_both.txt +1 -0
- data/spec/fixtures/lines/floor_limit_indicator_credit.txt +1 -0
- data/spec/fixtures/lines/floor_limit_indicator_debit.txt +1 -0
- data/spec/fixtures/lines/vmk_summary_credit.txt +1 -0
- data/spec/fixtures/lines/vmk_summary_debit.txt +1 -0
- data/spec/fixtures/mt942.txt +9 -0
- data/spec/fixtures/statement-details-mt942.txt +4 -0
- data/spec/mt940_parsing_spec.rb +13 -14
- data/spec/spec_helper.rb +3 -6
- data/spec/statement_spec.rb +119 -99
- data/spec/support/fixtures.rb +1 -1
- metadata +39 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a9d2c6d5faed6e357abd5459811d43764a89448fc46763993938b1519b17a2a
|
4
|
+
data.tar.gz: 3861abc066158de7c4468d9df01a57331d1913b1d84645b7618f2d146c419a47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 716ee9967921b4539174032223aae5eb996ada741c2181b556e7bb8ec5355668aedd8167ba564836ee73a8a8fa7256d83a74c4f6d8309496cde600c7d631b66c
|
7
|
+
data.tar.gz: 4395610ac7de16b264b309940eda9a2727cfce3c49f8cf051b91f4ab0f8f0486c2caf0528a8efd995fd327f31ccefc288a860f8e458b6ba7b0f1ffe7be85939e
|
data/.travis.yml
CHANGED
@@ -6,8 +6,11 @@ rvm:
|
|
6
6
|
- 2.4.3
|
7
7
|
- 2.5.0
|
8
8
|
- jruby-9.1.10.0
|
9
|
-
before_install:
|
10
|
-
gem update --system
|
9
|
+
before_install: if [[ `ruby -v` =~ 2.2.8 ]];
|
10
|
+
then gem update --system 2.7.8;
|
11
|
+
else gem update --system;
|
12
|
+
fi
|
13
|
+
|
11
14
|
after_success:
|
12
15
|
- bundle exec codeclimate-test-reporter
|
13
16
|
addons:
|
data/CHANGELOG.mdown
CHANGED
@@ -1,35 +1,45 @@
|
|
1
|
+
# 1.3.0
|
2
|
+
|
3
|
+
- [FEATURE] adds MT942 compatibility
|
4
|
+
|
1
5
|
# 1.2.0
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
+
|
7
|
+
- [FEATURE] strips mt940 header if configured ([#9](https://github.com/railslove/cmxl/issues/9))
|
8
|
+
```ruby
|
9
|
+
Cmxl.config[:strip_headers] = true
|
10
|
+
```
|
6
11
|
|
7
12
|
# 1.1.1
|
8
|
-
|
13
|
+
|
14
|
+
- [BUGFIX] prevents short bank references from swallowing supplementary details delimiter
|
9
15
|
|
10
16
|
# 1.1.0
|
11
|
-
|
17
|
+
|
18
|
+
- [FEATURE] adds support for supplementary details in transactions (Field 61, Subfield 9) ([#18](https://github.com/railslove/cmxl/issues/18))
|
12
19
|
|
13
20
|
# 1.0.0
|
14
|
-
|
15
|
-
|
16
|
-
|
21
|
+
|
22
|
+
- [FEATURE] adds support for storno transactions ([#14](https://github.com/railslove/cmxl/issues/14))
|
23
|
+
- [NOTE] full backwards compatibility
|
24
|
+
- [NOTE] same as release 0.2.2, fixing versioning
|
17
25
|
|
18
26
|
# 0.2.1
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
27
|
+
|
28
|
+
- addressing an bug that occoured for transactions submitted end of
|
29
|
+
but were fetched in the new year -> those ended up with the wrong year
|
30
|
+
on the entry date
|
31
|
+
- MT942 support for field 13
|
23
32
|
|
24
33
|
# 0.2.0
|
25
|
-
|
26
|
-
|
27
|
-
|
34
|
+
|
35
|
+
- added several balance related accessors ([#7](https://github.com/railslove/cmxl/issues/7))
|
36
|
+
- configuration option for `statement separator` ([#5](https://github.com/railslove/cmxl/issues/5))
|
37
|
+
- improvement for general compatibility
|
28
38
|
|
29
39
|
# 0.1.3
|
30
40
|
|
31
|
-
|
41
|
+
- [BUGFIX] fixed the statement details parser. It failed in case of empty values in the SEPA details
|
32
42
|
|
33
43
|
# 0.1.2
|
34
44
|
|
35
|
-
|
45
|
+
- [BUGFIX] fixed the statement details parser. It failed in case of empty values in the sub fields
|
data/README.md
CHANGED
@@ -2,24 +2,24 @@
|
|
2
2
|
|
3
3
|
# Cmxl - your friendly ruby MT940 parser
|
4
4
|
|
5
|
-
At [Railslove](http://railslove.com) we build a lot of financial applications and work on integrating applications with banks and banking functionality.
|
5
|
+
At [Railslove](http://railslove.com) we build a lot of financial applications and work on integrating applications with banks and banking functionality.
|
6
6
|
Our goal is to make simple solutions for what often looks complicated.
|
7
7
|
|
8
|
-
Cmxl is a friendly and extendible MT940 bank statement file parser that helps your extracting data from the bank statement files.
|
8
|
+
Cmxl is a friendly and extendible MT940 bank statement file parser that helps your extracting data from the bank statement files.
|
9
9
|
|
10
|
-
## What is MT940?
|
10
|
+
## What is MT940 & MT942?
|
11
11
|
|
12
|
-
MT940 (MT = Message Type) is the SWIFT-Standard for the electronic transfer of bank statement files.
|
13
|
-
When integrating with banks you often get MT940 files as interface.
|
12
|
+
MT940 (MT = Message Type) is the SWIFT-Standard for the electronic transfer of bank statement files.
|
13
|
+
When integrating with banks you often get MT940 or MT942 files as interface.
|
14
14
|
For more information have a look at the different [SWIFT message types](http://en.wikipedia.org/wiki/SWIFT_message_types)
|
15
15
|
|
16
16
|
At some point in the future MT940 file should be exchanged with newer XML documents - but banking institutions are slow so MT940 will stick around for a while.
|
17
17
|
|
18
18
|
## Reqirements
|
19
19
|
|
20
|
-
Cmxl is a pure ruby parser and has no dependency on native extensions.
|
20
|
+
Cmxl is a pure ruby parser and has no dependency on native extensions.
|
21
21
|
|
22
|
-
|
22
|
+
- Ruby 1.9.3 or newer (jruby, etc.)
|
23
23
|
|
24
24
|
## Installation
|
25
25
|
|
@@ -37,7 +37,7 @@ Or install it yourself as:
|
|
37
37
|
|
38
38
|
## Usage
|
39
39
|
|
40
|
-
Simple usage:
|
40
|
+
Simple usage:
|
41
41
|
|
42
42
|
```ruby
|
43
43
|
|
@@ -55,14 +55,14 @@ Cmxl.config[:strip_headers] = true
|
|
55
55
|
|
56
56
|
# Statment parsing:
|
57
57
|
|
58
|
-
statements = Cmxl.parse(File.read('mt940.txt'), :encoding => 'ISO-8859-1') # parses the file and returns an array of statement objects. Please note: if no encoding is given Cmxl tries to guess the encoding from the content and converts it to UTF-8.
|
58
|
+
statements = Cmxl.parse(File.read('mt940.txt'), :encoding => 'ISO-8859-1') # parses the file and returns an array of statement objects. Please note: if no encoding is given Cmxl tries to guess the encoding from the content and converts it to UTF-8.
|
59
59
|
statements.each do |s|
|
60
60
|
puts s.reference
|
61
61
|
puts s.generation_date
|
62
62
|
puts s.opening_balance.amount
|
63
63
|
puts s.closing_balance.amount
|
64
64
|
puts s.sha # SHA of the statement source - could be used as an unique identifier
|
65
|
-
|
65
|
+
|
66
66
|
s.transactions.each do |t|
|
67
67
|
puts t.information
|
68
68
|
puts t.description
|
@@ -87,14 +87,14 @@ Every object responds to `to_h` and let's you easily convert the data to a hash.
|
|
87
87
|
|
88
88
|
#### A note about encoding and file wirednesses
|
89
89
|
|
90
|
-
You probably will encounter encoding issues (hey, you are building banking applications!).
|
91
|
-
We try to handle encoding and format wirednesses as much as possible. If no encoding is passed we try to guess the encoding of the data and convert it to UTF8.
|
92
|
-
In the likely case that you encouter encoding issues you can pass encoding options to the `Cmxl.parse(<string>, <options hash>)` it accepts the same options as [String#encode](http://ruby-doc.org/core-2.1.3/String.html#method-i-encode)
|
90
|
+
You probably will encounter encoding issues (hey, you are building banking applications!).
|
91
|
+
We try to handle encoding and format wirednesses as much as possible. If no encoding is passed we try to guess the encoding of the data and convert it to UTF8.
|
92
|
+
In the likely case that you encouter encoding issues you can pass encoding options to the `Cmxl.parse(<string>, <options hash>)` it accepts the same options as [String#encode](http://ruby-doc.org/core-2.1.3/String.html#method-i-encode)
|
93
93
|
If that fails try to motify the file before you pass it to the parser - and please create an issue.
|
94
94
|
|
95
95
|
### MT940 SWIFT header data
|
96
96
|
|
97
|
-
Cmxl currently does not support parsing of the SWIFT headers (like {1:F01AXISINBBA ....)
|
97
|
+
Cmxl currently does not support parsing of the SWIFT headers (like {1:F01AXISINBBA ....)
|
98
98
|
If your file comes with these headers try the `strip_headers` configuration option to strip data execpt the actual MT940 fields.
|
99
99
|
|
100
100
|
```ruby
|
@@ -102,9 +102,31 @@ Cmxl.config[:strip_headers] = true
|
|
102
102
|
Cmxl.parse(...)
|
103
103
|
```
|
104
104
|
|
105
|
+
### MT942 data
|
106
|
+
|
107
|
+
CMXL is now also capable of parsing MT942 data. Just pass the data and the parser will identify the type automatically.
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
first_statement = Cmxl.parse(File.read('mt940.txt'), :encoding => 'ISO-8859-1').first
|
111
|
+
puts first_statement.mt942?
|
112
|
+
#=> false
|
113
|
+
|
114
|
+
first_statement = Cmxl.parse(File.read('mt942.txt'), :encoding => 'ISO-8859-1').first
|
115
|
+
puts first_statement.mt942?
|
116
|
+
#=> true
|
117
|
+
|
118
|
+
p first_statement.vmk_credit_summary.to_h
|
119
|
+
#=> { type: 'credit', entries: 1, amount: 9792.0, currency: 'EUR' }
|
120
|
+
|
121
|
+
p first_statement.vmk_dedit_summary.to_h
|
122
|
+
#=> { type: 'debit', entries: 0, amount: 0.0, currency: 'EUR' }
|
123
|
+
|
124
|
+
first_statement.transactions # same as for MT940
|
125
|
+
```
|
126
|
+
|
105
127
|
### Custom field parsers
|
106
128
|
|
107
|
-
Because a lot of banks implement the MT940 format slightly different one of the design goals of this library is to be able to customize the individual field parsers.
|
129
|
+
Because a lot of banks implement the MT940 format slightly different one of the design goals of this library is to be able to customize the individual field parsers.
|
108
130
|
Every line get parsed with a special parser. Here is how to write your own parser:
|
109
131
|
|
110
132
|
```ruby
|
@@ -128,23 +150,20 @@ my_field_parser.data #=> {'world' => 'hello from mt940'} - data is the accessor
|
|
128
150
|
|
129
151
|
## Parsing issues? - please create an issue with your file
|
130
152
|
|
131
|
-
The Mt940 format often looks different for the different banks and the different countries. Especially the not strict defined fields are often used for custom bank data.
|
153
|
+
The Mt940 format often looks different for the different banks and the different countries. Especially the not strict defined fields are often used for custom bank data.
|
132
154
|
If you have a file that can not be parsed please open an issue. We hope to build a parser that handles most of the files.
|
133
155
|
|
134
|
-
|
135
156
|
## ToDo
|
136
157
|
|
137
|
-
|
138
|
-
|
139
|
-
* better header data handling
|
140
|
-
|
158
|
+
- collect MT940 files from different banks and use them as example for specs
|
159
|
+
- better header data handling
|
141
160
|
|
142
161
|
## Looking for other Banking and EBICS tools?
|
143
162
|
|
144
163
|
Maybe these are also interesting for you.
|
145
164
|
|
146
|
-
|
147
|
-
|
165
|
+
- [EPICS: Open Source SEPA EBICS client](https://railslove.github.io/epics/) full implementation to manage all the banking activities like direct debits, credits, etc. (SEPA Lastschrift, Überweisungen, etc.)
|
166
|
+
- [EBICS::Box: out of the box solution to automate banking activities](http://www.railslove.com/ebics-box) - The missing API for your bank
|
148
167
|
|
149
168
|
## Contributing
|
150
169
|
|
@@ -161,9 +180,9 @@ Automated tests: We use rspec to test Cmxl. Simply run `rake` to execute the who
|
|
161
180
|
Cmxl is inspired and borrows ideas from the `mt940_parser` by the great people at [betterplace](https://www.betterplace.org/).
|
162
181
|
|
163
182
|
other parsers:
|
164
|
-
* [betterplace/mt940_parser](https://github.com/betterplace/mt940_parser)
|
165
|
-
* [gmitrev/mt940parser](https://github.com/gmitrev/mt940parser)
|
166
183
|
|
184
|
+
- [betterplace/mt940_parser](https://github.com/betterplace/mt940_parser)
|
185
|
+
- [gmitrev/mt940parser](https://github.com/gmitrev/mt940parser)
|
167
186
|
|
168
187
|
## Stats
|
169
188
|
|
@@ -172,6 +191,6 @@ other parsers:
|
|
172
191
|
[](https://codeclimate.com/github/railslove/cmxl)
|
173
192
|
[](http://badge.fury.io/rb/cmxl)
|
174
193
|
|
175
|
-
|
194
|
+
---
|
176
195
|
|
177
196
|
2014 - built with love by [Railslove](http://railslove.com) and released under the MIT-Licence. We have built quite a number of FinTech products. If you need support we are happy to help. Please contact us at team@railslove.com.
|
data/cmxl.gemspec
CHANGED
@@ -1,30 +1,29 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'cmxl/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'cmxl'
|
8
7
|
spec.version = Cmxl::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
8
|
+
spec.authors = ['Michael Bumann']
|
9
|
+
spec.email = ['michael@railslove.com']
|
10
|
+
spec.summary = 'Cmxl is your friendly MT940 bank statement parser'
|
11
|
+
spec.description = 'Cmxl provides an friendly, extensible and customizable parser for the MT940 bank statement format.'
|
12
|
+
spec.homepage = 'https://github.com/railslove/cmxl'
|
13
|
+
spec.license = 'MIT'
|
15
14
|
|
16
15
|
spec.post_install_message = "Thanks for using Cmxl - your friendly MT940 parser!\nWe hope we can make dealing with MT940 files a bit more fun. :) \nPlease create an issue on github if anything is not as expected.\n\n"
|
17
16
|
|
18
17
|
spec.files = `git ls-files -z`.split("\x0")
|
19
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
-
spec.require_paths = [
|
20
|
+
spec.require_paths = ['lib']
|
22
21
|
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
22
|
+
spec.add_development_dependency 'bundler'
|
23
|
+
spec.add_development_dependency 'pry'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rspec', '~>3.0'
|
26
|
+
spec.add_development_dependency 'simplecov'
|
28
27
|
|
29
|
-
spec.add_dependency
|
28
|
+
spec.add_dependency 'rchardet19'
|
30
29
|
end
|
data/lib/cmxl.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require 'cmxl/version'
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'rchardet19'
|
4
4
|
|
5
5
|
require 'cmxl/field'
|
6
6
|
require 'cmxl/statement'
|
@@ -11,9 +11,9 @@ module Cmxl
|
|
11
11
|
@config
|
12
12
|
end
|
13
13
|
@config = {
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
14
|
+
statement_separator: /\n-\s*\n/m,
|
15
|
+
raise_line_format_errors: true,
|
16
|
+
strip_headers: false
|
17
17
|
}
|
18
18
|
|
19
19
|
# Public: Parse a MT940 string
|
@@ -28,8 +28,8 @@ module Cmxl
|
|
28
28
|
# Cmxl.parse(mt940_string)
|
29
29
|
#
|
30
30
|
# Returns an array of Statement objects
|
31
|
-
def self.parse(data, options={})
|
32
|
-
options[:statement_separator] ||=
|
31
|
+
def self.parse(data, options = {})
|
32
|
+
options[:statement_separator] ||= config[:statement_separator]
|
33
33
|
# if no encoding is provided we try to guess using CharDet
|
34
34
|
if options[:encoding].nil? && cd = CharDet.detect(data, silent: true)
|
35
35
|
options[:encoding] = cd.encoding
|
@@ -38,9 +38,9 @@ module Cmxl
|
|
38
38
|
if options[:encoding]
|
39
39
|
data.encode!('UTF-8', options.delete(:encoding), options)
|
40
40
|
else
|
41
|
-
data.encode!('UTF-8', options)
|
41
|
+
data.encode!('UTF-8', options) unless options.empty?
|
42
42
|
end
|
43
43
|
|
44
|
-
data.split(options[:statement_separator]).reject { |s| s.strip.empty? }.collect {|s| Cmxl::Statement.new(s.strip) }
|
44
|
+
data.split(options[:statement_separator]).reject { |s| s.strip.empty? }.collect { |s| Cmxl::Statement.new(s.strip) }
|
45
45
|
end
|
46
46
|
end
|
data/lib/cmxl/field.rb
CHANGED
@@ -2,13 +2,13 @@ require 'date'
|
|
2
2
|
module Cmxl
|
3
3
|
class Field
|
4
4
|
class LineFormatError < StandardError; end
|
5
|
-
class Unknown < Field
|
6
|
-
@parser= /(?<source>.*)/
|
5
|
+
class Unknown < Field
|
6
|
+
@parser = /(?<source>.*)/
|
7
7
|
def to_h
|
8
8
|
{ tag: tag, modifier: modifier, source: source }
|
9
9
|
end
|
10
10
|
end
|
11
|
-
DATE = /(?<year>\d{0,2})(?<month>\d{2})(?<day>\d{2})
|
11
|
+
DATE = /(?<year>\d{0,2})(?<month>\d{2})(?<day>\d{2})/.freeze
|
12
12
|
attr_accessor :source, :modifier, :match, :data, :tag
|
13
13
|
|
14
14
|
# The parser class variable is the registry of all available parser.
|
@@ -16,7 +16,9 @@ module Cmxl
|
|
16
16
|
# When parsing a statment line we look for a matching entry or use the Unknown class as default
|
17
17
|
@@parsers = {}
|
18
18
|
@@parsers.default = Unknown
|
19
|
-
def self.parsers
|
19
|
+
def self.parsers
|
20
|
+
@@parsers
|
21
|
+
end
|
20
22
|
|
21
23
|
# Class accessor for the parser
|
22
24
|
# Every sub class should have its own parser (regex to parse a MT940 field/line)
|
@@ -30,8 +32,9 @@ module Cmxl
|
|
30
32
|
@tag = tag.to_s
|
31
33
|
@@parsers[tag.to_s] = self
|
32
34
|
end
|
33
|
-
|
34
|
-
|
35
|
+
|
36
|
+
class << self
|
37
|
+
attr_reader :tag
|
35
38
|
end
|
36
39
|
|
37
40
|
# Public: Parses a statement line and initiates a matching Field class
|
@@ -44,23 +47,25 @@ module Cmxl
|
|
44
47
|
# Cmxl::Field.parse(':60F:C031002PLN40000,00') #=> returns an AccountBalance instance
|
45
48
|
#
|
46
49
|
def self.parse(line)
|
47
|
-
if line
|
48
|
-
tag
|
50
|
+
if line =~ /\A:(\d{2,2})(\w)?:(.*)\z/m
|
51
|
+
tag = Regexp.last_match(1)
|
52
|
+
modifier = Regexp.last_match(2)
|
53
|
+
content = Regexp.last_match(3).delete("\r").gsub(/\n\z/, '') # remove trailing line break to prevent empty field parsing
|
49
54
|
Field.parsers[tag.to_s].new(content, modifier, tag)
|
50
55
|
else
|
51
56
|
raise LineFormatError, "Wrong line format: #{line.dump}" if Cmxl.config[:raise_line_format_errors]
|
52
57
|
end
|
53
58
|
end
|
54
59
|
|
55
|
-
def initialize(source, modifier=nil, tag=nil)
|
60
|
+
def initialize(source, modifier = nil, tag = nil)
|
56
61
|
self.tag = tag
|
57
62
|
self.modifier = modifier
|
58
63
|
self.source = source
|
59
64
|
self.data = {}
|
60
65
|
|
61
66
|
if self.match = self.source.match(self.class.parser)
|
62
|
-
|
63
|
-
|
67
|
+
match.names.each do |name|
|
68
|
+
data[name] = match[name]
|
64
69
|
end
|
65
70
|
end
|
66
71
|
end
|
@@ -70,11 +75,13 @@ module Cmxl
|
|
70
75
|
end
|
71
76
|
|
72
77
|
def to_h
|
73
|
-
|
78
|
+
data.merge('tag' => tag)
|
74
79
|
end
|
80
|
+
|
75
81
|
def to_hash
|
76
82
|
to_h
|
77
83
|
end
|
84
|
+
|
78
85
|
def to_json(*args)
|
79
86
|
to_h.to_json(*args)
|
80
87
|
end
|
@@ -89,9 +96,9 @@ module Cmxl
|
|
89
96
|
# to_date('0909', 2014)
|
90
97
|
#
|
91
98
|
# Retuns a date object or the provided date value if it is not parseable.
|
92
|
-
def to_date(date, year=nil)
|
99
|
+
def to_date(date, year = nil)
|
93
100
|
if match = date.to_s.match(DATE)
|
94
|
-
year ||= "20#{match['year'] || Date.today.strftime(
|
101
|
+
year ||= "20#{match['year'] || Date.today.strftime('%y')}"
|
95
102
|
month = match['month']
|
96
103
|
day = match['day']
|
97
104
|
Date.new(year.to_i, month.to_i, day.to_i)
|
@@ -103,18 +110,18 @@ module Cmxl
|
|
103
110
|
end
|
104
111
|
|
105
112
|
def to_amount_in_cents(value)
|
106
|
-
value.gsub(/[,|\.](\d*)/) {
|
113
|
+
value.gsub(/[,|\.](\d*)/) { Regexp.last_match(1).ljust(2, '0') }.to_i
|
107
114
|
end
|
108
115
|
|
109
116
|
def to_amount(value)
|
110
|
-
value.
|
117
|
+
value.tr(',', '.').to_f
|
111
118
|
end
|
112
119
|
|
113
120
|
def method_missing(m, *value)
|
114
121
|
if m =~ /=\z/
|
115
|
-
|
122
|
+
data[m] = value.first
|
116
123
|
else
|
117
|
-
|
124
|
+
data[m.to_s]
|
118
125
|
end
|
119
126
|
end
|
120
127
|
end
|