cmxl 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.mdown +5 -0
- data/cmxl.gemspec +1 -0
- data/lib/cmxl.rb +3 -3
- data/lib/cmxl/field.rb +4 -0
- data/lib/cmxl/fields/{statement_line.rb → transaction.rb} +45 -2
- data/lib/cmxl/statement.rb +39 -8
- data/lib/cmxl/version.rb +1 -1
- data/spec/fields/{statment_line_spec.rb → transaction_spec.rb} +2 -2
- data/spec/fixtures/mt940-deutsche_bank.txt +70 -0
- data/spec/fixtures/mt940-with-detailed-end-balance.txt +8 -0
- data/spec/fixtures/statement-details-mt940.txt +2 -0
- data/spec/fixtures/statement-mt940.txt +1 -0
- data/spec/mt940_parsing_spec.rb +19 -6
- data/spec/spec_helper.rb +2 -2
- data/spec/{transaction_spec.rb → statement_spec.rb} +41 -13
- metadata +31 -9
- data/lib/cmxl/transaction.rb +0 -98
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42504a4554682fd712473e3e744db2892083965e
|
4
|
+
data.tar.gz: 3830a7a989cb7f5d490122d2079e67a45dcc75a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fc0b6927125e065f9c5b9f8c15f2e6ee7d35feb938a72f9bfde9e059e672389e2a00c6e747e81dacf50ca062a8eb1dd39cac7c30272d40fd282022124ddd56a
|
7
|
+
data.tar.gz: f64a53ecbf51cedbaf80fdcad20a9e0e1aa47bd9780cb05768401d3449756344ad4956e4bb4eaef10bfe2851409b72c95cdc6ba0298582a95a51ce1568c1d766
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
CHANGED
data/CHANGELOG.mdown
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# 0.2.0
|
2
|
+
* added several balance related accessors (#7)
|
3
|
+
* configuration option for `statement separator` (#5)
|
4
|
+
* improvement for general compatibility
|
5
|
+
|
1
6
|
# 0.1.3
|
2
7
|
|
3
8
|
* [BUGFIX] fixed the statement details parser. It failed in case of empty values in the SEPA details
|
data/cmxl.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.5"
|
24
24
|
spec.add_development_dependency "rake"
|
25
25
|
spec.add_development_dependency "rspec", '~>3.0'
|
26
|
+
spec.add_development_dependency "simplecov"
|
26
27
|
|
27
28
|
spec.add_dependency "rchardet19"
|
28
29
|
end
|
data/lib/cmxl.rb
CHANGED
@@ -4,14 +4,13 @@ require "rchardet19"
|
|
4
4
|
|
5
5
|
require 'cmxl/field'
|
6
6
|
require 'cmxl/statement'
|
7
|
-
require 'cmxl/transaction'
|
8
7
|
Dir[File.join(File.dirname(__FILE__), 'cmxl/fields', '*.rb')].each { |f| require f; }
|
9
8
|
|
10
9
|
module Cmxl
|
11
10
|
def self.config
|
12
11
|
@config
|
13
12
|
end
|
14
|
-
@config = { :statement_separator => /\n
|
13
|
+
@config = { :statement_separator => /\n-\s*\n/m, :raise_line_format_errors => true }
|
15
14
|
|
16
15
|
# Public: Parse a MT940 string
|
17
16
|
#
|
@@ -27,6 +26,7 @@ module Cmxl
|
|
27
26
|
# Returns an array of Statement objects
|
28
27
|
def self.parse(data, options={})
|
29
28
|
options[:universal_newline] ||= true
|
29
|
+
options[:statement_separator] ||= self.config[:statement_separator]
|
30
30
|
# if no encoding is provided we try to guess using CharDet
|
31
31
|
if options[:encoding].nil? && cd = CharDet.detect(data, silent: true)
|
32
32
|
options[:encoding] = cd.encoding
|
@@ -38,6 +38,6 @@ module Cmxl
|
|
38
38
|
data.encode!('UTF-8', options) if !options.empty?
|
39
39
|
end
|
40
40
|
|
41
|
-
data.split(
|
41
|
+
data.split(options[:statement_separator]).reject { |s| s.strip.empty? }.collect {|s| Cmxl::Statement.new(s.strip) }
|
42
42
|
end
|
43
43
|
end
|
data/lib/cmxl/field.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
1
|
module Cmxl
|
2
2
|
module Fields
|
3
|
-
class
|
3
|
+
class Transaction < Field
|
4
4
|
self.tag = 61
|
5
5
|
self.parser = /^(?<date>\d{6})(?<entry_date>\d{4})?(?<funds_code>[a-zA-Z])(?<currency_letter>[a-zA-Z])?(?<amount>\d{1,12},\d{0,2})(?<swift_code>(?:N|F).{3})(?<reference>NONREF|.{0,16})(?:$|\/\/)(?<bank_reference>.*)/i
|
6
6
|
|
7
|
+
attr_accessor :details
|
8
|
+
|
9
|
+
def add_meta_data(content)
|
10
|
+
self.details = Cmxl::Fields::StatementDetails.parse(content) unless content.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
def sha
|
14
|
+
Digest::SHA2.new.update(source).to_s
|
15
|
+
end
|
16
|
+
|
7
17
|
def credit?
|
8
18
|
self.data['funds_code'].to_s.upcase == 'C'
|
9
19
|
end
|
@@ -31,8 +41,33 @@ module Cmxl
|
|
31
41
|
to_date(self.data['entry_date'], self.date.year) if self.data['entry_date'] && self.date
|
32
42
|
end
|
33
43
|
|
44
|
+
# Fields from details
|
45
|
+
|
46
|
+
def description
|
47
|
+
details.description if details
|
48
|
+
end
|
49
|
+
def information
|
50
|
+
details.information if details
|
51
|
+
end
|
52
|
+
def bic
|
53
|
+
details.bic if details
|
54
|
+
end
|
55
|
+
def name
|
56
|
+
details.name if details
|
57
|
+
end
|
58
|
+
def iban
|
59
|
+
details.iban if details
|
60
|
+
end
|
61
|
+
def sepa
|
62
|
+
details.sepa if details
|
63
|
+
end
|
64
|
+
def sub_fields
|
65
|
+
details.sub_fields if details
|
66
|
+
end
|
67
|
+
|
34
68
|
def to_h
|
35
69
|
{
|
70
|
+
'sha' => sha,
|
36
71
|
'date' => date,
|
37
72
|
'entry_date' => entry_date,
|
38
73
|
'amount' => amount,
|
@@ -45,7 +80,15 @@ module Cmxl
|
|
45
80
|
'reference' => reference,
|
46
81
|
'bank_reference' => bank_reference,
|
47
82
|
'currency_letter' => currency_letter
|
48
|
-
}
|
83
|
+
}.merge(details ? details.to_h : {})
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_hash
|
87
|
+
to_h
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_json(*args)
|
91
|
+
to_h.to_json(*args)
|
49
92
|
end
|
50
93
|
end
|
51
94
|
end
|
data/lib/cmxl/statement.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'digest/sha2'
|
2
2
|
module Cmxl
|
3
3
|
class Statement
|
4
|
-
attr_accessor :source, :collection, :
|
4
|
+
attr_accessor :source, :collection, :fields, :lines
|
5
5
|
|
6
6
|
# Public: Initiate a new Statement and parse a provided single statement string
|
7
7
|
# It directly parses the source and initiates file and transaction objects.
|
@@ -13,10 +13,13 @@ module Cmxl
|
|
13
13
|
self.source = source
|
14
14
|
self.fields = []
|
15
15
|
self.lines = []
|
16
|
-
self.transactions = []
|
17
16
|
self.parse!
|
18
17
|
end
|
19
18
|
|
19
|
+
def transactions
|
20
|
+
self.fields.select { |field| field.kind_of?(Fields::Transaction) }
|
21
|
+
end
|
22
|
+
|
20
23
|
# Internal: Parse a single MT940 statement and extract the line data
|
21
24
|
#
|
22
25
|
def parse!
|
@@ -28,17 +31,33 @@ module Cmxl
|
|
28
31
|
self.lines.last << line.strip
|
29
32
|
end
|
30
33
|
end
|
31
|
-
|
32
|
-
self.
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
|
35
|
+
self.fields = []
|
36
|
+
lines.each do |line|
|
37
|
+
if line.match(/\A:86:/)
|
38
|
+
if field = fields.last
|
39
|
+
field.add_meta_data(line)
|
40
|
+
end
|
37
41
|
else
|
38
42
|
field = Field.parse(line)
|
39
43
|
self.fields << field unless field.nil?
|
40
44
|
end
|
41
45
|
end
|
46
|
+
|
47
|
+
# puts "Fixed Fields"
|
48
|
+
# puts fields.inspect
|
49
|
+
#
|
50
|
+
# # Now we check each line for its content ans structure it for further use. If it is part of a transaction we initate or update a transaction else we parse the field and add it to the fields collection
|
51
|
+
# self.lines.each do |line|
|
52
|
+
# if line.match(/\A:61:/)
|
53
|
+
# self.transactions << Cmxl::Transaction.new(line)
|
54
|
+
# elsif line.match(/\A:86:/) && !self.transactions.last.nil?
|
55
|
+
# self.transactions.last.details = line
|
56
|
+
# else
|
57
|
+
# field = Field.parse(line)
|
58
|
+
# self.fields << field unless field.nil?
|
59
|
+
# end
|
60
|
+
# end
|
42
61
|
end
|
43
62
|
|
44
63
|
# Public: SHA2 of the provided source
|
@@ -65,14 +84,26 @@ module Cmxl
|
|
65
84
|
self.field(60, 'F')
|
66
85
|
end
|
67
86
|
|
87
|
+
def opening_or_intermediary_balance
|
88
|
+
self.field(60)
|
89
|
+
end
|
90
|
+
|
68
91
|
def closing_balance
|
69
92
|
self.field(62, 'F')
|
70
93
|
end
|
71
94
|
|
95
|
+
def closing_or_intermediary_balance
|
96
|
+
self.field(62)
|
97
|
+
end
|
98
|
+
|
72
99
|
def available_balance
|
73
100
|
self.field(64)
|
74
101
|
end
|
75
102
|
|
103
|
+
def legal_sequence_number
|
104
|
+
self.field(28).source
|
105
|
+
end
|
106
|
+
|
76
107
|
def to_h
|
77
108
|
{
|
78
109
|
'reference' => reference,
|
data/lib/cmxl/version.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Cmxl::Fields::
|
3
|
+
describe Cmxl::Fields::Transaction do
|
4
4
|
|
5
|
-
subject { Cmxl::Fields::
|
5
|
+
subject { Cmxl::Fields::Transaction.parse(fixture_line(:statement_line)) }
|
6
6
|
|
7
7
|
it { expect(subject.date).to eql(Date.new(2014,9,1)) }
|
8
8
|
it { expect(subject.entry_date).to eql(Date.new(2014,9,2)) }
|
@@ -0,0 +1,70 @@
|
|
1
|
+
:20:131110
|
2
|
+
:25:45050050/76198810
|
3
|
+
:28:27/01
|
4
|
+
:60F:C131016DEM84349,74
|
5
|
+
:61:131017D6800,NCHK16703074
|
6
|
+
:86:999PN5477SCHECK-NR. 0000016703074
|
7
|
+
:61:131017D620,3NSTON
|
8
|
+
:86:999PN0911DAUERAUFTR.NR. 14
|
9
|
+
:61:131017C18500,NCLRN
|
10
|
+
:86:999PN2406SCHECK
|
11
|
+
:61:131015D14220,NBOEN
|
12
|
+
:86:999PN0920WECHSEL
|
13
|
+
:61:131017D1507,NTRFN
|
14
|
+
:86:999PN0920SCHNELLUEB
|
15
|
+
:61:131024C4200,NMSCN
|
16
|
+
:86:999PN2506AUSSENH. NR. 1
|
17
|
+
:61:131017D19900,NTRFN
|
18
|
+
:86:999PN0907UEBERTRAG
|
19
|
+
:61:131017D400,NTRFN
|
20
|
+
:86:999PN0891BTX
|
21
|
+
:61:131018C3656,74NMSCN
|
22
|
+
:86:999PN0850EINZAHLG.N
|
23
|
+
:61:131019C23040,NMSCN
|
24
|
+
:86:999PN0812LT.ANLAGE
|
25
|
+
:61:131027D5862,14NCHKN
|
26
|
+
:86:999PN5329AUSLSCHECK
|
27
|
+
:62F:C131017DEM84437,04
|
28
|
+
-
|
29
|
+
:20:1234567
|
30
|
+
:21:9876543210
|
31
|
+
:25:10020030/1234567
|
32
|
+
:28C:5/1
|
33
|
+
:60F:C021101EUR2187,95
|
34
|
+
:61:0211011102DR800,NSTONONREF//55555
|
35
|
+
:86:008?00DAUERAUFTRAG?100599?20Miete November?3010020030?31234567?32MUELLER?34339
|
36
|
+
:61:0211021102CR3000,NTRFNONREF//55555
|
37
|
+
:86:051?00UEBERWEISUNG?100599?20Gehalt Oktob
|
38
|
+
er
|
39
|
+
?21Firma
|
40
|
+
Mustermann
|
41
|
+
GmbH?3050060400?31084756
|
42
|
+
4700?32MUELLER?34339
|
43
|
+
:62F:C021131EUR4387,95
|
44
|
+
-
|
45
|
+
:20:TELEWIZORY S.A.
|
46
|
+
:25:BPHKPLPK/320000546101
|
47
|
+
:28C:00084/001
|
48
|
+
:60F:C031002PLN40000,00
|
49
|
+
:61:0310201020C20000,00FMSCNONREF//8327000090031789
|
50
|
+
Card transaction
|
51
|
+
:86: 020?00Wyplata-(dysp/przel)?2008106000760000777777777777?2115617?
|
52
|
+
22INFO INFO INFO INFO INFO INFO 1 END?23INFO INFO INFO INFO INFO
|
53
|
+
INFO 2 END?24ZAPLATA ZA FABRYKATY DO TUB?25 - 200 S ZTUK, TRANZY
|
54
|
+
STORY-?26300 SZT GR544 I OPORNIKI-5?2700 SZT GTX847 FAKTURA 333/
|
55
|
+
2?28003.?3010600076?310000777777777777?32HUTA SZKLA TOPIC UL
|
56
|
+
PRZEMY?33SLOWA 67 32-669 WROCLAW?38PL081060007600007777777
|
57
|
+
77777
|
58
|
+
:61:0310201020D10000,00FTRFREF 25611247//8327000090031790
|
59
|
+
Transfer
|
60
|
+
:86: 020?00Wyplata-(dysp/przel)?2008106000760000777777777777?2115617?
|
61
|
+
22INFO INFO INFO INFO INFO INFO 1 END?23INFO INFO INFO INFO INFO
|
62
|
+
INFO 2 END?24ZAPLATA ZA FABRYKATY DO TUB?25 - 200 S ZTUK, TRANZY
|
63
|
+
STORY-?26300 SZT GR544 I OPORNIKI-5?2700 SZT GTX847 FAKTURA 333/
|
64
|
+
2?28003.?3010600076?310000777777777777?38PL081060007600007777777
|
65
|
+
77777
|
66
|
+
:61:0310201020C40,00FTRFNONREF//8327000090031791
|
67
|
+
Interest credit
|
68
|
+
:86: 844?00Uznanie kwotą odsetek?20Odsetki od lokaty nr 101000?21022086
|
69
|
+
:62F:C020325PLN50040,00
|
70
|
+
-
|
@@ -0,0 +1,8 @@
|
|
1
|
+
:20:STARTUMS
|
2
|
+
:25:45050050/76198810
|
3
|
+
:28C:00001/00001
|
4
|
+
:60F:C160101EUR10,00
|
5
|
+
:61:1601010222CR1,00NTRFNONREF//CT16-01-01-08.32
|
6
|
+
:86:008?00DAUERAUFTRAG?100599?20Miete Dezember?3010020030?31234567?32MUELLER?34339
|
7
|
+
:62F:C160222EUR15,00
|
8
|
+
:86:Some random addition to it
|
@@ -0,0 +1,2 @@
|
|
1
|
+
:61:1409010902DR000000000001,62NTRF0000549855700010//025498557/000001
|
2
|
+
:86:171?00SEPA LASTSCHRIFT KUNDE?10281?20KREF+EREF+TRX-0A4A47C3-F846-4729?21-8A1B-5DF620F?22MREF+CAC97D2144174318AC18D9?23BF815BD4FB?24CRED+DE98ZZZ09999999999?25SVWZ+FOO TRX-0A4A47C3-F84?266-4729-8A1B-5DF620F?30HYVEDEMMXXX?31HUkkbbbsssskcccccccccccccccx?32Peter Pan?99?34171
|
@@ -0,0 +1 @@
|
|
1
|
+
:61:1409010902DR000000000001,62NTRF0000549855700010//025498557/000001
|
data/spec/mt940_parsing_spec.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
2
|
require 'spec_helper'
|
4
3
|
|
5
4
|
describe 'parsing a statement' do
|
6
|
-
|
7
5
|
context 'ISO 8859-1' do
|
8
6
|
subject { Cmxl.parse(mt940_file('mt940-iso8859-1'))[0] }
|
7
|
+
|
9
8
|
it { expect(subject.reference).to eql('1234567') }
|
10
9
|
it { expect(subject.opening_balance.amount_in_cents).to eql(218795) }
|
11
10
|
it { expect(subject.closing_balance.amount_in_cents).to eql(438795) }
|
@@ -17,12 +16,12 @@ describe 'parsing a statement' do
|
|
17
16
|
|
18
17
|
context 'first example' do
|
19
18
|
subject { Cmxl.parse(mt940_file(), :encoding => 'ISO-8859-1', :universal_newline => true)[0] }
|
19
|
+
|
20
20
|
it { expect(subject.reference).to eql('131110') }
|
21
21
|
it { expect(subject.opening_balance.amount_in_cents).to eql(8434974) }
|
22
22
|
it { expect(subject.closing_balance.amount_in_cents).to eql(8443704) }
|
23
23
|
it { expect(subject.generation_date).to eql(Date.new(2013, 11, 10)) }
|
24
24
|
it { expect(subject.transactions.count).to eql(11) }
|
25
|
-
|
26
25
|
it { expect(subject.transactions.first.description).to eql('PN5477SCHECK-NR. 0000016703074') }
|
27
26
|
it { expect(subject.transactions.first.information).to eql('PN5477SCHECK-NR. 0000016703074') }
|
28
27
|
it { expect(subject.transactions.first.sepa).to eql({}) }
|
@@ -31,6 +30,7 @@ describe 'parsing a statement' do
|
|
31
30
|
|
32
31
|
context 'second example' do
|
33
32
|
subject { Cmxl.parse(mt940_file(), :encoding => 'ISO-8859-1', :universal_newline => true)[1] }
|
33
|
+
|
34
34
|
it { expect(subject.reference).to eql('1234567') }
|
35
35
|
it { expect(subject.opening_balance.amount_in_cents).to eql(218795) }
|
36
36
|
it { expect(subject.closing_balance.amount_in_cents).to eql(438795) }
|
@@ -44,10 +44,9 @@ describe 'parsing a statement' do
|
|
44
44
|
it { expect(subject.transactions.first.iban).to eql('234567') }
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
|
-
|
49
47
|
context 'third example' do
|
50
48
|
subject { Cmxl.parse(mt940_file(), :encoding => 'ISO-8859-1', :universal_newline => true)[2] }
|
49
|
+
|
51
50
|
it { expect(subject.reference).to eql('TELEWIZORY S.A.') }
|
52
51
|
it { expect(subject.opening_balance.amount_in_cents).to eql(4000000) }
|
53
52
|
it { expect(subject.closing_balance.amount_in_cents).to eql(5004000) }
|
@@ -59,7 +58,21 @@ describe 'parsing a statement' do
|
|
59
58
|
it { expect(subject.transactions.first.bic).to eql('10600076') }
|
60
59
|
it { expect(subject.transactions.first.iban).to eql('PL08106000760000777777777777') }
|
61
60
|
it { expect(subject.transactions.first.sepa).to eql({}) }
|
62
|
-
end
|
61
|
+
end
|
63
62
|
|
63
|
+
context 'statement separator as used by most banks' do
|
64
|
+
subject { Cmxl.parse(mt940_file('mt940')) }
|
64
65
|
|
66
|
+
it 'detects all statements by default' do
|
67
|
+
expect(subject.size).to eq(3)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'statement separator as used by Deutsche Bank' do
|
72
|
+
subject { Cmxl.parse(mt940_file('mt940-deutsche_bank')) }
|
73
|
+
|
74
|
+
it 'detects all statements by default' do
|
75
|
+
expect(subject.size).to eq(3)
|
76
|
+
end
|
77
|
+
end
|
65
78
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Cmxl
|
3
|
+
describe Cmxl do
|
4
4
|
|
5
5
|
context 'with details' do
|
6
|
-
subject { Cmxl
|
6
|
+
subject { Cmxl.parse( mt940_file('statement-details-mt940') ).first.transactions.first }
|
7
|
+
|
7
8
|
it { expect(subject).to be_debit }
|
8
9
|
it { expect(subject).to_not be_credit }
|
9
10
|
it { expect(subject.funds_code).to eql('D') }
|
10
|
-
it { expect(subject.date).to eql(Date.new(2014,9,1))}
|
11
|
-
it { expect(subject.entry_date).to eql(Date.new(2014,9,2))}
|
12
|
-
it { expect(subject.amount).to eql(1.62)}
|
13
|
-
it { expect(subject.
|
14
|
-
it { expect(subject.amount_in_cents).to eql(162)}
|
11
|
+
it { expect(subject.date).to eql(Date.new(2014,9,1)) }
|
12
|
+
it { expect(subject.entry_date).to eql(Date.new(2014,9,2)) }
|
13
|
+
it { expect(subject.amount).to eql(1.62) }
|
14
|
+
it { expect(subject.amount_in_cents).to eql(162) }
|
15
15
|
it { expect(subject.to_h).to eql(
|
16
16
|
{
|
17
17
|
"date" => Date.new(2014,9,1),
|
@@ -63,14 +63,42 @@ describe Cmxl::Transaction do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
context 'without details' do
|
66
|
-
subject { Cmxl
|
66
|
+
subject { Cmxl.parse( mt940_file('statement-mt940') ).first.transactions.first }
|
67
|
+
|
67
68
|
it { expect(subject).to be_debit }
|
68
69
|
it { expect(subject).to_not be_credit }
|
69
70
|
it { expect(subject.date).to eql(Date.new(2014,9,1))}
|
70
|
-
it { expect(subject.entry_date).to eql(Date.new(2014,9,2))}
|
71
|
-
it { expect(subject.amount).to eql(1.62)}
|
72
|
-
it { expect(subject.amount_in_cents).to eql(162)}
|
73
|
-
it
|
74
|
-
|
71
|
+
it { expect(subject.entry_date).to eql(Date.new(2014,9,2)) }
|
72
|
+
it { expect(subject.amount).to eql(1.62) }
|
73
|
+
it { expect(subject.amount_in_cents).to eql(162) }
|
74
|
+
it 'does not include any details in its hash representation' do
|
75
|
+
expect(subject.to_h).to eql({
|
76
|
+
"date" => Date.new(2014,9,1),
|
77
|
+
"sha" => "3c5e65aa3d3878b06b58b6f1ae2f3693004dfb04e3ab7119a1c1244e612293da",
|
78
|
+
"entry_date"=>Date.new(2014,9,2),
|
79
|
+
"funds_code" => "D",
|
80
|
+
"currency_letter" => "R",
|
81
|
+
"amount" => 1.62,
|
82
|
+
"swift_code" => "NTRF",
|
83
|
+
"reference" => "0000549855700010",
|
84
|
+
"bank_reference" => "025498557/000001",
|
85
|
+
"amount_in_cents" => 162,
|
86
|
+
"sign" => -1,
|
87
|
+
"debit" => true,
|
88
|
+
"credit" => false
|
89
|
+
})
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'statement with detailed end balance' do
|
94
|
+
subject { Cmxl.parse( mt940_file('mt940-with-detailed-end-balance') ).first.transactions.first }
|
95
|
+
|
96
|
+
it 'includes correct iban' do
|
97
|
+
expect(subject.iban).to eq('234567')
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'includes correct bic' do
|
101
|
+
expect(subject.bic).to eq('10020030')
|
102
|
+
end
|
75
103
|
end
|
76
104
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cmxl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bumann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rchardet19
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,6 +89,7 @@ extensions: []
|
|
75
89
|
extra_rdoc_files: []
|
76
90
|
files:
|
77
91
|
- ".gitignore"
|
92
|
+
- ".rspec"
|
78
93
|
- ".travis.yml"
|
79
94
|
- CHANGELOG.mdown
|
80
95
|
- Gemfile
|
@@ -90,10 +105,9 @@ files:
|
|
90
105
|
- lib/cmxl/fields/closing_balance.rb
|
91
106
|
- lib/cmxl/fields/reference.rb
|
92
107
|
- lib/cmxl/fields/statement_details.rb
|
93
|
-
- lib/cmxl/fields/statement_line.rb
|
94
108
|
- lib/cmxl/fields/statement_number.rb
|
109
|
+
- lib/cmxl/fields/transaction.rb
|
95
110
|
- lib/cmxl/statement.rb
|
96
|
-
- lib/cmxl/transaction.rb
|
97
111
|
- lib/cmxl/version.rb
|
98
112
|
- spec/field_spec.rb
|
99
113
|
- spec/fields/account_balance_spec.rb
|
@@ -103,7 +117,7 @@ files:
|
|
103
117
|
- spec/fields/reference_spec.rb
|
104
118
|
- spec/fields/statement_details_spec.rb
|
105
119
|
- spec/fields/statement_number_spec.rb
|
106
|
-
- spec/fields/
|
120
|
+
- spec/fields/transaction_spec.rb
|
107
121
|
- spec/fields/unknown_spec.rb
|
108
122
|
- spec/fixtures/lines/account_balance_credit.txt
|
109
123
|
- spec/fixtures/lines/account_balance_debit.txt
|
@@ -115,12 +129,16 @@ files:
|
|
115
129
|
- spec/fixtures/lines/statement_details.txt
|
116
130
|
- spec/fixtures/lines/statement_line.txt
|
117
131
|
- spec/fixtures/lines/statement_number.txt
|
132
|
+
- spec/fixtures/mt940-deutsche_bank.txt
|
118
133
|
- spec/fixtures/mt940-iso8859-1.txt
|
134
|
+
- spec/fixtures/mt940-with-detailed-end-balance.txt
|
119
135
|
- spec/fixtures/mt940.txt
|
136
|
+
- spec/fixtures/statement-details-mt940.txt
|
137
|
+
- spec/fixtures/statement-mt940.txt
|
120
138
|
- spec/mt940_parsing_spec.rb
|
121
139
|
- spec/spec_helper.rb
|
140
|
+
- spec/statement_spec.rb
|
122
141
|
- spec/support/fixtures.rb
|
123
|
-
- spec/transaction_spec.rb
|
124
142
|
homepage: https://github.com/railslove/cmxl
|
125
143
|
licenses:
|
126
144
|
- MIT
|
@@ -143,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
161
|
version: '0'
|
144
162
|
requirements: []
|
145
163
|
rubyforge_project:
|
146
|
-
rubygems_version: 2.
|
164
|
+
rubygems_version: 2.5.1
|
147
165
|
signing_key:
|
148
166
|
specification_version: 4
|
149
167
|
summary: Cmxl is your friendly MT940 bank statement parser
|
@@ -156,7 +174,7 @@ test_files:
|
|
156
174
|
- spec/fields/reference_spec.rb
|
157
175
|
- spec/fields/statement_details_spec.rb
|
158
176
|
- spec/fields/statement_number_spec.rb
|
159
|
-
- spec/fields/
|
177
|
+
- spec/fields/transaction_spec.rb
|
160
178
|
- spec/fields/unknown_spec.rb
|
161
179
|
- spec/fixtures/lines/account_balance_credit.txt
|
162
180
|
- spec/fixtures/lines/account_balance_debit.txt
|
@@ -168,9 +186,13 @@ test_files:
|
|
168
186
|
- spec/fixtures/lines/statement_details.txt
|
169
187
|
- spec/fixtures/lines/statement_line.txt
|
170
188
|
- spec/fixtures/lines/statement_number.txt
|
189
|
+
- spec/fixtures/mt940-deutsche_bank.txt
|
171
190
|
- spec/fixtures/mt940-iso8859-1.txt
|
191
|
+
- spec/fixtures/mt940-with-detailed-end-balance.txt
|
172
192
|
- spec/fixtures/mt940.txt
|
193
|
+
- spec/fixtures/statement-details-mt940.txt
|
194
|
+
- spec/fixtures/statement-mt940.txt
|
173
195
|
- spec/mt940_parsing_spec.rb
|
174
196
|
- spec/spec_helper.rb
|
197
|
+
- spec/statement_spec.rb
|
175
198
|
- spec/support/fixtures.rb
|
176
|
-
- spec/transaction_spec.rb
|
data/lib/cmxl/transaction.rb
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
module Cmxl
|
2
|
-
class Transaction
|
3
|
-
attr_accessor :statement_line, :details
|
4
|
-
|
5
|
-
def initialize(statement_line, details = nil)
|
6
|
-
self.statement_line = statement_line
|
7
|
-
self.details = details
|
8
|
-
end
|
9
|
-
|
10
|
-
def statement_line=(line)
|
11
|
-
@statement_line = Cmxl::Fields::StatementLine.parse(line) unless line.nil?
|
12
|
-
end
|
13
|
-
|
14
|
-
def details=(line)
|
15
|
-
@details = Cmxl::Fields::StatementDetails.parse(line) unless line.nil?
|
16
|
-
end
|
17
|
-
|
18
|
-
def sha
|
19
|
-
Digest::SHA2.new.update(self.statement_line.source).to_s
|
20
|
-
end
|
21
|
-
|
22
|
-
def debit?
|
23
|
-
self.statement_line.debit?
|
24
|
-
end
|
25
|
-
def credit?
|
26
|
-
self.statement_line.credit?
|
27
|
-
end
|
28
|
-
def amount
|
29
|
-
self.statement_line.amount
|
30
|
-
end
|
31
|
-
def sign
|
32
|
-
self.statement_line.sign
|
33
|
-
end
|
34
|
-
def funds_code
|
35
|
-
self.statement_line.funds_code
|
36
|
-
end
|
37
|
-
def amount_in_cents
|
38
|
-
self.statement_line.amount_in_cents
|
39
|
-
end
|
40
|
-
def date
|
41
|
-
self.statement_line.date
|
42
|
-
end
|
43
|
-
def entry_date
|
44
|
-
self.statement_line.entry_date
|
45
|
-
end
|
46
|
-
def funds_code
|
47
|
-
self.statement_line.funds_code
|
48
|
-
end
|
49
|
-
def currency_letter
|
50
|
-
self.statement_line.currency_letter
|
51
|
-
end
|
52
|
-
def swift_code
|
53
|
-
self.statement_line.swift_code
|
54
|
-
end
|
55
|
-
def reference
|
56
|
-
self.statement_line.reference
|
57
|
-
end
|
58
|
-
def bank_reference
|
59
|
-
self.statement_line.bank_reference
|
60
|
-
end
|
61
|
-
def description
|
62
|
-
self.details.description if self.details
|
63
|
-
end
|
64
|
-
def information
|
65
|
-
self.details.information if self.details
|
66
|
-
end
|
67
|
-
def bic
|
68
|
-
self.details.bic if self.details
|
69
|
-
end
|
70
|
-
def name
|
71
|
-
self.details.name if self.details
|
72
|
-
end
|
73
|
-
def iban
|
74
|
-
self.details.iban if self.details
|
75
|
-
end
|
76
|
-
def sepa
|
77
|
-
self.details.sepa if self.details
|
78
|
-
end
|
79
|
-
def sub_fields
|
80
|
-
self.details.sub_fields if self.details
|
81
|
-
end
|
82
|
-
|
83
|
-
def to_h
|
84
|
-
{}.tap do |h|
|
85
|
-
h['sha'] = self.sha
|
86
|
-
h.merge!(self.statement_line.to_h)
|
87
|
-
h.merge!(self.details.to_h) if self.details
|
88
|
-
end
|
89
|
-
end
|
90
|
-
def to_hash
|
91
|
-
to_h
|
92
|
-
end
|
93
|
-
def to_json(*args)
|
94
|
-
to_h.to_json(*args)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|